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