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()) {
2548 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2549 ((BitFieldSize % ByteSizeInBits) != 0);
2551 Size += LastBitfieldOrUnnamedOffset;
2552 UpdateRunSkipBlockVars(
false,
2553 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2555 BytePos + LastBitfieldOrUnnamedOffset,
2558 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2562 UpdateRunSkipBlockVars(
false,
2563 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2565 BytePos + LastBitfieldOrUnnamedOffset,
2571 UpdateRunSkipBlockVars(
false,
2572 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2573 BytePos + MaxFieldOffset,
2577void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2584 const llvm::StructLayout *RecLayout =
2585 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2587 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2599uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2602 if (Layout.size() <= 3) {
2603 unsigned size = Layout.size();
2604 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2606 enum BLOCK_LAYOUT_OPCODE opcode ;
2610 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2611 if (opcode == BLOCK_LAYOUT_STRONG)
2612 strong_word_count = (inst & 0xF)+1;
2616 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2617 if (opcode == BLOCK_LAYOUT_BYREF)
2618 byref_word_count = (inst & 0xF)+1;
2622 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2623 if (opcode == BLOCK_LAYOUT_WEAK)
2624 weak_word_count = (inst & 0xF)+1;
2631 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2632 if (opcode == BLOCK_LAYOUT_STRONG) {
2633 strong_word_count = (inst & 0xF)+1;
2635 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2636 if (opcode == BLOCK_LAYOUT_BYREF)
2637 byref_word_count = (inst & 0xF)+1;
2638 else if (opcode == BLOCK_LAYOUT_WEAK)
2639 weak_word_count = (inst & 0xF)+1;
2643 else if (opcode == BLOCK_LAYOUT_BYREF) {
2644 byref_word_count = (inst & 0xF)+1;
2646 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2647 if (opcode == BLOCK_LAYOUT_WEAK)
2648 weak_word_count = (inst & 0xF)+1;
2658 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2659 if (opcode == BLOCK_LAYOUT_STRONG)
2660 strong_word_count = (inst & 0xF)+1;
2661 else if (opcode == BLOCK_LAYOUT_BYREF)
2662 byref_word_count = (inst & 0xF)+1;
2663 else if (opcode == BLOCK_LAYOUT_WEAK)
2664 weak_word_count = (inst & 0xF)+1;
2676 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2680 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2682 if (size == count) {
2683 if (strong_word_count)
2684 Result = strong_word_count;
2686 if (byref_word_count)
2687 Result += byref_word_count;
2689 if (weak_word_count)
2690 Result += weak_word_count;
2696llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2697 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2698 if (RunSkipBlockVars.empty())
2702 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2706 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2709 unsigned size = RunSkipBlockVars.size();
2710 for (
unsigned i = 0; i < size; i++) {
2711 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2712 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2713 CharUnits end_byte_pos = start_byte_pos;
2716 if (opcode == RunSkipBlockVars[j].opcode) {
2717 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2724 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2727 RunSkipBlockVars[j].block_var_bytepos -
2728 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2729 size_in_bytes += gap;
2732 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2733 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2734 size_in_bytes -= residue_in_bytes;
2735 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2738 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2739 while (size_in_words >= 16) {
2742 unsigned char inst = (opcode << 4) | 0xf;
2743 Layout.push_back(inst);
2744 size_in_words -= 16;
2746 if (size_in_words > 0) {
2749 unsigned char inst = (opcode << 4) | (size_in_words-1);
2750 Layout.push_back(inst);
2753 unsigned char inst =
2754 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2755 Layout.push_back(inst);
2759 while (!Layout.empty()) {
2760 unsigned char inst = Layout.back();
2761 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2762 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2768 uint64_t Result = InlineLayoutInstruction(Layout);
2772 if (ComputeByrefLayout)
2773 printf(
"\n Inline BYREF variable layout: ");
2775 printf(
"\n Inline block variable layout: ");
2776 printf(
"0x0%" PRIx64
"", Result);
2777 if (
auto numStrong = (Result & 0xF00) >> 8)
2778 printf(
", BL_STRONG:%d", (
int) numStrong);
2779 if (
auto numByref = (Result & 0x0F0) >> 4)
2780 printf(
", BL_BYREF:%d", (
int) numByref);
2781 if (
auto numWeak = (Result & 0x00F) >> 0)
2782 printf(
", BL_WEAK:%d", (
int) numWeak);
2783 printf(
", BL_OPERATOR:0\n");
2785 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2788 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2789 Layout.push_back(inst);
2791 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2792 BitMap += Layout[i];
2795 if (ComputeByrefLayout)
2796 printf(
"\n Byref variable layout: ");
2798 printf(
"\n Block variable layout: ");
2799 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2800 unsigned char inst = BitMap[i];
2801 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2804 case BLOCK_LAYOUT_OPERATOR:
2808 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2809 printf(
"BL_NON_OBJECT_BYTES:");
2811 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2812 printf(
"BL_NON_OBJECT_WORD:");
2814 case BLOCK_LAYOUT_STRONG:
2817 case BLOCK_LAYOUT_BYREF:
2820 case BLOCK_LAYOUT_WEAK:
2823 case BLOCK_LAYOUT_UNRETAINED:
2824 printf(
"BL_UNRETAINED:");
2829 printf(
"%d", (inst & 0xf) + delta);
2837 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2845 bool HasCopyDisposeHelpers) {
2847 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2848 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2852 }
else if (HasCopyDisposeHelpers) {
2860 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2863 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2866 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2873 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2874 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
2879void CGObjCCommonMac::fillRunSkipBlockVars(
CodeGenModule &CGM,
2881 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2883 RunSkipBlockVars.clear();
2884 bool hasUnion =
false;
2888 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2893 const llvm::StructLayout *layout =
2903 for (
const auto &CI :
blockDecl->captures()) {
2904 const VarDecl *variable = CI.getVariable();
2915 assert(!
type->isArrayType() &&
"array variable should not be caught");
2918 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2926 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
2927 fieldOffset, fieldSize);
2934 fillRunSkipBlockVars(CGM, blockInfo);
2935 return getBitmapBlockLayout(
false);
2938std::string CGObjCCommonMac::getRCBlockLayoutStr(
CodeGenModule &CGM,
2940 fillRunSkipBlockVars(CGM, blockInfo);
2946 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2947 assert(!
T->
isArrayType() &&
"__block array variable should not be caught");
2949 RunSkipBlockVars.clear();
2950 bool hasUnion =
false;
2952 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2953 llvm::Constant *Result = getBitmapBlockLayout(
true);
2954 if (isa<llvm::ConstantInt>(Result))
2955 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2958 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2968 return GetProtocolRef(PD);
2980 GetOrEmitProtocol(PD);
2983llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2985 return GetOrEmitProtocol(PD);
2987 return GetOrEmitProtocolRef(PD);
2990llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2993 ObjCCommonTypesHelper &ObjCTypes) {
2994 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
2996 llvm::Value *className = CGF.
CGM
2998 ID->getObjCRuntimeNameAsString()))
3002 CGF.
Builder.CreateBitCast(className,
3005 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3006 call->setDoesNotThrow();
3023 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3026 if (Entry && Entry->hasInitializer())
3038 auto methodLists = ProtocolMethodLists::get(PD);
3041 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3042 values.add(EmitProtocolExtension(PD, methodLists));
3044 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3046 values.add(methodLists.emitMethodList(
this, PD,
3047 ProtocolMethodLists::RequiredInstanceMethods));
3048 values.add(methodLists.emitMethodList(
this, PD,
3049 ProtocolMethodLists::RequiredClassMethods));
3053 assert(Entry->hasPrivateLinkage());
3054 values.finishAndSetAsInitializer(Entry);
3056 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
3059 llvm::GlobalValue::PrivateLinkage);
3060 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3069llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3070 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3076 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3077 false, llvm::GlobalValue::PrivateLinkage,
3078 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3079 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3081 Entry->setAlignment(llvm::Align(4));
3099 const ProtocolMethodLists &methodLists) {
3100 auto optInstanceMethods =
3101 methodLists.emitMethodList(
this, PD,
3102 ProtocolMethodLists::OptionalInstanceMethods);
3103 auto optClassMethods =
3104 methodLists.emitMethodList(
this, PD,
3105 ProtocolMethodLists::OptionalClassMethods);
3107 auto extendedMethodTypes =
3108 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3109 methodLists.emitExtendedTypesArray(
this),
3112 auto instanceProperties =
3113 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3115 auto classProperties =
3116 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3117 PD, ObjCTypes,
true);
3120 if (optInstanceMethods->isNullValue() &&
3121 optClassMethods->isNullValue() &&
3122 extendedMethodTypes->isNullValue() &&
3123 instanceProperties->isNullValue() &&
3124 classProperties->isNullValue()) {
3125 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3129 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3132 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3133 values.addInt(ObjCTypes.IntTy, size);
3134 values.add(optInstanceMethods);
3135 values.add(optClassMethods);
3136 values.add(instanceProperties);
3137 values.add(extendedMethodTypes);
3138 values.add(classProperties);
3141 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3153CGObjCMac::EmitProtocolList(Twine name,
3157 auto PDs = GetRuntimeProtocolList(begin, end);
3159 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3162 auto values = builder.beginStruct();
3165 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3168 auto countSlot = values.addPlaceholder();
3170 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3171 for (
const auto *Proto : PDs)
3172 refsArray.add(GetProtocolRef(Proto));
3174 auto count = refsArray.size();
3177 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3179 refsArray.finishAndAddTo(values);
3180 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3183 if (CGM.
getTriple().isOSBinFormatMachO())
3184 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3186 llvm::GlobalVariable *GV =
3187 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3195 bool IsClassProperty) {
3197 if (IsClassProperty != PD->isClassProperty())
3201 Properties.push_back(PD);
3220llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3221 const Decl *Container,
3223 const ObjCCommonTypesHelper &ObjCTypes,
3224 bool IsClassProperty) {
3225 if (IsClassProperty) {
3229 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3230 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3231 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3239 for (
auto *PD : ClassExt->properties()) {
3240 if (IsClassProperty != PD->isClassProperty())
3242 if (PD->isDirectProperty())
3245 Properties.push_back(PD);
3249 if (IsClassProperty != PD->isClassProperty())
3255 if (PD->isDirectProperty())
3257 Properties.push_back(PD);
3261 for (
const auto *
P : OID->all_referenced_protocols())
3265 for (
const auto *
P : CD->protocols())
3270 if (Properties.empty())
3271 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3273 unsigned propertySize =
3277 auto values = builder.beginStruct();
3278 values.addInt(ObjCTypes.IntTy, propertySize);
3279 values.addInt(ObjCTypes.IntTy, Properties.size());
3280 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3281 for (
auto PD : Properties) {
3282 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3284 property.add(GetPropertyTypeString(PD, Container));
3285 property.finishAndAddTo(propertiesArray);
3287 propertiesArray.finishAndAddTo(values);
3290 if (CGM.
getTriple().isOSBinFormatMachO())
3291 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3292 :
"__OBJC,__property,regular,no_dead_strip";
3294 llvm::GlobalVariable *GV =
3295 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3300CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3302 const ObjCCommonTypesHelper &ObjCTypes) {
3304 if (MethodTypes.empty())
3305 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3307 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3308 MethodTypes.size());
3309 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3312 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3313 Section =
"__DATA, __objc_const";
3315 llvm::GlobalVariable *GV =
3344 llvm::raw_svector_ostream(ExtName) <<
Interface->getName() <<
'_'
3348 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3356 for (
const auto *MD : OCD->
methods()) {
3357 if (!MD->isDirectMethod())
3358 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3361 Values.add(GetClassName(OCD->
getName()));
3362 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
3363 LazySymbols.insert(
Interface->getIdentifier());
3365 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3366 Methods[InstanceMethods]));
3367 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3368 Methods[ClassMethods]));
3371 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3374 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3376 Values.addInt(ObjCTypes.IntTy, Size);
3380 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
3382 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3385 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3386 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3389 llvm::GlobalVariable *GV =
3390 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3391 "__OBJC,__category,regular,no_dead_strip",
3393 DefinedCategories.push_back(GV);
3394 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3396 MethodDefinitions.clear();
3456 for (
auto *field : recType->getDecl()->fields()) {
3471 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3474 ID->getClassInterface()->all_declared_ivar_begin();
3475 ivar; ivar = ivar->getNextIvar()) {
3505 DefinedSymbols.insert(RuntimeName);
3507 std::string ClassName =
ID->getNameAsString();
3511 llvm::Constant *Protocols =
3512 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
3513 Interface->all_referenced_protocol_begin(),
3514 Interface->all_referenced_protocol_end());
3516 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
3519 bool hasMRCWeak =
false;
3539 for (
const auto *MD :
ID->methods()) {
3540 if (!MD->isDirectMethod())
3541 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3544 for (
const auto *PID :
ID->property_impls()) {
3546 if (PID->getPropertyDecl()->isDirectProperty())
3549 if (GetMethodDefinition(MD))
3550 Methods[InstanceMethods].push_back(MD);
3552 if (GetMethodDefinition(MD))
3553 Methods[InstanceMethods].push_back(MD);
3558 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3559 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3562 LazySymbols.insert(Super->getIdentifier());
3564 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
3566 values.addNullPointer(ObjCTypes.ClassPtrTy);
3568 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
3570 values.addInt(ObjCTypes.LongTy, 0);
3571 values.addInt(ObjCTypes.LongTy, Flags);
3572 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
3573 values.add(EmitIvarList(ID,
false));
3574 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
3575 Methods[InstanceMethods]));
3577 values.addNullPointer(ObjCTypes.CachePtrTy);
3578 values.add(Protocols);
3580 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3583 std::string Name(
"OBJC_CLASS_");
3585 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3587 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3589 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3590 "Forward metaclass reference has incorrect type.");
3591 values.finishAndSetAsInitializer(GV);
3592 GV->setSection(Section);
3596 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3597 DefinedClasses.push_back(GV);
3598 ImplementedClasses.push_back(
Interface);
3600 MethodDefinitions.clear();
3604 llvm::Constant *Protocols,
3613 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3623 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
3625 values.addNullPointer(ObjCTypes.ClassPtrTy);
3627 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
3629 values.addInt(ObjCTypes.LongTy, 0);
3630 values.addInt(ObjCTypes.LongTy, Flags);
3631 values.addInt(ObjCTypes.LongTy, Size);
3632 values.add(EmitIvarList(ID,
true));
3633 values.add(emitMethodList(
ID->getName(), MethodListType::ClassMethods,
3636 values.addNullPointer(ObjCTypes.CachePtrTy);
3637 values.add(Protocols);
3639 values.addNullPointer(ObjCTypes.Int8PtrTy);
3644 std::string Name(
"OBJC_METACLASS_");
3645 Name +=
ID->getName();
3648 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3650 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3651 "Forward metaclass reference has incorrect type.");
3652 values.finishAndSetAsInitializer(GV);
3656 llvm::GlobalValue::PrivateLinkage);
3658 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3665 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
3675 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3677 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3678 llvm::GlobalValue::PrivateLinkage,
nullptr,
3681 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3682 "Forward metaclass reference has incorrect type.");
3687 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
3688 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3691 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3692 llvm::GlobalValue::PrivateLinkage,
nullptr,
3695 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3696 "Forward class metadata reference has incorrect type.");
3716 llvm::Constant *layout;
3718 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3725 llvm::Constant *propertyList =
3726 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
3727 : Twine(
"_OBJC_$_PROP_LIST_"))
3729 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
3732 if (layout->isNullValue() && propertyList->isNullValue()) {
3733 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3737 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3740 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
3741 values.addInt(ObjCTypes.IntTy, size);
3743 values.add(propertyList);
3745 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
3746 "__OBJC,__class_ext,regular,no_dead_strip",
3770 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3775 auto ivarList = builder.beginStruct();
3776 auto countSlot = ivarList.addPlaceholder();
3777 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3782 if (!IVD->getDeclName())
3785 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3786 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3787 ivar.add(GetMethodVarType(IVD));
3788 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3789 ivar.finishAndAddTo(ivars);
3793 auto count = ivars.size();
3797 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3800 ivars.finishAndAddTo(ivarList);
3801 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3803 llvm::GlobalVariable *GV;
3804 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
3805 "__OBJC,__instance_vars,regular,no_dead_strip",
3818 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3819 description.add(GetMethodVarName(MD->
getSelector()));
3820 description.add(GetMethodVarType(MD));
3821 description.finishAndAddTo(builder);
3833 llvm::Function *fn = GetMethodDefinition(MD);
3834 assert(fn &&
"no definition registered for method");
3836 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3838 method.add(GetMethodVarType(MD));
3840 method.finishAndAddTo(builder);
3856llvm::Constant *CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
3860 bool forProtocol =
false;
3862 case MethodListType::CategoryInstanceMethods:
3863 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3864 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3865 forProtocol =
false;
3867 case MethodListType::CategoryClassMethods:
3868 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3869 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3870 forProtocol =
false;
3872 case MethodListType::InstanceMethods:
3873 prefix =
"OBJC_INSTANCE_METHODS_";
3874 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3875 forProtocol =
false;
3877 case MethodListType::ClassMethods:
3878 prefix =
"OBJC_CLASS_METHODS_";
3879 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3880 forProtocol =
false;
3882 case MethodListType::ProtocolInstanceMethods:
3883 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3884 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3887 case MethodListType::ProtocolClassMethods:
3888 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3889 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3892 case MethodListType::OptionalProtocolInstanceMethods:
3893 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3894 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3897 case MethodListType::OptionalProtocolClassMethods:
3898 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3899 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3905 if (methods.empty())
3906 return llvm::Constant::getNullValue(forProtocol
3907 ? ObjCTypes.MethodDescriptionListPtrTy
3908 : ObjCTypes.MethodListPtrTy);
3915 values.addInt(ObjCTypes.IntTy, methods.size());
3916 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3917 for (
auto MD : methods) {
3918 emitMethodDescriptionConstant(methodArray, MD);
3920 methodArray.finishAndAddTo(values);
3922 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3930 values.addNullPointer(ObjCTypes.Int8PtrTy);
3931 values.addInt(ObjCTypes.IntTy, methods.size());
3932 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3933 for (
auto MD : methods) {
3935 emitMethodConstant(methodArray, MD);
3937 methodArray.finishAndAddTo(values);
3939 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3944llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3946 llvm::Function *Method;
3949 Method = GenerateDirectMethod(OMD, CD);
3951 auto Name = getSymbolNameForMethod(OMD);
3954 llvm::FunctionType *MethodTy =
3955 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3957 llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage,
3961 MethodDefinitions.insert(std::make_pair(OMD, Method));
3970 auto I = DirectMethodDefinitions.find(COMD);
3971 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
3973 if (I != DirectMethodDefinitions.end()) {
3989 llvm::FunctionType *MethodTy =
3990 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3993 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
3995 Fn->takeName(OldFn);
3996 OldFn->replaceAllUsesWith(Fn);
3997 OldFn->eraseFromParent();
4002 auto Name = getSymbolNameForMethod(OMD,
false);
4004 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4006 DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));
4012void CGObjCCommonMac::GenerateDirectMethodPrologue(
4016 bool ReceiverCanBeNull =
true;
4018 auto selfValue = Builder.CreateLoad(selfAddr);
4036 "GenerateDirectMethod() should be called with the Class Interface");
4049 result = GeneratePossiblySpecializedMessageSend(
4057 ReceiverCanBeNull = isWeakLinkedClass(OID);
4060 if (ReceiverCanBeNull) {
4061 llvm::BasicBlock *SelfIsNilBlock =
4063 llvm::BasicBlock *ContBlock =
4067 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
4068 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4071 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,
4072 ContBlock, MDHelper.createUnlikelyBranchWeights());
4078 Builder.SetInsertPoint(SelfIsNilBlock);
4079 if (!retTy->isVoidType()) {
4087 Builder.SetInsertPoint(ContBlock);
4095 Builder.CreateStore(GetSelector(CGF, OMD),
4100llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4105 llvm::GlobalValue::LinkageTypes
LT =
4107 llvm::GlobalVariable *GV =
4108 Init.finishAndCreateGlobal(Name, Align,
false,
LT);
4109 if (!Section.empty())
4110 GV->setSection(Section);
4116llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4117 llvm::Constant *
Init,
4121 llvm::Type *Ty =
Init->getType();
4122 llvm::GlobalValue::LinkageTypes
LT =
4124 llvm::GlobalVariable *GV =
4126 if (!Section.empty())
4127 GV->setSection(Section);
4134llvm::GlobalVariable *
4135CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
4136 bool ForceNonFragileABI,
4137 bool NullTerminate) {
4140 case ObjCLabelType::ClassName:
Label =
"OBJC_CLASS_NAME_";
break;
4141 case ObjCLabelType::MethodVarName:
Label =
"OBJC_METH_VAR_NAME_";
break;
4142 case ObjCLabelType::MethodVarType:
Label =
"OBJC_METH_VAR_TYPE_";
break;
4143 case ObjCLabelType::PropertyName:
Label =
"OBJC_PROP_NAME_ATTR_";
break;
4146 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
4150 case ObjCLabelType::ClassName:
4151 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
4152 :
"__TEXT,__cstring,cstring_literals";
4154 case ObjCLabelType::MethodVarName:
4155 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
4156 :
"__TEXT,__cstring,cstring_literals";
4158 case ObjCLabelType::MethodVarType:
4159 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
4160 :
"__TEXT,__cstring,cstring_literals";
4162 case ObjCLabelType::PropertyName:
4163 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
4164 :
"__TEXT,__cstring,cstring_literals";
4168 llvm::Constant *
Value =
4169 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
4170 llvm::GlobalVariable *GV =
4173 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
4174 if (CGM.
getTriple().isOSBinFormatMachO())
4175 GV->setSection(Section);
4176 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4183llvm::Function *CGObjCMac::ModuleInitFunction() {
4189llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
4190 return ObjCTypes.getGetPropertyFn();
4193llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
4194 return ObjCTypes.getSetPropertyFn();
4197llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
4199 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4202llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
4203 return ObjCTypes.getCopyStructFn();
4206llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
4207 return ObjCTypes.getCopyStructFn();
4210llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
4211 return ObjCTypes.getCppAtomicObjectFunction();
4214llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
4215 return ObjCTypes.getCppAtomicObjectFunction();
4218llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
4219 return ObjCTypes.getEnumerationMutationFn();
4223 return EmitTryOrSynchronizedStmt(CGF, S);
4228 return EmitTryOrSynchronizedStmt(CGF, S);
4237 ObjCTypesHelper &ObjCTypes;
4238 PerformFragileFinally(
const Stmt *S,
4242 ObjCTypesHelper *ObjCTypes)
4243 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4244 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4249 llvm::BasicBlock *FinallyCallExit =
4251 llvm::BasicBlock *FinallyNoCallExit =
4254 FinallyCallExit, FinallyNoCallExit);
4262 if (isa<ObjCAtTryStmt>(S)) {
4264 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4266 if (flags.isForEHCleanup())
return;
4270 llvm::Value *CurCleanupDest =
4273 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4292 class FragileHazards {
4295 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
4297 llvm::InlineAsm *ReadHazard;
4298 llvm::InlineAsm *WriteHazard;
4300 llvm::FunctionType *GetAsmFnType();
4302 void collectLocals();
4308 void emitWriteHazard();
4309 void emitHazardsInNewBlocks();
4321 if (Locals.empty())
return;
4324 for (llvm::Function::iterator
4325 I = CGF.
CurFn->begin(),
E = CGF.
CurFn->end(); I !=
E; ++I)
4326 BlocksBeforeTry.insert(&*I);
4328 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4336 std::string Constraint;
4337 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++I) {
4338 if (I) Constraint +=
',';
4342 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4350 std::string Constraint;
4351 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++I) {
4352 if (I) Constraint +=
',';
4353 Constraint +=
"=*m";
4356 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4361void FragileHazards::emitWriteHazard() {
4362 if (Locals.empty())
return;
4365 for (
auto Pair : llvm::enumerate(Locals))
4366 Call->addParamAttr(Pair.index(), llvm::Attribute::get(
4368 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
4371void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4372 assert(!Locals.empty());
4373 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4374 call->setDoesNotThrow();
4376 for (
auto Pair : llvm::enumerate(Locals))
4377 call->addParamAttr(Pair.index(), llvm::Attribute::get(
4378 Builder.getContext(), llvm::Attribute::ElementType,
4379 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
4384void FragileHazards::emitHazardsInNewBlocks() {
4385 if (Locals.empty())
return;
4390 for (llvm::Function::iterator
4391 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4392 llvm::BasicBlock &BB = *FI;
4393 if (BlocksBeforeTry.count(&BB))
continue;
4396 for (llvm::BasicBlock::iterator
4397 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4398 llvm::Instruction &I = *BI;
4402 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
4404 if (isa<llvm::IntrinsicInst>(I))
4409 if (cast<llvm::CallBase>(I).doesNotThrow())
4417 Builder.SetInsertPoint(&BB, BI);
4418 emitReadHazard(Builder);
4425 if (llvm::Value *Ptr =
V.getBasePointer())
4429void FragileHazards::collectLocals() {
4431 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
4437 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4438 for (llvm::BasicBlock::iterator
4439 I = Entry.begin(),
E = Entry.end(); I !=
E; ++I)
4440 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4441 Locals.push_back(&*I);
4444llvm::FunctionType *FragileHazards::GetAsmFnType() {
4446 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4447 tys[i] = Locals[i]->getType();
4448 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4561 bool isTry = isa<ObjCAtTryStmt>(S);
4565 CodeGenFunction::JumpDest FinallyEnd =
4570 CodeGenFunction::JumpDest FinallyRethrow =
4580 llvm::Value *SyncArg =
4581 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4582 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
4594 "exceptiondata.ptr");
4600 FragileHazards Hazards(CGF);
4629 ExceptionData.emitRawPointer(CGF));
4632 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4635 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
4638 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4639 SetJmpResult->setCanReturnTwice();
4645 llvm::Value *DidCatch =
4646 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4647 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4652 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4653 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4655 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4661 Hazards.emitWriteHazard();
4665 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4675 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
4686 llvm::BasicBlock *CatchBlock =
nullptr;
4687 llvm::BasicBlock *CatchHandler =
nullptr;
4693 "propagating_exception");
4699 ExceptionData.emitRawPointer(CGF));
4701 llvm::CallInst *SetJmpResult =
4703 SetJmpBuffer,
"setjmp.result");
4704 SetJmpResult->setCanReturnTwice();
4706 llvm::Value *Threw =
4707 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4711 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4721 bool AllMatched =
false;
4723 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4742 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4749 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4752 CGF.
EmitStmt(CatchStmt->getCatchBody());
4755 CatchVarCleanups.ForceCleanup();
4761 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4766 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4769 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
4771 llvm::Value *matchArgs[] = {
Class, Caught };
4772 llvm::CallInst *Match =
4774 matchArgs,
"match");
4779 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4780 MatchedBlock, NextCatchBlock);
4787 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4794 CGF.
Builder.CreateBitCast(Caught,
4796 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4798 CGF.
EmitStmt(CatchStmt->getCatchBody());
4801 CatchVarCleanups.ForceCleanup();
4812 if (Caught->use_empty())
4813 Caught->eraseFromParent();
4829 assert(PropagatingExnVar.
isValid());
4831 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
4842 Hazards.emitHazardsInNewBlocks();
4845 CGF.
Builder.restoreIP(TryFallthroughIP);
4849 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4852 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4853 CGF.
EmitBlock(FinallyRethrow.getBlock(),
true);
4856 llvm::Value *PropagatingExn;
4857 if (PropagatingExnVar.
isValid()) {
4863 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
4864 PropagatingExn = Caught;
4869 CGF.
Builder.CreateUnreachable();
4872 CGF.
Builder.restoreIP(SavedIP);
4877 bool ClearInsertionPoint) {
4878 llvm::Value *ExceptionAsObject;
4880 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4883 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4886 "Unexpected rethrow outside @catch block.");
4890 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4891 ->setDoesNotReturn();
4892 CGF.
Builder.CreateUnreachable();
4895 if (ClearInsertionPoint)
4896 CGF.
Builder.ClearInsertionPoint();
4905 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
4907 llvm::Value *read_weak =
4909 AddrWeakObjVal,
"weakread");
4910 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
4918 llvm::Value *src,
Address dst) {
4919 llvm::Type * SrcTy = src->getType();
4920 if (!isa<llvm::PointerType>(SrcTy)) {
4922 assert(Size <= 8 && "does not support size > 8
");
4923 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4924 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4925 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4927 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4928 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4929 ObjCTypes.PtrObjectPtrTy);
4930 llvm::Value *args[] = { src, dstVal };
4931 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4932 args, "weakassign
");
4938void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4939 llvm::Value *src, Address dst,
4941 llvm::Type * SrcTy = src->getType();
4942 if (!isa<llvm::PointerType>(SrcTy)) {
4943 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4944 assert(Size <= 8 && "does
not support size > 8
");
4945 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4946 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4947 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4949 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4950 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4951 ObjCTypes.PtrObjectPtrTy);
4952 llvm::Value *args[] = {src, dstVal};
4954 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4955 args, "globalassign
");
4957 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4958 args, "threadlocalassign
");
4964void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4965 llvm::Value *src, Address dst,
4966 llvm::Value *ivarOffset) {
4967 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4968 llvm::Type * SrcTy = src->getType();
4969 if (!isa<llvm::PointerType>(SrcTy)) {
4970 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4971 assert(Size <= 8 && "does
not support size > 8
");
4972 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4973 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4974 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4976 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4977 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4978 ObjCTypes.PtrObjectPtrTy);
4979 llvm::Value *args[] = {src, dstVal, ivarOffset};
4980 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4986void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4987 llvm::Value *src, Address dst) {
4988 llvm::Type * SrcTy = src->getType();
4989 if (!isa<llvm::PointerType>(SrcTy)) {
4990 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4991 assert(Size <= 8 && "does
not support size > 8
");
4992 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4993 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4994 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4996 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4997 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4998 ObjCTypes.PtrObjectPtrTy);
4999 llvm::Value *args[] = {src, dstVal};
5000 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
5001 args, "strongassign
");
5004void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5005 Address DestPtr, Address SrcPtr,
5006 llvm::Value *size) {
5007 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5008 SrcPtr.emitRawPointer(CGF), size};
5009 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5014LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5016 llvm::Value *BaseValue,
5017 const ObjCIvarDecl *Ivar,
5018 unsigned CVRQualifiers) {
5019 const ObjCInterfaceDecl *ID =
5020 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5021 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5022 EmitIvarOffset(CGF, ID, Ivar));
5025llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5026 const ObjCInterfaceDecl *Interface,
5027 const ObjCIvarDecl *Ivar) {
5028 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5029 return llvm::ConstantInt::get(
5030 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
5034/* *** Private Interface *** */
5036std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5037 StringRef MachOAttributes) {
5038 switch (CGM.getTriple().getObjectFormat()) {
5039 case llvm::Triple::UnknownObjectFormat:
5040 llvm_unreachable("unexpected
object file format
");
5041 case llvm::Triple::MachO: {
5042 if (MachOAttributes.empty())
5043 return ("__DATA,
" + Section).str();
5044 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5046 case llvm::Triple::ELF:
5047 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5048 return Section.substr(2).str();
5049 case llvm::Triple::COFF:
5050 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5051 return (".
" + Section.substr(2) + "$B
").str();
5052 case llvm::Triple::Wasm:
5053 case llvm::Triple::GOFF:
5054 case llvm::Triple::SPIRV:
5055 case llvm::Triple::XCOFF:
5056 case llvm::Triple::DXContainer:
5057 llvm::report_fatal_error(
5058 "Objective-
C support is unimplemented
for object file format
");
5061 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5072enum ImageInfoFlags {
5073 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5074 eImageInfo_GarbageCollected = (1 << 1),
5075 eImageInfo_GCOnly = (1 << 2),
5076 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5078 // A flag indicating that the module has no instances of a @synthesize of a
5079 // superclass variable. This flag used to be consumed by the runtime to work
5080 // around miscompile by gcc.
5081 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
5082 eImageInfo_ImageIsSimulated = (1 << 5),
5083 eImageInfo_ClassProperties = (1 << 6)
5086void CGObjCCommonMac::EmitImageInfo() {
5087 unsigned version = 0; // Version is unused?
5088 std::string Section =
5090 ? "__OBJC,__image_info,regular
"
5091 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
5093 // Generate module-level named metadata to convey this information to the
5094 // linker and code-gen.
5095 llvm::Module &Mod = CGM.getModule();
5097 // Add the ObjC ABI version to the module flags.
5098 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
5099 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
5101 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
5102 llvm::MDString::get(VMContext, Section));
5104 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
5105 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5106 // Non-GC overrides those files which specify GC.
5107 Mod.addModuleFlag(llvm::Module::Error,
5108 "Objective-
C Garbage Collection
",
5109 llvm::ConstantInt::get(Int8Ty,0));
5111 // Add the ObjC garbage collection value.
5112 Mod.addModuleFlag(llvm::Module::Error,
5113 "Objective-
C Garbage Collection
",
5114 llvm::ConstantInt::get(Int8Ty,
5115 (uint8_t)eImageInfo_GarbageCollected));
5117 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
5118 // Add the ObjC GC Only value.
5119 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
5122 // Require that GC be specified and set to eImageInfo_GarbageCollected.
5123 llvm::Metadata *Ops[2] = {
5124 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
5125 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
5126 Int8Ty, eImageInfo_GarbageCollected))};
5127 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
5128 llvm::MDNode::get(VMContext, Ops));
5132 // Indicate whether we're compiling this to run on a simulator.
5133 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
5134 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
5135 eImageInfo_ImageIsSimulated);
5137 // Indicate whether we are generating class properties.
5138 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
5139 eImageInfo_ClassProperties);
5142// struct objc_module {
5143// unsigned long version;
5144// unsigned long size;
5149// FIXME: Get from somewhere
5150static const int ModuleVersion = 7;
5152void CGObjCMac::EmitModuleInfo() {
5153 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
5155 ConstantInitBuilder builder(CGM);
5156 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
5157 values.addInt(ObjCTypes.LongTy, ModuleVersion);
5158 values.addInt(ObjCTypes.LongTy, Size);
5159 // This used to be the filename, now it is unused. <rdr://4327263>
5160 values.add(GetClassName(StringRef("")));
5161 values.add(EmitModuleSymbols());
5162 CreateMetadataVar("OBJC_MODULES
", values,
5163 "__OBJC,__module_info,regular,no_dead_strip
",
5164 CGM.getPointerAlign(), true);
5167llvm::Constant *CGObjCMac::EmitModuleSymbols() {
5168 unsigned NumClasses = DefinedClasses.size();
5169 unsigned NumCategories = DefinedCategories.size();
5171 // Return null if no symbols were defined.
5172 if (!NumClasses && !NumCategories)
5173 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
5175 ConstantInitBuilder builder(CGM);
5176 auto values = builder.beginStruct();
5177 values.addInt(ObjCTypes.LongTy, 0);
5178 values.addNullPointer(ObjCTypes.SelectorPtrTy);
5179 values.addInt(ObjCTypes.ShortTy, NumClasses);
5180 values.addInt(ObjCTypes.ShortTy, NumCategories);
5182 // The runtime expects exactly the list of defined classes followed
5183 // by the list of defined categories, in a single array.
5184 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
5185 for (unsigned i=0; i<NumClasses; i++) {
5186 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5188 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5189 // We are implementing a weak imported interface. Give it external linkage
5190 if (ID->isWeakImported() && !IMP->isWeakImported())
5191 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5193 array.add(DefinedClasses[i]);
5195 for (unsigned i=0; i<NumCategories; i++)
5196 array.add(DefinedCategories[i]);
5198 array.finishAndAddTo(values);
5200 llvm::GlobalVariable *GV = CreateMetadataVar(
5201 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
5202 CGM.getPointerAlign(), true);
5206llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
5207 IdentifierInfo *II) {
5208 LazySymbols.insert(II);
5210 llvm::GlobalVariable *&Entry = ClassReferences[II];
5214 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
5215 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
5216 CGM.getPointerAlign(), true);
5219 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
5220 CGF.getPointerAlign());
5223llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
5224 const ObjCInterfaceDecl *ID) {
5225 // If the class has the objc_runtime_visible attribute, we need to
5226 // use the Objective-C runtime to get the class.
5227 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
5228 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
5230 IdentifierInfo *RuntimeName =
5231 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
5232 return EmitClassRefFromId(CGF, RuntimeName);
5235llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
5236 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
5237 return EmitClassRefFromId(CGF, II);
5240llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
5241 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
5244ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
5245 CharUnits Align = CGM.getPointerAlign();
5247 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5249 Entry = CreateMetadataVar(
5250 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
5251 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
5252 Entry->setExternallyInitialized(true);
5255 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
5258llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5259 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5261 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
5262 return getConstantGEP(VMContext, Entry, 0, 0);
5265llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5266 return MethodDefinitions.lookup(MD);
5271llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5272 const ObjCCommonTypesHelper &ObjCTypes) {
5273 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5276void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5278 const RecordDecl *RD = RT->getDecl();
5280 // If this is a union, remember that we had one, because it might mess
5281 // up the ordering of layout entries.
5283 IsDisordered = true;
5285 const ASTRecordLayout *recLayout = nullptr;
5286 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5287 [&](const FieldDecl *field) -> CharUnits {
5289 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5290 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5291 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5295template <class Iterator, class GetOffsetFn>
5296void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5297 CharUnits aggregateOffset,
5298 const GetOffsetFn &getOffset) {
5299 for (; begin != end; ++begin) {
5300 auto field = *begin;
5302 // Skip over bitfields.
5303 if (field->isBitField()) {
5307 // Compute the offset of the field within the aggregate.
5308 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5310 visitField(field, fieldOffset);
5315void IvarLayoutBuilder::visitField(const FieldDecl *field,
5316 CharUnits fieldOffset) {
5317 QualType fieldType = field->getType();
5319 // Drill down into arrays.
5320 uint64_t numElts = 1;
5321 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5323 fieldType = arrayType->getElementType();
5325 // Unlike incomplete arrays, constant arrays can be nested.
5326 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5327 numElts *= arrayType->getZExtSize();
5328 fieldType = arrayType->getElementType();
5331 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
5333 // If we ended up with a zero-sized array, we've done what we can do within
5334 // the limits of this layout encoding.
5335 if (numElts == 0) return;
5337 // Recurse if the base element type is a record type.
5338 if (auto recType = fieldType->getAs<RecordType>()) {
5339 size_t oldEnd = IvarsInfo.size();
5341 visitRecord(recType, fieldOffset);
5343 // If we have an array, replicate the first entry's layout information.
5344 auto numEltEntries = IvarsInfo.size() - oldEnd;
5345 if (numElts != 1 && numEltEntries != 0) {
5346 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
5347 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5348 // Copy the last numEltEntries onto the end of the array, adjusting
5349 // each for the element size.
5350 for (size_t i = 0; i != numEltEntries; ++i) {
5351 auto firstEntry = IvarsInfo[oldEnd + i];
5352 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5353 firstEntry.SizeInWords));
5361 // Classify the element type.
5362 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
5364 // If it matches what we're looking for, add an entry.
5365 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
5366 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5367 assert(CGM.getContext().getTypeSizeInChars(fieldType)
5368 == CGM.getPointerSize());
5369 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
5376llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5377 llvm::SmallVectorImpl<unsigned char> &buffer) {
5378 // The bitmap is a series of skip/scan instructions, aligned to word
5379 // boundaries. The skip is performed first.
5380 const unsigned char MaxNibble = 0xF;
5381 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5382 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5384 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
5386 // Sort the ivar info on byte position in case we encounterred a
5387 // union nested in the ivar list.
5389 // This isn't a stable sort, but our algorithm should handle it fine.
5390 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
5392 assert(llvm::is_sorted(IvarsInfo));
5394 assert(IvarsInfo.back().Offset < InstanceEnd);
5396 assert(buffer.empty());
5398 // Skip the next N words.
5399 auto skip = [&](unsigned numWords) {
5400 assert(numWords > 0);
5402 // Try to merge into the previous byte. Since scans happen second, we
5403 // can't do this if it includes a scan.
5404 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5405 unsigned lastSkip = buffer.back() >> SkipShift;
5406 if (lastSkip < MaxNibble) {
5407 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
5408 numWords -= claimed;
5409 lastSkip += claimed;
5410 buffer.back() = (lastSkip << SkipShift);
5414 while (numWords >= MaxNibble) {
5415 buffer.push_back(MaxNibble << SkipShift);
5416 numWords -= MaxNibble;
5419 buffer.push_back(numWords << SkipShift);
5423 // Scan the next N words.
5424 auto scan = [&](unsigned numWords) {
5425 assert(numWords > 0);
5427 // Try to merge into the previous byte. Since scans happen second, we can
5428 // do this even if it includes a skip.
5429 if (!buffer.empty()) {
5430 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5431 if (lastScan < MaxNibble) {
5432 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
5433 numWords -= claimed;
5434 lastScan += claimed;
5435 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5439 while (numWords >= MaxNibble) {
5440 buffer.push_back(MaxNibble << ScanShift);
5441 numWords -= MaxNibble;
5444 buffer.push_back(numWords << ScanShift);
5448 // One past the end of the last scan.
5449 unsigned endOfLastScanInWords = 0;
5450 const CharUnits WordSize = CGM.getPointerSize();
5452 // Consider all the scan requests.
5453 for (auto &request : IvarsInfo) {
5454 CharUnits beginOfScan = request.Offset - InstanceBegin;
5456 // Ignore scan requests that don't start at an even multiple of the
5457 // word size. We can't encode them.
5458 if ((beginOfScan % WordSize) != 0) continue;
5460 // Ignore scan requests that start before the instance start.
5461 // This assumes that scans never span that boundary. The boundary
5462 // isn't the true start of the ivars, because in the fragile-ARC case
5463 // it's rounded up to word alignment, but the test above should leave
5464 // us ignoring that possibility.
5465 if (beginOfScan.isNegative()) {
5466 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5470 unsigned beginOfScanInWords = beginOfScan / WordSize;
5471 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5473 // If the scan starts some number of words after the last one ended,
5475 if (beginOfScanInWords > endOfLastScanInWords) {
5476 skip(beginOfScanInWords - endOfLastScanInWords);
5478 // Otherwise, start scanning where the last left off.
5480 beginOfScanInWords = endOfLastScanInWords;
5482 // If that leaves us with nothing to scan, ignore this request.
5483 if (beginOfScanInWords >= endOfScanInWords) continue;
5486 // Scan to the end of the request.
5487 assert(beginOfScanInWords < endOfScanInWords);
5488 scan(endOfScanInWords - beginOfScanInWords);
5489 endOfLastScanInWords = endOfScanInWords;
5493 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
5495 // For GC layouts, emit a skip to the end of the allocation so that we
5496 // have precise information about the entire thing. This isn't useful
5497 // or necessary for the ARC-style layout strings.
5498 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5499 unsigned lastOffsetInWords =
5500 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5501 if (lastOffsetInWords > endOfLastScanInWords) {
5502 skip(lastOffsetInWords - endOfLastScanInWords);
5506 // Null terminate the string.
5507 buffer.push_back(0);
5509 auto *Entry = CGObjC.CreateCStringLiteral(
5510 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
5511 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
5531CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5532 CharUnits beginOffset, CharUnits endOffset,
5533 bool ForStrongLayout, bool HasMRCWeakIvars) {
5534 // If this is MRC, and we're either building a strong layout or there
5535 // are no weak ivars, bail out early.
5536 llvm::Type *PtrTy = CGM.Int8PtrTy;
5537 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5538 !CGM.getLangOpts().ObjCAutoRefCount &&
5539 (ForStrongLayout || !HasMRCWeakIvars))
5540 return llvm::Constant::getNullValue(PtrTy);
5542 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5543 SmallVector<const ObjCIvarDecl*, 32> ivars;
5545 // GC layout strings include the complete object layout, possibly
5546 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5549 // ARC layout strings only include the class's ivars. In non-fragile
5550 // runtimes, that means starting at InstanceStart, rounded up to word
5551 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5552 // starting at the offset of the first ivar, rounded up to word alignment.
5554 // MRC weak layout strings follow the ARC style.
5555 CharUnits baseOffset;
5556 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5557 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5558 IVD; IVD = IVD->getNextIvar())
5559 ivars.push_back(IVD);
5561 if (isNonFragileABI()) {
5562 baseOffset = beginOffset; // InstanceStart
5563 } else if (!ivars.empty()) {
5565 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5567 baseOffset = CharUnits::Zero();
5570 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5573 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5575 baseOffset = CharUnits::Zero();
5579 return llvm::Constant::getNullValue(PtrTy);
5581 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5583 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5584 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5585 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5588 if (!builder.hasBitmapData())
5589 return llvm::Constant::getNullValue(PtrTy);
5591 llvm::SmallVector<unsigned char, 4> buffer;
5592 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5594 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5595 printf("\n%
s ivar layout
for class '%s':
",
5596 ForStrongLayout ? "strong
" : "weak
",
5597 OMD->getClassInterface()->getName().str().c_str());
5598 builder.dump(buffer);
5603llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5604 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5605 // FIXME: Avoid std::string in "Sel.
getAsString()
"
5607 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
5608 return getConstantGEP(VMContext, Entry, 0, 0);
5611// FIXME: Merge into a single cstring creation function.
5612llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5613 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5616llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5617 std::string TypeStr;
5618 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5620 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5622 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5623 return getConstantGEP(VMContext, Entry, 0, 0);
5626llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5628 std::string TypeStr =
5629 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
5631 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5633 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5634 return getConstantGEP(VMContext, Entry, 0, 0);
5637// FIXME: Merge into a single cstring creation function.
5638llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5639 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5641 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
5642 return getConstantGEP(VMContext, Entry, 0, 0);
5645// FIXME: Merge into a single cstring creation function.
5646// FIXME: This Decl should be more precise.
5648CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5649 const Decl *Container) {
5650 std::string TypeStr =
5651 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5652 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5655void CGObjCMac::FinishModule() {
5658 // Emit the dummy bodies for any protocols which were referenced but
5660 for (auto &entry : Protocols) {
5661 llvm::GlobalVariable *global = entry.second;
5662 if (global->hasInitializer())
5665 ConstantInitBuilder builder(CGM);
5666 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
5667 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
5668 values.add(GetClassName(entry.first->getName()));
5669 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
5670 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5671 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5672 values.finishAndSetAsInitializer(global);
5673 CGM.addCompilerUsedGlobal(global);
5676 // Add assembler directives to add lazy undefined symbol references
5677 // for classes which are referenced but not defined. This is
5678 // important for correct linker interaction.
5680 // FIXME: It would be nice if we had an LLVM construct for this.
5681 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5682 CGM.getTriple().isOSBinFormatMachO()) {
5683 SmallString<256> Asm;
5684 Asm += CGM.getModule().getModuleInlineAsm();
5685 if (!Asm.empty() && Asm.back() != '\n')
5688 llvm::raw_svector_ostream OS(Asm);
5689 for (const auto *Sym : DefinedSymbols)
5690 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
5691 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
5692 for (const auto *Sym : LazySymbols)
5693 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
5694 for (const auto &Category : DefinedCategoryNames)
5695 OS << "\t.objc_category_name_
" << Category << "=0\n
"
5696 << "\t.globl .objc_category_name_
" << Category << "\n
";
5698 CGM.getModule().setModuleInlineAsm(OS.str());
5702CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5703 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5704 ObjCEmptyVtableVar(nullptr) {
5710ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5711 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5713 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5714 ASTContext &Ctx = CGM.getContext();
5715 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
5717 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
5719 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
5720 Int8PtrTy = CGM.Int8PtrTy;
5721 Int8PtrProgramASTy = llvm::PointerType::get(CGM.Int8Ty, ProgramAS);
5722 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5724 // arm64 targets use "int" ivar offset variables. All others,
5725 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5726 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5727 IvarOffsetVarTy = IntTy;
5729 IvarOffsetVarTy = LongTy;
5732 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
5734 llvm::PointerType::getUnqual(ObjectPtrTy);
5736 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
5738 // I'm not sure I like this. The implicit coordination is a bit
5739 // gross. We should solve this in a reasonable fashion because this
5740 // is a pretty common task (match some runtime data structure with
5741 // an LLVM data structure).
5743 // FIXME: This is leaked.
5744 // FIXME: Merge with rewriter code?
5746 // struct _objc_super {
5750 RecordDecl *RD = RecordDecl::Create(
5751 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
5752 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
5753 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5754 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5755 false, ICIS_NoInit));
5756 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5757 nullptr, Ctx.getObjCClassType(), nullptr,
5758 nullptr, false, ICIS_NoInit));
5759 RD->completeDefinition();
5761 SuperCTy = Ctx.getTagDeclType(RD);
5762 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5764 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5765 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5769 // char *attributes;
5771 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
5773 // struct _prop_list_t {
5774 // uint32_t entsize; // sizeof(struct _prop_t)
5775 // uint32_t count_of_properties;
5776 // struct _prop_t prop_list[count_of_properties];
5778 PropertyListTy = llvm::StructType::create(
5779 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
5780 // struct _prop_list_t *
5781 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5783 // struct _objc_method {
5785 // char *method_type;
5788 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
5789 Int8PtrTy, Int8PtrProgramASTy);
5791 // struct _objc_cache *
5792 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5793 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5796ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5797 : ObjCCommonTypesHelper(cgm) {
5798 // struct _objc_method_description {
5802 MethodDescriptionTy = llvm::StructType::create(
5803 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
5805 // struct _objc_method_description_list {
5807 // struct _objc_method_description[1];
5809 MethodDescriptionListTy =
5810 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
5811 llvm::ArrayType::get(MethodDescriptionTy, 0));
5813 // struct _objc_method_description_list *
5814 MethodDescriptionListPtrTy =
5815 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5817 // Protocol description structures
5819 // struct _objc_protocol_extension {
5820 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5821 // struct _objc_method_description_list *optional_instance_methods;
5822 // struct _objc_method_description_list *optional_class_methods;
5823 // struct _objc_property_list *instance_properties;
5824 // const char ** extendedMethodTypes;
5825 // struct _objc_property_list *class_properties;
5827 ProtocolExtensionTy = llvm::StructType::create(
5828 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
5829 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
5832 // struct _objc_protocol_extension *
5833 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5835 // Handle construction of Protocol and ProtocolList types
5837 // struct _objc_protocol {
5838 // struct _objc_protocol_extension *isa;
5839 // char *protocol_name;
5840 // struct _objc_protocol **_objc_protocol_list;
5841 // struct _objc_method_description_list *instance_methods;
5842 // struct _objc_method_description_list *class_methods;
5844 ProtocolTy = llvm::StructType::create(
5845 {ProtocolExtensionPtrTy, Int8PtrTy,
5846 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
5847 MethodDescriptionListPtrTy},
5848 "struct._objc_protocol
");
5851 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
5852 llvm::ArrayType::get(ProtocolTy, 0)},
5853 "struct._objc_protocol_list
");
5855 // struct _objc_protocol_list *
5856 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5858 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5860 // Class description structures
5862 // struct _objc_ivar {
5867 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
5870 // struct _objc_ivar_list *
5872 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5873 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5875 // struct _objc_method_list *
5877 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5878 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5880 // struct _objc_class_extension *
5881 ClassExtensionTy = llvm::StructType::create(
5882 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
5883 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5885 // struct _objc_class {
5887 // Class super_class;
5891 // long instance_size;
5892 // struct _objc_ivar_list *ivars;
5893 // struct _objc_method_list *methods;
5894 // struct _objc_cache *cache;
5895 // struct _objc_protocol_list *protocols;
5896 // char *ivar_layout;
5897 // struct _objc_class_ext *ext;
5899 ClassTy = llvm::StructType::create(
5900 {llvm::PointerType::getUnqual(VMContext),
5901 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
5902 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
5903 Int8PtrTy, ClassExtensionPtrTy},
5904 "struct._objc_class
");
5906 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5908 // struct _objc_category {
5909 // char *category_name;
5910 // char *class_name;
5911 // struct _objc_method_list *instance_method;
5912 // struct _objc_method_list *class_method;
5913 // struct _objc_protocol_list *protocols;
5914 // uint32_t size; // sizeof(struct _objc_category)
5915 // struct _objc_property_list *instance_properties;// category's @property
5916 // struct _objc_property_list *class_properties;
5918 CategoryTy = llvm::StructType::create(
5919 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5920 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
5923 // Global metadata structures
5925 // struct _objc_symtab {
5926 // long sel_ref_cnt;
5928 // short cls_def_cnt;
5929 // short cat_def_cnt;
5930 // char *defs[cls_def_cnt + cat_def_cnt];
5932 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
5933 SelectorPtrTy, ShortTy, ShortTy,
5934 llvm::ArrayType::get(Int8PtrTy, 0));
5935 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5937 // struct _objc_module {
5939 // long size; // sizeof(struct _objc_module)
5941 // struct _objc_symtab* symtab;
5943 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
5944 Int8PtrTy, SymtabPtrTy);
5946 // FIXME: This is the size of the setjmp buffer and should be target
5947 // specific. 18 is what's used on 32-bit X86.
5948 uint64_t SetJmpBufferSize = 18;
5951 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5953 ExceptionDataTy = llvm::StructType::create(
5954 "struct._objc_exception_data
",
5955 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
5958ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5959 : ObjCCommonTypesHelper(cgm) {
5960 // struct _method_list_t {
5961 // uint32_t entsize; // sizeof(struct _objc_method)
5962 // uint32_t method_count;
5963 // struct _objc_method method_list[method_count];
5966 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5967 llvm::ArrayType::get(MethodTy, 0));
5968 // struct method_list_t *
5969 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5971 // struct _protocol_t {
5973 // const char * const protocol_name;
5974 // const struct _protocol_list_t * protocol_list; // super protocols
5975 // const struct method_list_t * const instance_methods;
5976 // const struct method_list_t * const class_methods;
5977 // const struct method_list_t *optionalInstanceMethods;
5978 // const struct method_list_t *optionalClassMethods;
5979 // const struct _prop_list_t * properties;
5980 // const uint32_t size; // sizeof(struct _protocol_t)
5981 // const uint32_t flags; // = 0
5982 // const char ** extendedMethodTypes;
5983 // const char *demangledName;
5984 // const struct _prop_list_t * class_properties;
5987 ProtocolnfABITy = llvm::StructType::create(
5988 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5989 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
5990 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5991 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
5994 // struct _protocol_t*
5995 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5997 // struct _protocol_list_t {
5998 // long protocol_count; // Note, this is 32/64 bit
5999 // struct _protocol_t *[protocol_count];
6001 ProtocolListnfABITy = llvm::StructType::create(
6002 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6003 "struct._objc_protocol_list
");
6005 // struct _objc_protocol_list*
6006 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
6009 // unsigned [long] int *offset; // pointer to ivar offset location
6012 // uint32_t alignment;
6015 IvarnfABITy = llvm::StructType::create(
6016 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
6017 Int8PtrTy, Int8PtrTy, IntTy, IntTy);
6019 // struct _ivar_list_t {
6020 // uint32 entsize; // sizeof(struct _ivar_t)
6022 // struct _iver_t list[count];
6025 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6026 llvm::ArrayType::get(IvarnfABITy, 0));
6028 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
6030 // struct _class_ro_t {
6031 // uint32_t const flags;
6032 // uint32_t const instanceStart;
6033 // uint32_t const instanceSize;
6034 // uint32_t const reserved; // only when building for 64bit targets
6035 // const uint8_t * const ivarLayout;
6036 // const char *const name;
6037 // const struct _method_list_t * const baseMethods;
6038 // const struct _objc_protocol_list *const baseProtocols;
6039 // const struct _ivar_list_t *const ivars;
6040 // const uint8_t * const weakIvarLayout;
6041 // const struct _prop_list_t * const properties;
6044 // FIXME. Add 'reserved' field in 64bit abi mode!
6045 ClassRonfABITy = llvm::StructType::create(
6046 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6047 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6048 Int8PtrTy, PropertyListPtrTy);
6050 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6051 ImpnfABITy = CGM.UnqualPtrTy;
6053 // struct _class_t {
6054 // struct _class_t *isa;
6055 // struct _class_t * const superclass;
6058 // struct class_ro_t *ro;
6061 ClassnfABITy = llvm::StructType::create(
6062 {llvm::PointerType::getUnqual(VMContext),
6063 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6064 llvm::PointerType::getUnqual(ImpnfABITy),
6065 llvm::PointerType::getUnqual(ClassRonfABITy)},
6068 // LLVM for struct _class_t *
6069 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
6071 // struct _category_t {
6072 // const char * const name;
6073 // struct _class_t *const cls;
6074 // const struct _method_list_t * const instance_methods;
6075 // const struct _method_list_t * const class_methods;
6076 // const struct _protocol_list_t * const protocols;
6077 // const struct _prop_list_t * const properties;
6078 // const struct _prop_list_t * const class_properties;
6079 // const uint32_t size;
6081 CategorynfABITy = llvm::StructType::create(
6082 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6083 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6084 PropertyListPtrTy, IntTy);
6086 // New types for nonfragile abi messaging.
6087 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6088 ASTContext &Ctx = CGM.getContext();
6090 // MessageRefTy - LLVM for:
6091 // struct _message_ref_t {
6096 // First the clang type for struct _message_ref_t
6097 RecordDecl *RD = RecordDecl::Create(
6098 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6099 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
6100 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6101 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
6103 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6104 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
6105 false, ICIS_NoInit));
6106 RD->completeDefinition();
6108 MessageRefCTy = Ctx.getTagDeclType(RD);
6109 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
6110 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
6112 // MessageRefPtrTy - LLVM for struct _message_ref_t*
6113 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
6115 // SuperMessageRefTy - LLVM for:
6116 // struct _super_message_ref_t {
6117 // SUPER_IMP messenger;
6120 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
6121 ImpnfABITy, SelectorPtrTy);
6123 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
6124 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
6127 // struct objc_typeinfo {
6128 // const void** vtable; // objc_ehtype_vtable + 2
6129 // const char* name; // c++ typeinfo string
6132 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
6133 llvm::PointerType::getUnqual(Int8PtrTy),
6134 Int8PtrTy, ClassnfABIPtrTy);
6135 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
6138llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
6139 FinishNonFragileABIModule();
6144void CGObjCNonFragileABIMac::AddModuleClassList(
6145 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
6146 StringRef SectionName) {
6147 unsigned NumClasses = Container.size();
6152 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
6153 for (unsigned i=0; i<NumClasses; i++)
6154 Symbols[i] = Container[i];
6156 llvm::Constant *Init =
6157 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
6161 // Section name is obtained by calling GetSectionName, which returns
6162 // sections in the __DATA segment on MachO.
6163 assert((!CGM.getTriple().isOSBinFormatMachO() ||
6164 SectionName.starts_with("__DATA
")) &&
6165 "SectionName expected to start with __DATA on MachO
");
6166 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
6167 CGM.getModule(), Init->getType(), false,
6168 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
6169 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
6170 GV->setSection(SectionName);
6171 CGM.addCompilerUsedGlobal(GV);
6174void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
6175 // nonfragile abi has no module definition.
6177 // Build list of all implemented class addresses in array
6178 // L_OBJC_LABEL_CLASS_$.
6180 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
6181 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6183 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6184 // We are implementing a weak imported interface. Give it external linkage
6185 if (ID->isWeakImported() && !IMP->isWeakImported()) {
6186 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6187 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6191 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
6192 GetSectionName("__objc_classlist
",
6193 "regular,no_dead_strip
"));
6195 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
6196 GetSectionName("__objc_nlclslist
",
6197 "regular,no_dead_strip
"));
6199 // Build list of all implemented category addresses in array
6200 // L_OBJC_LABEL_CATEGORY_$.
6201 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
6202 GetSectionName("__objc_catlist
",
6203 "regular,no_dead_strip
"));
6204 AddModuleClassList(DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
6205 GetSectionName("__objc_catlist2
",
6206 "regular,no_dead_strip
"));
6207 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
6208 GetSectionName("__objc_nlcatlist
",
6209 "regular,no_dead_strip
"));
6218bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6219 // At various points we've experimented with using vtable-based
6220 // dispatch for all methods.
6221 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6222 case CodeGenOptions::Legacy:
6224 case CodeGenOptions::NonLegacy:
6226 case CodeGenOptions::Mixed:
6230 // If so, see whether this selector is in the white-list of things which must
6231 // use the new dispatch convention. We lazily build a dense set for this.
6232 if (VTableDispatchMethods.empty()) {
6233 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
6234 VTableDispatchMethods.insert(GetNullarySelector("class"));
6235 VTableDispatchMethods.insert(GetNullarySelector("self
"));
6236 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
6237 VTableDispatchMethods.insert(GetNullarySelector("length"));
6238 VTableDispatchMethods.insert(GetNullarySelector("count
"));
6240 // These are vtable-based if GC is disabled.
6241 // Optimistically use vtable dispatch for hybrid compiles.
6242 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6243 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
6244 VTableDispatchMethods.insert(GetNullarySelector("release
"));
6245 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
6248 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
6249 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
6250 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
6251 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
6252 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
6253 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
6254 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
6256 // These are vtable-based if GC is enabled.
6257 // Optimistically use vtable dispatch for hybrid compiles.
6258 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6259 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
6260 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
6262 // "countByEnumeratingWithState:objects:count
"
6263 const IdentifierInfo *KeyIdents[] = {
6264 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
6265 &CGM.getContext().Idents.get("objects
"),
6266 &CGM.getContext().Idents.get("count
")};
6267 VTableDispatchMethods.insert(
6268 CGM.getContext().Selectors.getSelector(3, KeyIdents));
6272 return VTableDispatchMethods.count(Sel);
6290llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6292 unsigned InstanceStart,
6293 unsigned InstanceSize,
6294 const ObjCImplementationDecl *ID) {
6295 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
6297 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6298 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6300 bool hasMRCWeak = false;
6301 if (CGM.getLangOpts().ObjCAutoRefCount)
6302 flags |= NonFragileABI_Class_CompiledByARC;
6303 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6304 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6306 ConstantInitBuilder builder(CGM);
6307 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6309 values.addInt(ObjCTypes.IntTy, flags);
6310 values.addInt(ObjCTypes.IntTy, InstanceStart);
6311 values.addInt(ObjCTypes.IntTy, InstanceSize);
6312 values.add((flags & NonFragileABI_Class_Meta)
6313 ? GetIvarLayoutName(nullptr, ObjCTypes)
6314 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6315 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6317 // const struct _method_list_t * const baseMethods;
6318 SmallVector<const ObjCMethodDecl*, 16> methods;
6319 if (flags & NonFragileABI_Class_Meta) {
6320 for (const auto *MD : ID->class_methods())
6321 if (!MD->isDirectMethod())
6322 methods.push_back(MD);
6324 for (const auto *MD : ID->instance_methods())
6325 if (!MD->isDirectMethod())
6326 methods.push_back(MD);
6329 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6330 (flags & NonFragileABI_Class_Meta)
6331 ? MethodListType::ClassMethods
6332 : MethodListType::InstanceMethods,
6335 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6336 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
6337 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
"
6338 + OID->getObjCRuntimeNameAsString(),
6339 OID->all_referenced_protocol_begin(),
6340 OID->all_referenced_protocol_end()));
6342 if (flags & NonFragileABI_Class_Meta) {
6343 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
6344 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
6345 values.add(EmitPropertyList(
6346 "_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6347 ID, ID->getClassInterface(), ObjCTypes, true));
6349 values.add(EmitIvarList(ID));
6350 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
6351 values.add(EmitPropertyList(
6352 "_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6353 ID, ID->getClassInterface(), ObjCTypes, false));
6356 llvm::SmallString<64> roLabel;
6357 llvm::raw_svector_ostream(roLabel)
6358 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
6359 : "_OBJC_CLASS_RO_$_
")
6362 return finishAndCreateGlobal(values, roLabel, CGM);
6375llvm::GlobalVariable *
6376CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6378 llvm::Constant *IsAGV,
6379 llvm::Constant *SuperClassGV,
6380 llvm::Constant *ClassRoGV,
6381 bool HiddenVisibility) {
6382 ConstantInitBuilder builder(CGM);
6383 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6386 values.add(SuperClassGV);
6388 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6390 values.add(ObjCEmptyCacheVar);
6391 values.add(ObjCEmptyVtableVar);
6392 values.add(ClassRoGV);
6394 llvm::GlobalVariable *GV =
6395 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6396 values.finishAndSetAsInitializer(GV);
6398 if (CGM.getTriple().isOSBinFormatMachO())
6399 GV->setSection("__DATA, __objc_data
");
6400 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
6401 if (!CGM.getTriple().isOSBinFormatCOFF())
6402 if (HiddenVisibility)
6403 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6407bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
6408 const ObjCImplDecl *OD) const {
6409 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
6410 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
6411 OD->hasAttr<ObjCNonLazyClassAttr>();
6414void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6415 uint32_t &InstanceStart,
6416 uint32_t &InstanceSize) {
6417 const ASTRecordLayout &RL =
6418 CGM.getContext().getASTObjCImplementationLayout(OID);
6420 // InstanceSize is really instance end.
6421 InstanceSize = RL.getDataSize().getQuantity();
6423 // If there are no fields, the start is the same as the end.
6424 if (!RL.getFieldCount())
6425 InstanceStart = InstanceSize;
6427 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
6430static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6432 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6433 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6434 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
6436 const VarDecl *VD = nullptr;
6437 for (const auto *Result : DC->lookup(&II))
6438 if ((VD = dyn_cast<VarDecl>(Result)))
6442 return llvm::GlobalValue::DLLImportStorageClass;
6443 if (VD->hasAttr<DLLExportAttr>())
6444 return llvm::GlobalValue::DLLExportStorageClass;
6445 if (VD->hasAttr<DLLImportAttr>())
6446 return llvm::GlobalValue::DLLImportStorageClass;
6447 return llvm::GlobalValue::DefaultStorageClass;
6450void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6451 if (!ObjCEmptyCacheVar) {
6453 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6454 llvm::GlobalValue::ExternalLinkage, nullptr,
6455 "_objc_empty_cache
");
6456 if (CGM.getTriple().isOSBinFormatCOFF())
6457 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
"));
6459 // Only OS X with deployment version <10.9 use the empty vtable symbol
6460 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6461 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6462 ObjCEmptyVtableVar =
6463 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6464 llvm::GlobalValue::ExternalLinkage, nullptr,
6465 "_objc_empty_vtable
");
6467 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.UnqualPtrTy);
6470 // FIXME: Is this correct (that meta class size is never computed)?
6471 uint32_t InstanceStart =
6472 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6473 uint32_t InstanceSize = InstanceStart;
6474 uint32_t flags = NonFragileABI_Class_Meta;
6476 llvm::Constant *SuperClassGV, *IsAGV;
6478 const auto *CI = ID->getClassInterface();
6479 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
6481 // Build the flags for the metaclass.
6482 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
6483 ? !CI->hasAttr<DLLExportAttr>()
6484 : CI->getVisibility() == HiddenVisibility;
6486 flags |= NonFragileABI_Class_Hidden;
6488 // FIXME: why is this flag set on the metaclass?
6489 // ObjC metaclasses have no fields and don't really get constructed.
6490 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6491 flags |= NonFragileABI_Class_HasCXXStructors;
6492 if (!ID->hasNonZeroConstructors())
6493 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6496 if (!CI->getSuperClass()) {
6498 flags |= NonFragileABI_Class_Root;
6500 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
6501 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
6503 // Has a root. Current class is not a root.
6504 const ObjCInterfaceDecl *Root = ID->getClassInterface();
6505 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6508 const auto *Super = CI->getSuperClass();
6509 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
6510 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
6513 llvm::GlobalVariable *CLASS_RO_GV =
6514 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6516 llvm::GlobalVariable *MetaTClass =
6517 BuildClassObject(CI, /*metaclass*/ true,
6518 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6519 CGM.setGVProperties(MetaTClass, CI);
6520 DefinedMetaClasses.push_back(MetaTClass);
6522 // Metadata for the class
6525 flags |= NonFragileABI_Class_Hidden;
6527 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6528 flags |= NonFragileABI_Class_HasCXXStructors;
6530 // Set a flag to enable a runtime optimization when a class has
6531 // fields that require destruction but which don't require
6532 // anything except zero-initialization during construction. This
6533 // is most notably true of __strong and __weak types, but you can
6534 // also imagine there being C++ types with non-trivial default
6535 // constructors that merely set all fields to null.
6536 if (!ID->hasNonZeroConstructors())
6537 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6540 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
6541 flags |= NonFragileABI_Class_Exception;
6543 if (!CI->getSuperClass()) {
6544 flags |= NonFragileABI_Class_Root;
6545 SuperClassGV = nullptr;
6547 // Has a root. Current class is not a root.
6548 const auto *Super = CI->getSuperClass();
6549 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
6552 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6554 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6556 llvm::GlobalVariable *ClassMD =
6557 BuildClassObject(CI, /*metaclass*/ false,
6558 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6559 CGM.setGVProperties(ClassMD, CI);
6560 DefinedClasses.push_back(ClassMD);
6561 ImplementedClasses.push_back(CI);
6563 // Determine if this class is also "non-lazy
".
6564 if (ImplementationIsNonLazy(ID))
6565 DefinedNonLazyClasses.push_back(ClassMD);
6567 // Force the definition of the EHType if necessary.
6568 if (flags & NonFragileABI_Class_Exception)
6569 (void) GetInterfaceEHType(CI, ForDefinition);
6570 // Make sure method definition entries are all clear for next implementation.
6571 MethodDefinitions.clear();
6582llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6583 const ObjCProtocolDecl *PD) {
6585 // This routine is called for @protocol only. So, we must build definition
6586 // of protocol's meta-data (not a reference to it!)
6587 assert(!PD->isNonRuntimeProtocol() &&
6588 "attempting to get a protocol ref to a
static protocol.
");
6589 llvm::Constant *Init = GetOrEmitProtocol(PD);
6591 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
6592 ProtocolName += PD->getObjCRuntimeNameAsString();
6594 CharUnits Align = CGF.getPointerAlign();
6596 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
6598 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
6599 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6600 llvm::GlobalValue::WeakAnyLinkage, Init,
6602 PTGV->setSection(GetSectionName("__objc_protorefs
",
6603 "coalesced,no_dead_strip
"));
6604 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6605 PTGV->setAlignment(Align.getAsAlign());
6606 if (!CGM.getTriple().isOSBinFormatMachO())
6607 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
6608 CGM.addUsedGlobal(PTGV);
6609 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
6624void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6625 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6626 const char *Prefix = "_OBJC_$_CATEGORY_
";
6628 llvm::SmallString<64> ExtCatName(Prefix);
6629 ExtCatName += Interface->getObjCRuntimeNameAsString();
6630 ExtCatName += "_$_
";
6631 ExtCatName += OCD->getNameAsString();
6633 ConstantInitBuilder builder(CGM);
6634 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
6635 values.add(GetClassName(OCD->getIdentifier()->getName()));
6636 // meta-class entry symbol
6637 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
6638 std::string listName =
6639 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
6641 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
6642 SmallVector<const ObjCMethodDecl *, 8> classMethods;
6643 for (const auto *MD : OCD->methods()) {
6644 if (MD->isDirectMethod())
6646 if (MD->isInstanceMethod()) {
6647 instanceMethods.push_back(MD);
6649 classMethods.push_back(MD);
6653 auto instanceMethodList = emitMethodList(
6654 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
6655 auto classMethodList = emitMethodList(
6656 listName, MethodListType::CategoryClassMethods, classMethods);
6657 values.add(instanceMethodList);
6658 values.add(classMethodList);
6659 // Keep track of whether we have actual metadata to emit.
6660 bool isEmptyCategory =
6661 instanceMethodList->isNullValue() && classMethodList->isNullValue();
6663 const ObjCCategoryDecl *Category =
6664 Interface->FindCategoryDeclaration(OCD->getIdentifier());
6666 SmallString<256> ExtName;
6667 llvm::raw_svector_ostream(ExtName)
6668 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
6670 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
6671 Interface->getObjCRuntimeNameAsString() + "_$_
" +
6672 Category->getName(),
6673 Category->protocol_begin(), Category->protocol_end());
6674 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
6675 OCD, Category, ObjCTypes, false);
6676 auto classPropertyList =
6677 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
6678 Category, ObjCTypes, true);
6679 values.add(protocolList);
6680 values.add(propertyList);
6681 values.add(classPropertyList);
6682 isEmptyCategory &= protocolList->isNullValue() &&
6683 propertyList->isNullValue() &&
6684 classPropertyList->isNullValue();
6686 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6687 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6688 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6691 if (isEmptyCategory) {
6692 // Empty category, don't emit any metadata.
6694 MethodDefinitions.clear();
6699 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6700 values.addInt(ObjCTypes.IntTy, Size);
6702 llvm::GlobalVariable *GCATV =
6703 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
6704 CGM.addCompilerUsedGlobal(GCATV);
6705 if (Interface->hasAttr<ObjCClassStubAttr>())
6706 DefinedStubCategories.push_back(GCATV);
6708 DefinedCategories.push_back(GCATV);
6710 // Determine if this category is also "non-lazy
".
6711 if (ImplementationIsNonLazy(OCD))
6712 DefinedNonLazyCategories.push_back(GCATV);
6713 // method definition entries must be clear for next implementation.
6714 MethodDefinitions.clear();
6726void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
6727 const ObjCMethodDecl *MD,
6729 auto method = builder.beginStruct(ObjCTypes.MethodTy);
6730 method.add(GetMethodVarName(MD->getSelector()));
6731 method.add(GetMethodVarType(MD));
6734 // Protocol methods have no implementation. So, this entry is always NULL.
6735 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
6737 llvm::Function *fn = GetMethodDefinition(MD);
6738 assert(fn && "no definition
for method?
");
6742 method.finishAndAddTo(builder);
6754CGObjCNonFragileABIMac::emitMethodList(Twine name, MethodListType kind,
6755 ArrayRef<const ObjCMethodDecl *> methods) {
6756 // Return null for empty list.
6757 if (methods.empty())
6758 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6763 case MethodListType::CategoryInstanceMethods:
6764 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
6765 forProtocol = false;
6767 case MethodListType::CategoryClassMethods:
6768 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
6769 forProtocol = false;
6771 case MethodListType::InstanceMethods:
6772 prefix = "_OBJC_$_INSTANCE_METHODS_
";
6773 forProtocol = false;
6775 case MethodListType::ClassMethods:
6776 prefix = "_OBJC_$_CLASS_METHODS_
";
6777 forProtocol = false;
6780 case MethodListType::ProtocolInstanceMethods:
6781 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
6784 case MethodListType::ProtocolClassMethods:
6785 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
6788 case MethodListType::OptionalProtocolInstanceMethods:
6789 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
6792 case MethodListType::OptionalProtocolClassMethods:
6793 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
6798 ConstantInitBuilder builder(CGM);
6799 auto values = builder.beginStruct();
6801 // sizeof(struct _objc_method)
6802 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6803 values.addInt(ObjCTypes.IntTy, Size);
6805 values.addInt(ObjCTypes.IntTy, methods.size());
6806 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6807 for (auto MD : methods)
6808 emitMethodConstant(methodArray, MD, forProtocol);
6809 methodArray.finishAndAddTo(values);
6811 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
6812 CGM.addCompilerUsedGlobal(GV);
6818llvm::GlobalVariable *
6819CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6820 const ObjCIvarDecl *Ivar) {
6821 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6822 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
6823 Name += Container->getObjCRuntimeNameAsString();
6825 Name += Ivar->getName();
6826 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
6827 if (!IvarOffsetGV) {
6829 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy,
6830 false, llvm::GlobalValue::ExternalLinkage,
6831 nullptr, Name.str());
6832 if (CGM.getTriple().isOSBinFormatCOFF()) {
6833 bool IsPrivateOrPackage =
6834 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6835 Ivar->getAccessControl() == ObjCIvarDecl::Package;
6837 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
6839 if (ContainingID->hasAttr<DLLImportAttr>())
6841 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6842 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6844 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6847 return IvarOffsetGV;
6851CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6852 const ObjCIvarDecl *Ivar,
6853 unsigned long int Offset) {
6854 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6855 IvarOffsetGV->setInitializer(
6856 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6857 IvarOffsetGV->setAlignment(
6858 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
6860 if (!CGM.getTriple().isOSBinFormatCOFF()) {
6861 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
6862 // as well (i.e., in ObjCIvarOffsetVariable).
6863 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6864 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6865 ID->getVisibility() == HiddenVisibility)
6866 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6868 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6871 // If ID's layout is known, then make the global constant. This serves as a
6872 // useful assertion: we'll never use this variable to calculate ivar offsets,
6873 // so if the runtime tries to patch it then we should crash.
6874 if (isClassLayoutKnownStatically(ID))
6875 IvarOffsetGV->setConstant(true);
6877 if (CGM.getTriple().isOSBinFormatMachO())
6878 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
6879 return IvarOffsetGV;
6899llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6900 const ObjCImplementationDecl *ID) {
6902 ConstantInitBuilder builder(CGM);
6903 auto ivarList = builder.beginStruct();
6904 ivarList.addInt(ObjCTypes.IntTy,
6905 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6906 auto ivarCountSlot = ivarList.addPlaceholder();
6907 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6909 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6910 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
6912 // FIXME. Consolidate this with similar code in GenerateClass.
6914 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6915 IVD; IVD = IVD->getNextIvar()) {
6916 // Ignore unnamed bit-fields.
6917 if (!IVD->getDeclName())
6920 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6921 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6922 ComputeIvarBaseOffset(CGM, ID, IVD)));
6923 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6924 ivar.add(GetMethodVarType(IVD));
6925 llvm::Type *FieldTy =
6926 CGM.getTypes().ConvertTypeForMem(IVD->getType());
6927 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6928 unsigned Align = CGM.getContext().getPreferredTypeAlign(
6929 IVD->getType().getTypePtr()) >> 3;
6930 Align = llvm::Log2_32(Align);
6931 ivar.addInt(ObjCTypes.IntTy, Align);
6932 // NOTE. Size of a bitfield does not match gcc's, because of the
6933 // way bitfields are treated special in each. But I am told that
6934 // 'size' for bitfield ivars is ignored by the runtime so it does
6935 // not matter. If it matters, there is enough info to get the
6937 ivar.addInt(ObjCTypes.IntTy, Size);
6938 ivar.finishAndAddTo(ivars);
6940 // Return null for empty list.
6941 if (ivars.empty()) {
6944 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6947 auto ivarCount = ivars.size();
6948 ivars.finishAndAddTo(ivarList);
6949 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6951 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
6952 llvm::GlobalVariable *GV = finishAndCreateGlobal(
6953 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
6954 CGM.addCompilerUsedGlobal(GV);
6958llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6959 const ObjCProtocolDecl *PD) {
6960 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6962 assert(!PD->isNonRuntimeProtocol() &&
6963 "attempting to GetOrEmit a non-runtime protocol
");
6965 // We use the initializer as a marker of whether this is a forward
6966 // reference or not. At module finalization we add the empty
6967 // contents for protocols which were referenced but never defined.
6968 llvm::SmallString<64> Protocol;
6969 llvm::raw_svector_ostream(Protocol) << "_OBJC_PROTOCOL_$_
"
6970 << PD->getObjCRuntimeNameAsString();
6972 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6973 false, llvm::GlobalValue::ExternalLinkage,
6975 if (!CGM.getTriple().isOSBinFormatMachO())
6976 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7002llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
7003 const ObjCProtocolDecl *PD) {
7004 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7006 // Early exit if a defining object has already been generated.
7007 if (Entry && Entry->hasInitializer())
7010 // Use the protocol definition, if there is one.
7011 assert(PD->hasDefinition() &&
7012 "emitting protocol metadata without definition
");
7013 PD = PD->getDefinition();
7015 auto methodLists = ProtocolMethodLists::get(PD);
7017 ConstantInitBuilder builder(CGM);
7018 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7021 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7022 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7023 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
"
7024 + PD->getObjCRuntimeNameAsString(),
7025 PD->protocol_begin(),
7026 PD->protocol_end()));
7027 values.add(methodLists.emitMethodList(this, PD,
7028 ProtocolMethodLists::RequiredInstanceMethods));
7029 values.add(methodLists.emitMethodList(this, PD,
7030 ProtocolMethodLists::RequiredClassMethods));
7031 values.add(methodLists.emitMethodList(this, PD,
7032 ProtocolMethodLists::OptionalInstanceMethods));
7033 values.add(methodLists.emitMethodList(this, PD,
7034 ProtocolMethodLists::OptionalClassMethods));
7035 values.add(EmitPropertyList(
7036 "_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7037 nullptr, PD, ObjCTypes, false));
7039 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7040 values.addInt(ObjCTypes.IntTy, Size);
7041 values.addInt(ObjCTypes.IntTy, 0);
7042 values.add(EmitProtocolMethodTypes("_OBJC_$_PROTOCOL_METHOD_TYPES_
"
7043 + PD->getObjCRuntimeNameAsString(),
7044 methodLists.emitExtendedTypesArray(this),
7047 // const char *demangledName;
7048 values.addNullPointer(ObjCTypes.Int8PtrTy);
7050 values.add(EmitPropertyList(
7051 "_OBJC_$_CLASS_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7052 nullptr, PD, ObjCTypes, true));
7055 // Already created, fix the linkage and update the initializer.
7056 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7057 values.finishAndSetAsInitializer(Entry);
7059 llvm::SmallString<64> symbolName;
7060 llvm::raw_svector_ostream(symbolName)
7061 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7063 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
7065 llvm::GlobalValue::WeakAnyLinkage);
7066 if (!CGM.getTriple().isOSBinFormatMachO())
7067 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
7069 Protocols[PD->getIdentifier()] = Entry;
7071 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7072 CGM.addUsedGlobal(Entry);
7074 // Use this protocol meta-data to build protocol list table in section
7075 // __DATA, __objc_protolist
7076 llvm::SmallString<64> ProtocolRef;
7077 llvm::raw_svector_ostream(ProtocolRef) << "_OBJC_LABEL_PROTOCOL_$_
"
7078 << PD->getObjCRuntimeNameAsString();
7080 llvm::GlobalVariable *PTGV =
7081 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
7082 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
7084 if (!CGM.getTriple().isOSBinFormatMachO())
7085 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
7087 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
7088 PTGV->setSection(GetSectionName("__objc_protolist
",
7089 "coalesced,no_dead_strip
"));
7090 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7091 CGM.addUsedGlobal(PTGV);
7104CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
7105 ObjCProtocolDecl::protocol_iterator begin,
7106 ObjCProtocolDecl::protocol_iterator end) {
7107 // Just return null for empty protocol lists
7108 auto Protocols = GetRuntimeProtocolList(begin, end);
7109 if (Protocols.empty())
7110 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7112 SmallVector<llvm::Constant *, 16> ProtocolRefs;
7113 ProtocolRefs.reserve(Protocols.size());
7115 for (const auto *PD : Protocols)
7116 ProtocolRefs.push_back(GetProtocolRef(PD));
7118 // If all of the protocols in the protocol list are objc_non_runtime_protocol
7120 if (ProtocolRefs.size() == 0)
7121 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7123 // FIXME: We shouldn't need to do this lookup here, should we?
7124 SmallString<256> TmpName;
7125 Name.toVector(TmpName);
7126 llvm::GlobalVariable *GV =
7127 CGM.getModule().getGlobalVariable(TmpName.str(), true);
7131 ConstantInitBuilder builder(CGM);
7132 auto values = builder.beginStruct();
7133 auto countSlot = values.addPlaceholder();
7135 // A null-terminated array of protocols.
7136 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
7137 for (auto const &proto : ProtocolRefs)
7139 auto count = array.size();
7140 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
7142 array.finishAndAddTo(values);
7143 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
7145 GV = finishAndCreateGlobal(values, Name, CGM);
7146 CGM.addCompilerUsedGlobal(GV);
7156LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7157 CodeGen::CodeGenFunction &CGF,
7159 llvm::Value *BaseValue,
7160 const ObjCIvarDecl *Ivar,
7161 unsigned CVRQualifiers) {
7162 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
7163 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
7164 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
7169CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
7170 const ObjCInterfaceDecl *Interface,
7171 const ObjCIvarDecl *Ivar) {
7172 llvm::Value *IvarOffsetValue;
7173 if (isClassLayoutKnownStatically(Interface)) {
7174 IvarOffsetValue = llvm::ConstantInt::get(
7175 ObjCTypes.IvarOffsetVarTy,
7176 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
7178 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
7180 CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
7181 CGF.getSizeAlign(), "ivar
");
7182 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7183 cast<llvm::LoadInst>(IvarOffsetValue)
7184 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
7185 llvm::MDNode::get(VMContext, {}));
7188 // This could be 32bit int or 64bit integer depending on the architecture.
7189 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
7190 // as this is what caller always expects.
7191 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7192 IvarOffsetValue = CGF.Builder.CreateIntCast(
7193 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
7194 return IvarOffsetValue;
7197static void appendSelectorForMessageRefTable(std::string &buffer,
7198 Selector selector) {
7199 if (selector.isUnarySelector()) {
7200 buffer += selector.getNameForSlot(0);
7204 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
7205 buffer += selector.getNameForSlot(i);
7221CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
7222 ReturnValueSlot returnSlot,
7223 QualType resultType,
7228 const CallArgList &formalArgs,
7229 const ObjCMethodDecl *method) {
7230 // Compute the actual arguments.
7233 // First argument: the receiver / super-call structure.
7235 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
7236 args.add(RValue::get(arg0), arg0Type);
7238 // Second argument: a pointer to the message ref structure. Leave
7239 // the actual argument value blank for now.
7240 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
7242 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7244 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7246 NullReturnState nullReturn;
7248 // Find the function to call and the mangled name for the message
7249 // ref structure. Using a different mangled name wouldn't actually
7250 // be a problem; it would just be a waste.
7252 // The runtime currently never uses vtable dispatch for anything
7253 // except normal, non-super message-sends.
7254 // FIXME: don't use this for that.
7255 llvm::FunctionCallee fn = nullptr;
7256 std::string messageRefName("_
");
7257 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
7259 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7260 messageRefName += "objc_msgSendSuper2_stret_fixup
";
7262 nullReturn.init(CGF, arg0);
7263 fn = ObjCTypes.getMessageSendStretFixupFn();
7264 messageRefName += "objc_msgSend_stret_fixup
";
7266 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
7267 fn = ObjCTypes.getMessageSendFpretFixupFn();
7268 messageRefName += "objc_msgSend_fpret_fixup
";
7271 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7272 messageRefName += "objc_msgSendSuper2_fixup
";
7274 fn = ObjCTypes.getMessageSendFixupFn();
7275 messageRefName += "objc_msgSend_fixup
";
7278 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
7279 messageRefName += '_';
7281 // Append the selector name, except use underscores anywhere we
7282 // would have used colons.
7283 appendSelectorForMessageRefTable(messageRefName, selector);
7285 llvm::GlobalVariable *messageRef
7286 = CGM.getModule().getGlobalVariable(messageRefName);
7288 // Build the message ref structure.
7289 ConstantInitBuilder builder(CGM);
7290 auto values = builder.beginStruct();
7291 values.add(cast<llvm::Constant>(fn.getCallee()));
7292 values.add(GetMethodVarName(selector));
7293 messageRef = values.finishAndCreateGlobal(messageRefName,
7294 CharUnits::fromQuantity(16),
7296 llvm::GlobalValue::WeakAnyLinkage);
7297 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
7298 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
7301 bool requiresnullCheck = false;
7302 if (CGM.getLangOpts().ObjCAutoRefCount && method)
7303 for (const auto *ParamDecl : method->parameters()) {
7304 if (ParamDecl->isDestroyedInCallee()) {
7305 if (!nullReturn.NullBB)
7306 nullReturn.init(CGF, arg0);
7307 requiresnullCheck = true;
7313 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
7314 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
7316 // Update the message ref argument.
7317 args[1].setRValue(RValue::get(mref, CGF));
7319 // Load the function to call from the message ref table.
7320 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
7321 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
7323 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
7324 CGCallee callee(CGCalleeInfo(), calleePtr);
7326 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
7327 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7328 requiresnullCheck ? method : nullptr);
7333CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
7334 ReturnValueSlot Return,
7335 QualType ResultType,
7337 llvm::Value *Receiver,
7338 const CallArgList &CallArgs,
7339 const ObjCInterfaceDecl *Class,
7340 const ObjCMethodDecl *Method) {
7341 return isVTableDispatchedSelector(Sel)
7342 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7343 Receiver, CGF.getContext().getObjCIdType(),
7344 false, CallArgs, Method)
7345 : EmitMessageSend(CGF, Return, ResultType, Sel,
7346 Receiver, CGF.getContext().getObjCIdType(),
7347 false, CallArgs, Method, Class, ObjCTypes);
7351CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
7353 ForDefinition_t isForDefinition) {
7355 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7356 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
7358 ID->isWeakImported(),
7360 && CGM.getTriple().isOSBinFormatCOFF()
7361 && ID->hasAttr<DLLImportAttr>());
7365CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7366 ForDefinition_t IsForDefinition,
7367 bool Weak, bool DLLImport) {
7368 llvm::GlobalValue::LinkageTypes L =
7369 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7370 : llvm::GlobalValue::ExternalLinkage;
7372 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
7373 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
7374 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
7378 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7381 GV->replaceAllUsesWith(NewGV);
7382 GV->eraseFromParent();
7385 CGM.getModule().insertGlobalVariable(GV);
7388 assert(GV->getLinkage() == L);
7393CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
7394 llvm::Constant *ClassGV = GetClassGlobal(ID, /*metaclass*/ false,
7397 if (!ID->hasAttr<ObjCClassStubAttr>())
7400 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
7402 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
7403 // must set the least significant bit set to 1.
7404 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
7405 return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, ClassGV, Idx);
7409CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
7410 const ObjCInterfaceDecl *ID,
7411 llvm::GlobalVariable *Entry) {
7412 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
7413 // Classrefs pointing at Objective-C stub classes must be loaded by calling
7414 // a special runtime function.
7415 return CGF.EmitRuntimeCall(
7416 ObjCTypes.getLoadClassrefFn(), Entry, "load_classref_result
");
7419 CharUnits Align = CGF.getPointerAlign();
7420 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
7424CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
7426 const ObjCInterfaceDecl *ID) {
7427 llvm::GlobalVariable *&Entry = ClassReferences[II];
7430 llvm::Constant *ClassGV;
7432 ClassGV = GetClassGlobalForClassRef(ID);
7434 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
7436 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7437 "classref was emitted with the wrong
type?
");
7440 std::string SectionName =
7441 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
7442 Entry = new llvm::GlobalVariable(
7443 CGM.getModule(), ClassGV->getType(), false,
7444 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
7445 "OBJC_CLASSLIST_REFERENCES_$_
");
7446 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7447 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
7448 Entry->setSection(SectionName);
7450 CGM.addCompilerUsedGlobal(Entry);
7453 return EmitLoadOfClassRef(CGF, ID, Entry);
7456llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
7457 const ObjCInterfaceDecl *ID) {
7458 // If the class has the objc_runtime_visible attribute, we need to
7459 // use the Objective-C runtime to get the class.
7460 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
7461 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7463 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
7466llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7467 CodeGenFunction &CGF) {
7468 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
7469 return EmitClassRefFromId(CGF, II, nullptr);
7473CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
7474 const ObjCInterfaceDecl *ID) {
7475 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
7478 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7479 std::string SectionName =
7480 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
7481 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
7482 llvm::GlobalValue::PrivateLinkage, ClassGV,
7483 "OBJC_CLASSLIST_SUP_REFS_$_
");
7484 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7485 Entry->setSection(SectionName);
7486 CGM.addCompilerUsedGlobal(Entry);
7489 return EmitLoadOfClassRef(CGF, ID, Entry);
7495llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
7496 const ObjCInterfaceDecl *ID,
7498 CharUnits Align = CGF.getPointerAlign();
7499 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
7501 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
7502 std::string SectionName =
7503 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
7504 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7505 false, llvm::GlobalValue::PrivateLinkage,
7506 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
7507 Entry->setAlignment(Align.getAsAlign());
7508 Entry->setSection(SectionName);
7509 CGM.addCompilerUsedGlobal(Entry);
7512 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
7517llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
7518 const ObjCInterfaceDecl *ID) {
7519 if (ID->isWeakImported()) {
7520 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7522 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7523 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7526 return EmitClassRef(CGF, ID);
7533CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
7534 ReturnValueSlot Return,
7535 QualType ResultType,
7537 const ObjCInterfaceDecl *Class,
7538 bool isCategoryImpl,
7539 llvm::Value *Receiver,
7540 bool IsClassMessage,
7541 const CodeGen::CallArgList &CallArgs,
7542 const ObjCMethodDecl *Method) {
7544 // Create and init a super structure; this is a (receiver, class)
7545 // pair we will pass to objc_msgSendSuper.
7546 RawAddress ObjCSuper = CGF.CreateTempAlloca(
7547 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
7549 llvm::Value *ReceiverAsObject =
7550 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
7551 CGF.Builder.CreateStore(ReceiverAsObject,
7552 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
7554 // If this is a class message the metaclass is passed as the target.
7555 llvm::Value *Target;
7557 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7559 Target = EmitSuperClassRef(CGF, Class);
7561 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7563 llvm::Type *ClassTy =
7564 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
7565 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
7566 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
7568 return (isVTableDispatchedSelector(Sel))
7569 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7570 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7571 true, CallArgs, Method)
7572 : EmitMessageSend(CGF, Return, ResultType, Sel,
7573 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7574 true, CallArgs, Method, Class, ObjCTypes);
7577llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7579 Address Addr = EmitSelectorAddr(Sel);
7581 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr);
7582 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
7583 llvm::MDNode::get(VMContext, {}));
7587ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
7588 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7589 CharUnits Align = CGM.getPointerAlign();
7591 std::string SectionName =
7592 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
7593 Entry = new llvm::GlobalVariable(
7594 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
7595 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
7596 "OBJC_SELECTOR_REFERENCES_
");
7597 Entry->setExternallyInitialized(true);
7598 Entry->setSection(SectionName);
7599 Entry->setAlignment(Align.getAsAlign());
7600 CGM.addCompilerUsedGlobal(Entry);
7603 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
7609void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7612 llvm::Value *ivarOffset) {
7613 llvm::Type * SrcTy = src->getType();
7614 if (!isa<llvm::PointerType>(SrcTy)) {
7615 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7616 assert(Size <= 8 && "does
not support size > 8
");
7617 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7618 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7619 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7621 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7622 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7623 ObjCTypes.PtrObjectPtrTy);
7624 llvm::Value *args[] = {src, dstVal, ivarOffset};
7625 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7631void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7632 CodeGen::CodeGenFunction &CGF,
7633 llvm::Value *src, Address dst) {
7634 llvm::Type * SrcTy = src->getType();
7635 if (!isa<llvm::PointerType>(SrcTy)) {
7636 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7637 assert(Size <= 8 && "does
not support size > 8
");
7638 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7639 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7640 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7642 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7643 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7644 ObjCTypes.PtrObjectPtrTy);
7645 llvm::Value *args[] = {src, dstVal};
7646 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7647 args, "weakassign
");
7650void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7651 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
7652 llvm::Value *Size) {
7653 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
7654 SrcPtr.emitRawPointer(CGF), Size};
7655 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7661llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7662 CodeGen::CodeGenFunction &CGF,
7663 Address AddrWeakObj) {
7664 llvm::Type *DestTy = AddrWeakObj.getElementType();
7665 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
7666 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
7667 llvm::Value *read_weak =
7668 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7669 AddrWeakObjVal, "weakread
");
7670 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7677void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7678 llvm::Value *src, Address dst) {
7679 llvm::Type * SrcTy = src->getType();
7680 if (!isa<llvm::PointerType>(SrcTy)) {
7681 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7682 assert(Size <= 8 && "does
not support size > 8
");
7683 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7684 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7685 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7687 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7688 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7689 ObjCTypes.PtrObjectPtrTy);
7690 llvm::Value *args[] = {src, dstVal};
7691 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7692 args, "weakassign
");
7698void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7699 llvm::Value *src, Address dst,
7701 llvm::Type * SrcTy = src->getType();
7702 if (!isa<llvm::PointerType>(SrcTy)) {
7703 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7704 assert(Size <= 8 && "does
not support size > 8
");
7705 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7706 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7707 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7709 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7710 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7711 ObjCTypes.PtrObjectPtrTy);
7712 llvm::Value *args[] = {src, dstVal};
7714 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7715 args, "globalassign
");
7717 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7718 args, "threadlocalassign
");
7722CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7723 const ObjCAtSynchronizedStmt &S) {
7724 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
7725 ObjCTypes.getSyncExitFn());
7729CGObjCNonFragileABIMac::GetEHType(QualType T) {
7730 // There's a particular fixed type info for 'id'.
7731 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7732 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
7735 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7736 llvm::GlobalValue::ExternalLinkage, nullptr,
7738 if (CGM.getTriple().isOSBinFormatCOFF())
7739 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
7744 // All other types should be Objective-C interface pointer types.
7745 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7748 const ObjCInterfaceType *IT = PT->getInterfaceType();
7749 assert(IT && "Invalid
@catch type.
");
7751 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
7754void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7755 const ObjCAtTryStmt &S) {
7756 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
7757 ObjCTypes.getObjCEndCatchFn(),
7758 ObjCTypes.getExceptionRethrowFn());
7762void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7763 const ObjCAtThrowStmt &S,
7764 bool ClearInsertionPoint) {
7765 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7766 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7767 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7768 llvm::CallBase *Call =
7769 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
7770 Call->setDoesNotReturn();
7772 llvm::CallBase *Call =
7773 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
7774 Call->setDoesNotReturn();
7777 CGF.Builder.CreateUnreachable();
7778 if (ClearInsertionPoint)
7779 CGF.Builder.ClearInsertionPoint();
7783CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7784 ForDefinition_t IsForDefinition) {
7785 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7786 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7788 // If we don't need a definition, return the entry if found or check
7789 // if we use an external reference.
7790 if (!IsForDefinition) {
7794 // If this type (or a super class) has the __objc_exception__
7795 // attribute, emit an external reference.
7796 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7797 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
7798 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7799 false, llvm::GlobalValue::ExternalLinkage,
7800 nullptr, EHTypeName);
7801 CGM.setGVProperties(Entry, ID);
7806 // Otherwise we need to either make a new entry or fill in the initializer.
7807 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
7809 std::string VTableName = "objc_ehtype_vtable
";
7810 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7813 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7814 llvm::GlobalValue::ExternalLinkage, nullptr,
7816 if (CGM.getTriple().isOSBinFormatCOFF())
7817 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7820 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7821 ConstantInitBuilder builder(CGM);
7822 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
7824 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(),
7825 VTableGV, VTableIdx));
7826 values.add(GetClassName(ClassName));
7827 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
7829 llvm::GlobalValue::LinkageTypes L = IsForDefinition
7830 ? llvm::GlobalValue::ExternalLinkage
7831 : llvm::GlobalValue::WeakAnyLinkage;
7833 values.finishAndSetAsInitializer(Entry);
7834 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
7836 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
7837 CGM.getPointerAlign(),
7840 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7841 CGM.setGVProperties(Entry, ID);
7843 assert(Entry->getLinkage() == L);
7845 if (!CGM.getTriple().isOSBinFormatCOFF())
7846 if (ID->getVisibility() == HiddenVisibility)
7847 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7849 if (IsForDefinition)
7850 if (CGM.getTriple().isOSBinFormatMachO())
7851 Entry->setSection("__DATA,__objc_const
");
7858CodeGen::CGObjCRuntime *
7859CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7860 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7861 case ObjCRuntime::FragileMacOSX:
7862 return new CGObjCMac(CGM);
7864 case ObjCRuntime::MacOSX:
7865 case ObjCRuntime::iOS:
7866 case ObjCRuntime::WatchOS:
7867 return new CGObjCNonFragileABIMac(CGM);
7869 case ObjCRuntime::GNUstep:
7870 case ObjCRuntime::GCC:
7871 case ObjCRuntime::ObjFW:
7872 llvm_unreachable("these runtimes are
not Mac runtimes
");
7874 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)
@ kCFTaggedObjectID_Integer
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
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 ASTContext &Ctx) 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