31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Intrinsics.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Module.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/ConvertUTF.h"
49class LazyRuntimeFunction {
50 CodeGenModule *CGM =
nullptr;
51 llvm::FunctionType *FTy =
nullptr;
52 const char *FunctionName =
nullptr;
53 llvm::FunctionCallee Function =
nullptr;
56 LazyRuntimeFunction() =
default;
60 template <
typename... Tys>
61 void init(CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
67 SmallVector<llvm::Type *, 8> ArgTys({Types...});
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, {},
false);
75 llvm::FunctionType *
getType() {
return FTy; }
79 operator llvm::FunctionCallee() {
83 Function = CGM->CreateRuntimeFunction(FTy, FunctionName);
96 llvm::Module &TheModule;
99 llvm::StructType *ObjCSuperTy;
102 llvm::PointerType *PtrToObjCSuperTy;
106 llvm::PointerType *SelectorTy;
108 llvm::Type *SelectorElemTy;
111 llvm::IntegerType *Int8Ty;
114 llvm::PointerType *PtrToInt8Ty;
116 llvm::StructType *ProtocolTy;
118 llvm::PointerType *ProtocolPtrTy;
124 llvm::PointerType *IMPTy;
129 llvm::PointerType *IdTy;
131 llvm::Type *IdElemTy;
134 llvm::PointerType *PtrToIdTy;
139 llvm::IntegerType *IntTy;
143 llvm::PointerType *PtrTy;
147 llvm::IntegerType *LongTy;
149 llvm::IntegerType *SizeTy;
151 llvm::IntegerType *IntPtrTy;
153 llvm::IntegerType *PtrDiffTy;
156 llvm::PointerType *PtrToIntTy;
160 llvm::IntegerType *Int32Ty;
162 llvm::IntegerType *Int64Ty;
164 llvm::StructType *PropertyMetadataTy;
168 unsigned msgSendMDKind;
171 bool usesSEHExceptions;
173 bool usesCxxExceptions;
178 return (R.
getKind() == kind) &&
179 (R.
getVersion() >= VersionTuple(major, minor));
182 std::string ManglePublicSymbol(StringRef Name) {
183 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
186 std::string SymbolForProtocol(Twine Name) {
187 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
190 std::string SymbolForProtocolRef(StringRef Name) {
191 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
198 llvm::Constant *MakeConstantString(StringRef Str, StringRef Name =
"") {
199 ConstantAddress Array =
201 return Array.getPointer();
208 llvm::Constant *ExportUniqueString(
const std::string &Str,
209 const std::string &prefix,
211 std::string
name = prefix + Str;
212 auto *ConstStr = TheModule.getGlobalVariable(name);
214 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
215 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
216 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
217 GV->setComdat(TheModule.getOrInsertComdat(name));
219 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
226 llvm::Constant *MakePropertyEncodingString(
const ObjCPropertyDecl *PD,
227 const Decl *Container) {
230 std::string NameAndAttributes;
231 std::string TypeStr =
233 NameAndAttributes +=
'\0';
234 NameAndAttributes += TypeStr.length() + 3;
235 NameAndAttributes += TypeStr;
236 NameAndAttributes +=
'\0';
238 return MakeConstantString(NameAndAttributes);
244 void PushPropertyAttributes(ConstantStructBuilder &Fields,
245 const ObjCPropertyDecl *property,
bool isSynthesized=
true,
bool
247 int attrs =
property->getPropertyAttributes();
250 attrs &= ~ObjCPropertyAttribute::kind_copy;
251 attrs &= ~ObjCPropertyAttribute::kind_retain;
252 attrs &= ~ObjCPropertyAttribute::kind_weak;
253 attrs &= ~ObjCPropertyAttribute::kind_strong;
256 Fields.
addInt(Int8Ty, attrs & 0xff);
262 attrs |= isSynthesized ? (1<<0) : 0;
263 attrs |= isDynamic ? (1<<1) : 0;
266 Fields.
addInt(Int8Ty, attrs & 0xff);
272 virtual llvm::Constant *GenerateCategoryProtocolList(
const
273 ObjCCategoryDecl *OCD);
274 virtual ConstantArrayBuilder PushPropertyListHeader(ConstantStructBuilder &Fields,
277 Fields.
addInt(IntTy, count);
280 const llvm::DataLayout &DL = TheModule.getDataLayout();
281 Fields.
addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
289 virtual void PushProperty(ConstantArrayBuilder &PropertiesArray,
290 const ObjCPropertyDecl *property,
292 bool isSynthesized=
true,
bool
294 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
296 Fields.
add(MakePropertyEncodingString(property, OCD));
297 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
298 auto addPropertyMethod = [&](
const ObjCMethodDecl *accessor) {
301 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302 Fields.
add(MakeConstantString(accessor->getSelector().getAsString()));
303 Fields.
add(TypeEncoding);
317 llvm::Value *EnforceType(CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
318 if (
V->getType() == Ty)
320 return B.CreateBitCast(
V, Ty);
324 llvm::Constant *Zeros[2];
326 llvm::Constant *NULLPtr;
328 llvm::LLVMContext &VMContext;
336 llvm::GlobalAlias *ClassPtrAlias;
341 llvm::GlobalAlias *MetaClassPtrAlias;
343 std::vector<llvm::Constant*> Classes;
345 std::vector<llvm::Constant*> Categories;
348 std::vector<llvm::Constant*> ConstantStrings;
352 llvm::StringMap<llvm::Constant*> ObjCStrings;
354 llvm::StringMap<llvm::Constant*> ExistingProtocols;
360 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
364 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
368 SelectorMap SelectorTable;
372 Selector RetainSel, ReleaseSel, AutoreleaseSel;
376 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377 WeakAssignFn, GlobalAssignFn;
379 typedef std::pair<std::string, std::string> ClassAliasPair;
381 std::vector<ClassAliasPair> ClassAliases;
385 LazyRuntimeFunction ExceptionThrowFn;
388 LazyRuntimeFunction ExceptionReThrowFn;
391 LazyRuntimeFunction EnterCatchFn;
394 LazyRuntimeFunction ExitCatchFn;
396 LazyRuntimeFunction SyncEnterFn;
398 LazyRuntimeFunction SyncExitFn;
403 LazyRuntimeFunction EnumerationMutationFn;
406 LazyRuntimeFunction GetPropertyFn;
409 LazyRuntimeFunction SetPropertyFn;
411 LazyRuntimeFunction GetStructPropertyFn;
413 LazyRuntimeFunction SetStructPropertyFn;
425 const int ProtocolVersion;
428 const int ClassABIVersion;
433 virtual llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
434 ArrayRef<llvm::Constant *> IvarTypes,
435 ArrayRef<llvm::Constant *> IvarOffsets,
436 ArrayRef<llvm::Constant *> IvarAlign,
437 ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership);
444 llvm::Constant *GenerateMethodList(StringRef ClassName,
445 StringRef CategoryName,
446 ArrayRef<const ObjCMethodDecl*> Methods,
447 bool isClassMethodList);
452 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
456 llvm::Constant *GeneratePropertyList(
const Decl *Container,
457 const ObjCContainerDecl *OCD,
458 bool isClassProperty=
false,
459 bool protocolOptionalProperties=
false);
463 llvm::Constant *GenerateProtocolList(ArrayRef<std::string> Protocols);
469 void GenerateProtocolHolderCategory();
472 llvm::Constant *GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
477 llvm::Constant *Version,
478 llvm::Constant *InstanceSize,
479 llvm::Constant *IVars,
480 llvm::Constant *Methods,
481 llvm::Constant *Protocols,
482 llvm::Constant *IvarOffsets,
483 llvm::Constant *Properties,
484 llvm::Constant *StrongIvarBitmap,
485 llvm::Constant *WeakIvarBitmap,
490 virtual llvm::Constant *GenerateProtocolMethodList(
491 ArrayRef<const ObjCMethodDecl*> Methods);
494 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
496 SmallVector<const ObjCMethodDecl*, 16> RequiredMethods;
497 SmallVector<const ObjCMethodDecl*, 16> OptionalMethods;
498 for (
const auto *I : Methods)
500 OptionalMethods.push_back(I);
502 RequiredMethods.push_back(I);
503 Required = GenerateProtocolMethodList(RequiredMethods);
504 Optional = GenerateProtocolMethodList(OptionalMethods);
509 virtual llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel,
510 const std::string &TypeEncoding);
515 virtual std::string GetIVarOffsetVariableName(
const ObjCInterfaceDecl *ID,
516 const ObjCIvarDecl *Ivar) {
517 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
522 llvm::GlobalVariable *ObjCIvarOffsetVariable(
const ObjCInterfaceDecl *ID,
523 const ObjCIvarDecl *Ivar);
526 void EmitClassRef(
const std::string &className);
529 virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF,
530 const std::string &Name,
bool isWeak);
535 virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
536 llvm::Value *&Receiver,
539 MessageSendInfo &MSI) = 0;
544 virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
547 MessageSendInfo &MSI) = 0;
560 llvm::Constant *MakeBitField(ArrayRef<bool> bits);
563 CGObjCGNU(CodeGenModule &cgm,
unsigned runtimeABIVersion,
564 unsigned protocolClassVersion,
unsigned classABI=1);
566 ConstantAddress GenerateConstantString(
const StringLiteral *)
override;
569 GenerateMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return,
570 QualType ResultType, Selector Sel,
571 llvm::Value *Receiver,
const CallArgList &CallArgs,
572 const ObjCInterfaceDecl *
Class,
573 const ObjCMethodDecl *
Method)
override;
575 GenerateMessageSendSuper(CodeGenFunction &CGF, ReturnValueSlot Return,
576 QualType ResultType, Selector Sel,
577 const ObjCInterfaceDecl *
Class,
578 bool isCategoryImpl, llvm::Value *Receiver,
579 bool IsClassMessage,
const CallArgList &CallArgs,
580 const ObjCMethodDecl *
Method)
override;
581 llvm::Value *GetClass(CodeGenFunction &CGF,
582 const ObjCInterfaceDecl *OID)
override;
583 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override;
584 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override;
585 llvm::Value *GetSelector(CodeGenFunction &CGF,
586 const ObjCMethodDecl *
Method)
override;
587 virtual llvm::Constant *GetConstantSelector(Selector Sel,
588 const std::string &TypeEncoding) {
589 llvm_unreachable(
"Runtime unable to generate constant selector");
591 llvm::Constant *GetConstantSelector(
const ObjCMethodDecl *M) {
595 llvm::Constant *GetEHType(QualType
T)
override;
597 llvm::Function *GenerateMethod(
const ObjCMethodDecl *OMD,
598 const ObjCContainerDecl *CD)
override;
601 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602 DirectMethodDefinitions;
603 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
604 const ObjCMethodDecl *OMD,
605 const ObjCContainerDecl *CD)
override;
606 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
607 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
608 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override;
609 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
610 const ObjCProtocolDecl *PD)
override;
611 void GenerateProtocol(
const ObjCProtocolDecl *PD)
override;
613 virtual llvm::Constant *GenerateProtocolRef(
const ObjCProtocolDecl *PD);
615 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override {
616 return GenerateProtocolRef(PD);
619 llvm::Function *ModuleInitFunction()
override;
620 llvm::FunctionCallee GetPropertyGetFunction()
override;
621 llvm::FunctionCallee GetPropertySetFunction()
override;
622 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
624 llvm::FunctionCallee GetSetStructFunction()
override;
625 llvm::FunctionCallee GetGetStructFunction()
override;
626 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
627 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
628 llvm::FunctionCallee EnumerationMutationFunction()
override;
630 void EmitTryStmt(CodeGenFunction &CGF,
631 const ObjCAtTryStmt &S)
override;
632 void EmitSynchronizedStmt(CodeGenFunction &CGF,
633 const ObjCAtSynchronizedStmt &S)
override;
634 void EmitThrowStmt(CodeGenFunction &CGF,
635 const ObjCAtThrowStmt &S,
636 bool ClearInsertionPoint=
true)
override;
637 llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF,
638 Address AddrWeakObj)
override;
639 void EmitObjCWeakAssign(CodeGenFunction &CGF,
640 llvm::Value *src, Address dst)
override;
641 void EmitObjCGlobalAssign(CodeGenFunction &CGF,
642 llvm::Value *src, Address dest,
643 bool threadlocal=
false)
override;
644 void EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src,
645 Address dest, llvm::Value *ivarOffset)
override;
646 void EmitObjCStrongCastAssign(CodeGenFunction &CGF,
647 llvm::Value *src, Address dest)
override;
648 void EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address DestPtr,
650 llvm::Value *Size)
override;
651 LValue EmitObjCValueForIvar(CodeGenFunction &CGF, QualType ObjectTy,
652 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
653 unsigned CVRQualifiers)
override;
654 llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
656 const ObjCIvarDecl *Ivar)
override;
657 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
658 llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM,
659 const CGBlockInfo &blockInfo)
override {
662 llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM,
663 const CGBlockInfo &blockInfo)
override {
667 llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType
T)
override {
680class CGObjCGCC :
public CGObjCGNU {
683 LazyRuntimeFunction MsgLookupFn;
687 LazyRuntimeFunction MsgLookupSuperFn;
690 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
691 llvm::Value *cmd, llvm::MDNode *node,
692 MessageSendInfo &MSI)
override {
693 CGBuilderTy &Builder = CGF.
Builder;
694 llvm::Value *args[] = {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
702 llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
703 llvm::Value *cmd, MessageSendInfo &MSI)
override {
704 CGBuilderTy &Builder = CGF.
Builder;
705 llvm::Value *lookupArgs[] = {
706 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
712 CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
714 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
716 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
717 PtrToObjCSuperTy, SelectorTy);
722class CGObjCGNUstep :
public CGObjCGNU {
725 LazyRuntimeFunction SlotLookupFn;
730 LazyRuntimeFunction SlotLookupSuperFn;
732 LazyRuntimeFunction SetPropertyAtomic;
734 LazyRuntimeFunction SetPropertyAtomicCopy;
736 LazyRuntimeFunction SetPropertyNonAtomic;
738 LazyRuntimeFunction SetPropertyNonAtomicCopy;
741 LazyRuntimeFunction CxxAtomicObjectGetFn;
744 LazyRuntimeFunction CxxAtomicObjectSetFn;
749 llvm::Type *SlotStructTy;
752 llvm::Constant *GetEHType(QualType
T)
override;
755 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
756 llvm::Value *cmd, llvm::MDNode *node,
757 MessageSendInfo &MSI)
override {
758 CGBuilderTy &Builder = CGF.
Builder;
759 llvm::FunctionCallee LookupFn = SlotLookupFn;
762 RawAddress ReceiverPtr =
764 Builder.CreateStore(Receiver, ReceiverPtr);
771 self = llvm::ConstantPointerNull::get(IdTy);
775 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
776 LookupFn2->addParamAttr(
778 llvm::CaptureInfo::none()));
780 llvm::Value *args[] = {
781 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
782 EnforceType(Builder, cmd, SelectorTy),
783 EnforceType(Builder, self, IdTy)};
785 slot->setOnlyReadsMemory();
786 slot->setMetadata(msgSendMDKind, node);
789 llvm::Value *imp = Builder.CreateAlignedLoad(
790 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
795 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
799 llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
801 MessageSendInfo &MSI)
override {
802 CGBuilderTy &Builder = CGF.
Builder;
805 llvm::CallInst *slot =
807 slot->setOnlyReadsMemory();
809 return Builder.CreateAlignedLoad(
810 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
815 CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
816 CGObjCGNUstep(CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
818 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
819 const ObjCRuntime &R = CGM.
getLangOpts().ObjCRuntime;
821 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
824 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
827 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
828 PtrToObjCSuperTy, SelectorTy);
830 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
831 if (usesCxxExceptions) {
833 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
835 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
837 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
838 }
else if (usesSEHExceptions) {
840 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
843 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
845 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
847 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
849 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
851 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
853 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
855 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
857 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
858 SelectorTy, IdTy, PtrDiffTy);
859 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
860 IdTy, SelectorTy, IdTy, PtrDiffTy);
861 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
862 IdTy, SelectorTy, IdTy, PtrDiffTy);
863 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
864 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
867 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
871 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
875 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
880 return CxxAtomicObjectGetFn;
883 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
888 return CxxAtomicObjectSetFn;
891 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
892 bool copy)
override {
896 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
903 if (copy)
return SetPropertyAtomicCopy;
904 return SetPropertyAtomic;
907 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
914class CGObjCGNUstep2 :
public CGObjCGNUstep {
919 ClassReferenceSection,
922 ProtocolReferenceSection,
924 ConstantStringSection
929 ClassFlagMeta = (1 << 0),
932 ClassFlagInitialized = (1 << 8),
934 static const char *
const SectionsBaseNames[8];
935 static const char *
const PECOFFSectionsBaseNames[8];
936 template<SectionKind K>
937 std::string sectionName() {
938 if (CGM.
getTriple().isOSBinFormatCOFF()) {
939 std::string
name(PECOFFSectionsBaseNames[K]);
943 return SectionsBaseNames[K];
948 LazyRuntimeFunction MsgLookupSuperFn;
950 LazyRuntimeFunction SentInitializeFn;
954 bool EmittedProtocol =
false;
959 bool EmittedProtocolRef =
false;
963 bool EmittedClass =
false;
967 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
969 std::vector<EarlyInitPair> EarlyInitList;
971 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
973 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
975 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
978 std::string SymbolForClass(StringRef Name) {
979 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
981 void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName,
982 ArrayRef<llvm::Value*> Args) {
983 SmallVector<llvm::Type *,8> Types;
984 for (
auto *Arg : Args)
985 Types.push_back(Arg->getType());
986 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
989 B.CreateCall(Fn, Args);
992 ConstantAddress GenerateConstantString(
const StringLiteral *SL)
override {
998 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
999 if (old != ObjCStrings.end())
1000 return ConstantAddress(old->getValue(), IdElemTy, Align);
1007 (LiteralLength < 9) && !isNonASCII) {
1013 for (
unsigned i=0 ; i<LiteralLength ; i++)
1014 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1016 str |= LiteralLength << 3;
1019 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1020 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1021 ObjCStrings[Str] = ObjCStr;
1022 return ConstantAddress(ObjCStr, IdElemTy, Align);
1027 if (StringClass.empty()) StringClass =
"NSConstantString";
1029 std::string Sym = SymbolForClass(StringClass);
1031 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1034 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1035 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1036 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1051 ConstantInitBuilder Builder(CGM);
1052 auto Fields = Builder.beginStruct();
1053 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1063 unsigned NumU8CodeUnits = Str.size();
1067 SmallVector<llvm::UTF16, 128> ToBuf(NumU8CodeUnits + 1);
1068 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1069 llvm::UTF16 *ToPtr = &ToBuf[0];
1070 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1071 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1072 uint32_t StringLength = ToPtr - &ToBuf[0];
1076 Fields.
addInt(Int32Ty, 2);
1078 Fields.
addInt(Int32Ty, StringLength);
1080 Fields.
addInt(Int32Ty, StringLength * 2);
1082 Fields.
addInt(Int32Ty, 0);
1084 auto Arr = llvm::ArrayRef(&ToBuf[0], ToPtr + 1);
1085 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1086 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1087 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1088 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1092 Fields.
addInt(Int32Ty, 0);
1094 Fields.
addInt(Int32Ty, Str.size());
1096 Fields.
addInt(Int32Ty, Str.size());
1098 Fields.
addInt(Int32Ty, 0);
1100 Fields.
add(MakeConstantString(Str));
1102 std::string StringName;
1105 StringName =
".objc_str_";
1106 for (
unsigned char c : Str) {
1117 llvm::GlobalVariable *ObjCStrGV =
1119 isNamed ? StringRef(StringName) :
".objc_string",
1120 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1121 : llvm::GlobalValue::PrivateLinkage);
1122 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1124 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1125 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1127 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1128 std::pair<llvm::GlobalVariable*, int> v{ObjCStrGV, 0};
1129 EarlyInitList.emplace_back(Sym, v);
1131 ObjCStrings[Str] = ObjCStrGV;
1132 ConstantStrings.push_back(ObjCStrGV);
1133 return ConstantAddress(ObjCStrGV, IdElemTy, Align);
1136 void PushProperty(ConstantArrayBuilder &PropertiesArray,
1137 const ObjCPropertyDecl *property,
1139 bool isSynthesized=
true,
bool
1140 isDynamic=
true)
override {
1149 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1152 std::string TypeStr =
1154 Fields.
add(MakeConstantString(TypeStr));
1155 std::string typeStr;
1157 Fields.
add(MakeConstantString(typeStr));
1158 auto addPropertyMethod = [&](
const ObjCMethodDecl *accessor) {
1161 Fields.
add(GetConstantSelector(accessor->getSelector(), TypeStr));
1163 Fields.
add(NULLPtr);
1172 GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods)
override {
1178 llvm::StructType *ObjCMethodDescTy =
1180 { PtrToInt8Ty, PtrToInt8Ty });
1182 ConstantInitBuilder Builder(CGM);
1189 auto MethodList = Builder.beginStruct();
1191 MethodList.addInt(IntTy, Methods.size());
1193 const llvm::DataLayout &DL = TheModule.getDataLayout();
1194 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1197 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1198 for (
auto *M : Methods) {
1199 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1200 Method.add(CGObjCGNU::GetConstantSelector(M));
1202 Method.finishAndAddTo(MethodArray);
1204 MethodArray.finishAndAddTo(MethodList);
1205 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1208 llvm::Constant *GenerateCategoryProtocolList(
const ObjCCategoryDecl *OCD)
1211 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1212 ReferencedProtocols.end());
1213 SmallVector<llvm::Constant *, 16> Protocols;
1214 for (
const auto *PI : RuntimeProtocols)
1215 Protocols.push_back(GenerateProtocolRef(PI));
1216 return GenerateProtocolList(Protocols);
1219 llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
1220 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1222 CGBuilderTy &Builder = CGF.
Builder;
1223 llvm::Value *lookupArgs[] = {
1230 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1231 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1232 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1235 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1236 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1237 nullptr, SymbolName);
1243 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1244 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1245 nullptr, SymbolForClass(Name)));
1247 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1252 const ObjCInterfaceDecl *OID =
nullptr;
1254 if ((OID = dyn_cast<ObjCInterfaceDecl>(
Result)))
1260 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1262 if (OIDDef !=
nullptr)
1265 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1266 if (OID->
hasAttr<DLLImportAttr>())
1267 Storage = llvm::GlobalValue::DLLImportStorageClass;
1268 else if (OID->
hasAttr<DLLExportAttr>())
1269 Storage = llvm::GlobalValue::DLLExportStorageClass;
1274 assert(ClassSymbol->getName() == SymbolName);
1277 llvm::Value *GetClassNamed(CodeGenFunction &CGF,
1278 const std::string &Name,
1279 bool isWeak)
override {
1291 switch (Ownership) {
1308 llvm::Constant *GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
1309 ArrayRef<llvm::Constant *> IvarTypes,
1310 ArrayRef<llvm::Constant *> IvarOffsets,
1311 ArrayRef<llvm::Constant *> IvarAlign,
1312 ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership)
override {
1313 llvm_unreachable(
"Method should not be called!");
1316 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1317 std::string Name = SymbolForProtocol(ProtocolName);
1318 auto *GV = TheModule.getGlobalVariable(Name);
1321 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1322 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1329 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1331 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1332 const ObjCProtocolDecl *PD)
override {
1334 auto *&Ref = ExistingProtocolRefs[Name];
1336 auto *&
Protocol = ExistingProtocols[Name];
1338 Protocol = GenerateProtocolRef(PD);
1339 std::string RefName = SymbolForProtocolRef(Name);
1340 assert(!TheModule.getGlobalVariable(RefName));
1342 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1343 llvm::GlobalValue::LinkOnceODRLinkage,
1345 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1346 GV->setSection(sectionName<ProtocolReferenceSection>());
1350 EmittedProtocolRef =
true;
1355 llvm::Constant *GenerateProtocolList(ArrayRef<llvm::Constant*> Protocols) {
1356 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1358 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1360 ConstantInitBuilder builder(CGM);
1361 auto ProtocolBuilder = builder.beginStruct();
1362 ProtocolBuilder.addNullPointer(PtrTy);
1363 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1364 ProtocolBuilder.add(ProtocolArray);
1365 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1369 void GenerateProtocol(
const ObjCProtocolDecl *PD)
override {
1372 llvm::Constant *GenerateProtocolRef(
const ObjCProtocolDecl *PD)
override {
1374 auto *&
Protocol = ExistingProtocols[ProtocolName];
1378 EmittedProtocol =
true;
1380 auto SymName = SymbolForProtocol(ProtocolName);
1381 auto *OldGV = TheModule.getGlobalVariable(SymName);
1391 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1393 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1397 SmallVector<llvm::Constant*, 16> Protocols;
1398 auto RuntimeProtocols =
1400 for (
const auto *PI : RuntimeProtocols)
1401 Protocols.push_back(GenerateProtocolRef(PI));
1402 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1405 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1406 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1408 OptionalInstanceMethodList);
1409 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1410 OptionalClassMethodList);
1414 ConstantInitBuilder builder(CGM);
1415 auto ProtocolBuilder = builder.beginStruct();
1416 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1417 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1418 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1419 ProtocolBuilder.add(ProtocolList);
1420 ProtocolBuilder.add(InstanceMethodList);
1421 ProtocolBuilder.add(ClassMethodList);
1422 ProtocolBuilder.add(OptionalInstanceMethodList);
1423 ProtocolBuilder.add(OptionalClassMethodList);
1425 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1427 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1429 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1431 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1433 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1435 GV->setSection(sectionName<ProtocolSection>());
1436 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1438 OldGV->replaceAllUsesWith(GV);
1439 OldGV->removeFromParent();
1440 GV->setName(SymName);
1445 llvm::Value *GetTypedSelector(CodeGenFunction &CGF, Selector Sel,
1446 const std::string &TypeEncoding)
override {
1447 return GetConstantSelector(Sel, TypeEncoding);
1449 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1450 std::string MangledTypes = std::string(TypeEncoding);
1456 llvm::replace(MangledTypes,
'@',
'\1');
1459 llvm::replace(MangledTypes,
'=',
'\2');
1460 return MangledTypes;
1462 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1463 if (TypeEncoding.empty())
1465 std::string MangledTypes =
1466 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1467 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1468 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1470 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1472 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1473 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1474 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1475 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1480 llvm::Constant *GetConstantSelector(Selector Sel,
1481 const std::string &TypeEncoding)
override {
1482 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1483 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1484 MangledTypes).str();
1485 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1487 ConstantInitBuilder builder(CGM);
1488 auto SelBuilder = builder.beginStruct();
1489 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1491 SelBuilder.add(GetTypeString(TypeEncoding));
1492 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1494 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1495 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1496 GV->setSection(sectionName<SelectorSection>());
1499 llvm::StructType *emptyStruct =
nullptr;
1508 std::pair<llvm::Constant*,llvm::Constant*>
1509 GetSectionBounds(StringRef Section) {
1510 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1511 if (emptyStruct ==
nullptr) {
1512 emptyStruct = llvm::StructType::create(
1513 VMContext, {},
".objc_section_sentinel",
true);
1515 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1516 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1517 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1519 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1521 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1522 Sym->setSection((Section + SecSuffix).str());
1523 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1528 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1530 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1532 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1534 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1535 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1537 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1539 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1540 return { Start, Stop };
1542 CatchTypeInfo getCatchAllTypeInfo()
override {
1545 llvm::Function *ModuleInitFunction()
override {
1546 llvm::Function *LoadFunction = llvm::Function::Create(
1547 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1548 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1550 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1551 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1553 llvm::BasicBlock *EntryBB =
1554 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1555 CGBuilderTy B(CGM, VMContext);
1556 B.SetInsertPoint(EntryBB);
1557 ConstantInitBuilder builder(CGM);
1558 auto InitStructBuilder = builder.beginStruct();
1559 InitStructBuilder.addInt(Int64Ty, 0);
1560 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1561 for (
auto *
s : sectionVec) {
1562 auto bounds = GetSectionBounds(
s);
1563 InitStructBuilder.add(bounds.first);
1564 InitStructBuilder.add(bounds.second);
1566 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1568 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1569 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1571 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1578 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1579 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1580 LoadFunction,
".objc_ctor");
1583 assert(InitVar->getName() ==
".objc_ctor");
1589 if (CGM.
getTriple().isOSBinFormatCOFF())
1590 InitVar->setSection(
".CRT$XCLz");
1594 InitVar->setSection(
".init_array");
1596 InitVar->setSection(
".ctors");
1598 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1599 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1601 for (
auto *
C : Categories) {
1603 Cat->setSection(sectionName<CategorySection>());
1606 auto createNullGlobal = [&](StringRef Name, ArrayRef<llvm::Constant*>
Init,
1607 StringRef Section) {
1608 auto nullBuilder = builder.beginStruct();
1609 for (
auto *F :
Init)
1611 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1612 false, llvm::GlobalValue::LinkOnceODRLinkage);
1613 GV->setSection(Section);
1614 GV->setComdat(TheModule.getOrInsertComdat(Name));
1615 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1619 for (
auto clsAlias : ClassAliases)
1620 createNullGlobal(std::string(
".objc_class_alias") +
1621 clsAlias.second, { MakeConstantString(clsAlias.second),
1622 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1627 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1628 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1629 sectionName<SelectorSection>());
1630 if (Categories.empty())
1631 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1632 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1633 sectionName<CategorySection>());
1634 if (!EmittedClass) {
1635 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1636 sectionName<ClassSection>());
1637 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1638 sectionName<ClassReferenceSection>());
1640 if (!EmittedProtocol)
1641 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1642 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1643 NULLPtr}, sectionName<ProtocolSection>());
1644 if (!EmittedProtocolRef)
1645 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1646 sectionName<ProtocolReferenceSection>());
1647 if (ClassAliases.empty())
1648 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1649 sectionName<ClassAliasSection>());
1650 if (ConstantStrings.empty()) {
1651 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1652 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1653 i32Zero, i32Zero, i32Zero, NULLPtr },
1654 sectionName<ConstantStringSection>());
1657 ConstantStrings.clear();
1661 if (EarlyInitList.size() > 0) {
1662 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1663 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1665 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1667 for (
const auto &lateInit : EarlyInitList) {
1668 auto *global = TheModule.getGlobalVariable(lateInit.first);
1670 llvm::GlobalVariable *GV = lateInit.second.first;
1671 b.CreateAlignedStore(
1673 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1680 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1681 true, llvm::GlobalValue::InternalLinkage,
1682 Init,
".objc_early_init_ptr");
1683 InitVar->setSection(
".CRT$XCLb");
1690 std::string GetIVarOffsetVariableName(
const ObjCInterfaceDecl *ID,
1691 const ObjCIvarDecl *Ivar)
override {
1692 std::string TypeEncoding;
1694 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1695 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1699 llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
1701 const ObjCIvarDecl *Ivar)
override {
1702 const ObjCInterfaceDecl *ContainingInterface =
1704 const std::string Name =
1705 GetIVarOffsetVariableName(ContainingInterface, Ivar);
1706 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1707 if (!IvarOffsetPointer) {
1708 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1709 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1715 llvm::Value *Offset =
1717 if (Offset->getType() != PtrDiffTy)
1718 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1721 void GenerateClass(
const ObjCImplementationDecl *OID)
override {
1723 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1726 ObjCInterfaceDecl *classDecl =
1729 auto *classNameConstant = MakeConstantString(className);
1731 ConstantInitBuilder builder(CGM);
1732 auto metaclassFields = builder.beginStruct();
1734 metaclassFields.addNullPointer(PtrTy);
1736 metaclassFields.addNullPointer(PtrTy);
1738 metaclassFields.add(classNameConstant);
1740 metaclassFields.addInt(LongTy, 0);
1743 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1747 metaclassFields.addInt(LongTy, 0);
1749 metaclassFields.addNullPointer(PtrTy);
1754 metaclassFields.addNullPointer(PtrTy);
1756 SmallVector<ObjCMethodDecl*, 16> ClassMethods;
1759 metaclassFields.add(
1760 GenerateMethodList(className,
"", ClassMethods,
true));
1763 metaclassFields.addNullPointer(PtrTy);
1765 metaclassFields.addNullPointer(PtrTy);
1767 metaclassFields.addNullPointer(PtrTy);
1769 metaclassFields.addNullPointer(PtrTy);
1771 metaclassFields.addNullPointer(PtrTy);
1773 metaclassFields.addNullPointer(PtrTy);
1775 metaclassFields.addNullPointer(PtrTy);
1777 metaclassFields.addInt(LongTy, 0);
1779 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1781 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1782 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1785 auto classFields = builder.beginStruct();
1787 classFields.add(metaclass);
1790 const ObjCInterfaceDecl * SuperClassDecl =
1792 llvm::Constant *SuperClass =
nullptr;
1793 if (SuperClassDecl) {
1794 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1795 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1798 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1799 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1801 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1802 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1803 Storage = llvm::GlobalValue::DLLImportStorageClass;
1804 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1805 Storage = llvm::GlobalValue::DLLExportStorageClass;
1811 classFields.add(SuperClass);
1813 classFields.addNullPointer(PtrTy);
1815 classFields.addNullPointer(PtrTy);
1817 classFields.
add(classNameConstant);
1819 classFields.addInt(LongTy, 0);
1822 classFields.addInt(LongTy, 0);
1824 int superInstanceSize = !SuperClassDecl ? 0 :
1837 classFields.addNullPointer(PtrTy);
1842 const llvm::DataLayout &DL = TheModule.getDataLayout();
1844 ConstantInitBuilder
b(CGM);
1845 auto ivarListBuilder =
b.beginStruct();
1847 ivarListBuilder.addInt(IntTy, ivar_count);
1849 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1855 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1858 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1861 auto ivarTy = IVD->getType();
1862 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1864 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1866 std::string TypeStr;
1869 ivarBuilder.add(MakeConstantString(TypeStr));
1871 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1872 uint64_t Offset = BaseOffset - superInstanceSize;
1873 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1874 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1875 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1877 OffsetVar->setInitializer(OffsetValue);
1879 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1880 false, llvm::GlobalValue::ExternalLinkage,
1881 OffsetValue, OffsetName);
1882 auto ivarVisibility =
1886 llvm::GlobalValue::HiddenVisibility :
1887 llvm::GlobalValue::DefaultVisibility;
1888 OffsetVar->setVisibility(ivarVisibility);
1889 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1891 ivarBuilder.add(OffsetVar);
1893 ivarBuilder.addInt(Int32Ty,
1904 ivarBuilder.addInt(Int32Ty,
1905 (align << 3) | (1<<2) |
1906 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1907 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1909 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1910 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1912 llvm::GlobalValue::PrivateLinkage);
1913 classFields.add(ivarList);
1916 SmallVector<const ObjCMethodDecl*, 16> InstanceMethods;
1917 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1920 if (propImpl->getPropertyImplementation() ==
1922 auto addIfExists = [&](
const ObjCMethodDecl *OMD) {
1923 if (OMD && OMD->hasBody())
1924 InstanceMethods.push_back(OMD);
1926 addIfExists(propImpl->getGetterMethodDecl());
1927 addIfExists(propImpl->getSetterMethodDecl());
1930 if (InstanceMethods.size() == 0)
1931 classFields.addNullPointer(PtrTy);
1934 GenerateMethodList(className,
"", InstanceMethods,
false));
1937 classFields.addNullPointer(PtrTy);
1939 classFields.addNullPointer(PtrTy);
1941 classFields.addNullPointer(PtrTy);
1943 classFields.addNullPointer(PtrTy);
1945 classFields.addNullPointer(PtrTy);
1947 auto RuntimeProtocols =
1950 SmallVector<llvm::Constant *, 16> Protocols;
1951 for (
const auto *I : RuntimeProtocols)
1952 Protocols.push_back(GenerateProtocolRef(I));
1954 if (Protocols.empty())
1955 classFields.addNullPointer(PtrTy);
1957 classFields.add(GenerateProtocolList(Protocols));
1959 classFields.addNullPointer(PtrTy);
1961 classFields.addInt(LongTy, 0);
1963 classFields.add(GeneratePropertyList(OID, classDecl));
1965 llvm::GlobalVariable *classStruct =
1966 classFields.finishAndCreateGlobal(SymbolForClass(className),
1969 auto *classRefSymbol = GetClassVar(className);
1970 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1971 classRefSymbol->setInitializer(classStruct);
1976 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1981 std::pair<llvm::GlobalVariable*, int> v{classStruct, 1};
1982 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1991 if (ClassPtrAlias) {
1992 ClassPtrAlias->replaceAllUsesWith(classStruct);
1993 ClassPtrAlias->eraseFromParent();
1994 ClassPtrAlias =
nullptr;
1996 if (
auto Placeholder =
1997 TheModule.getNamedGlobal(SymbolForClass(className)))
1998 if (Placeholder != classStruct) {
1999 Placeholder->replaceAllUsesWith(classStruct);
2000 Placeholder->eraseFromParent();
2001 classStruct->setName(SymbolForClass(className));
2003 if (MetaClassPtrAlias) {
2004 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
2005 MetaClassPtrAlias->eraseFromParent();
2006 MetaClassPtrAlias =
nullptr;
2008 assert(classStruct->getName() == SymbolForClass(className));
2010 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2011 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2012 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2013 classInitRef->setSection(sectionName<ClassSection>());
2016 EmittedClass =
true;
2019 CGObjCGNUstep2(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2020 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2021 PtrToObjCSuperTy, SelectorTy);
2022 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2023 llvm::Type::getVoidTy(VMContext), IdTy);
2032 PropertyMetadataTy =
2034 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2037 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
2038 const ObjCMethodDecl *OMD,
2039 const ObjCContainerDecl *CD)
override {
2041 bool ReceiverCanBeNull =
true;
2043 auto selfValue = Builder.CreateLoad(selfAddr);
2068 ReceiverCanBeNull = isWeakLinkedClass(OID);
2072 if (ReceiverCanBeNull) {
2073 llvm::BasicBlock *SelfIsNilBlock =
2075 llvm::BasicBlock *ContBlock =
2080 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2082 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero),
2083 SelfIsNilBlock, ContBlock,
2084 MDHelper.createUnlikelyBranchWeights());
2090 Builder.SetInsertPoint(SelfIsNilBlock);
2091 if (!retTy->isVoidType()) {
2099 Builder.SetInsertPoint(ContBlock);
2105 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2112 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2114 astContext.getTypeAlign(astContext.UnsignedLongTy));
2115 auto flags = Builder.CreateLoad(Address{Val, LongTy, Align});
2116 auto isInitialized =
2117 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2118 llvm::BasicBlock *notInitializedBlock =
2120 llvm::BasicBlock *initializedBlock =
2122 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2123 notInitializedBlock, initializedBlock,
2124 MDHelper.createUnlikelyBranchWeights());
2126 Builder.SetInsertPoint(notInitializedBlock);
2128 Builder.CreateBr(initializedBlock);
2130 Builder.SetInsertPoint(initializedBlock);
2138 Builder.CreateStore(GetSelector(CGF, OMD),
2144const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2151"__objc_protocol_refs",
2152"__objc_class_aliases",
2153"__objc_constant_string"
2156const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2169class CGObjCObjFW:
public CGObjCGNU {
2173 LazyRuntimeFunction MsgLookupFn;
2176 LazyRuntimeFunction MsgLookupFnSRet;
2180 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2182 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
2183 llvm::Value *cmd, llvm::MDNode *node,
2184 MessageSendInfo &MSI)
override {
2185 CGBuilderTy &Builder = CGF.
Builder;
2186 llvm::Value *args[] = {
2187 EnforceType(Builder, Receiver, IdTy),
2188 EnforceType(Builder, cmd, SelectorTy) };
2190 llvm::CallBase *imp;
2196 imp->setMetadata(msgSendMDKind, node);
2200 llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
2201 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2202 CGBuilderTy &Builder = CGF.
Builder;
2203 llvm::Value *lookupArgs[] = {
2204 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2214 llvm::Value *GetClassNamed(CodeGenFunction &CGF,
const std::string &Name,
2215 bool isWeak)
override {
2217 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2220 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2221 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2223 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2224 llvm::GlobalValue::ExternalLinkage,
2225 nullptr, SymbolName);
2229 void GenerateDirectMethodPrologue(
2230 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
2231 const ObjCContainerDecl *CD)
override {
2233 bool ReceiverCanBeNull =
true;
2235 auto selfValue = Builder.CreateLoad(selfAddr);
2254 "GenerateDirectMethod() should be called with the Class Interface");
2267 result = GeneratePossiblySpecializedMessageSend(
2268 CGF, ReturnValueSlot(), ResultType, SelfSel, selfValue, Args, OID,
2275 ReceiverCanBeNull = isWeakLinkedClass(OID);
2278 if (ReceiverCanBeNull) {
2279 llvm::BasicBlock *SelfIsNilBlock =
2281 llvm::BasicBlock *ContBlock =
2286 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2289 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero),
2290 SelfIsNilBlock, ContBlock,
2291 MDHelper.createUnlikelyBranchWeights());
2297 Builder.SetInsertPoint(SelfIsNilBlock);
2298 if (!retTy->isVoidType()) {
2306 Builder.SetInsertPoint(ContBlock);
2314 Builder.CreateStore(GetSelector(CGF, OMD),
2320 CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
2322 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2323 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2326 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2327 PtrToObjCSuperTy, SelectorTy);
2328 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2329 PtrToObjCSuperTy, SelectorTy);
2337void CGObjCGNU::EmitClassRef(
const std::string &className) {
2338 std::string symbolRef =
"__objc_class_ref_" + className;
2340 if (TheModule.getGlobalVariable(symbolRef))
2342 std::string symbolName =
"__objc_class_name_" + className;
2343 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2345 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2346 llvm::GlobalValue::ExternalLinkage,
2347 nullptr, symbolName);
2349 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2350 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2353CGObjCGNU::CGObjCGNU(CodeGenModule &cgm,
unsigned runtimeABIVersion,
2354 unsigned protocolClassVersion,
unsigned classABI)
2355 : CGObjCRuntime(cgm), TheModule(CGM.getModule()),
2356 VMContext(cgm.getLLVMContext()), ClassPtrAlias(
nullptr),
2357 MetaClassPtrAlias(
nullptr), RuntimeVersion(runtimeABIVersion),
2358 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2360 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2362 cgm.
getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment();
2364 cgm.
getContext().getTargetInfo().getTriple().isOSCygMing() &&
2378 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2383 PtrToInt8Ty = PtrTy;
2384 ProtocolPtrTy = PtrTy;
2386 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2387 Zeros[1] = Zeros[0];
2388 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2392 SelectorTy = PtrToInt8Ty;
2393 SelectorElemTy = Int8Ty;
2399 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2400 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2403 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2418 ProtocolTy = llvm::StructType::get(IdTy,
2440 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2441 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2442 PtrToInt8Ty, PtrToInt8Ty });
2444 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2445 PtrToObjCSuperTy = PtrTy;
2447 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2450 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2451 ExceptionReThrowFn.init(&CGM,
2452 usesCxxExceptions ?
"objc_exception_rethrow"
2453 :
"objc_exception_throw",
2456 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2458 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2461 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2464 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2467 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2468 PtrDiffTy, IdTy, BoolTy, BoolTy);
2470 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2471 PtrDiffTy, BoolTy, BoolTy);
2473 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2474 PtrDiffTy, BoolTy, BoolTy);
2481 RuntimeVersion = 10;
2496 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2498 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2501 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2503 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2505 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2507 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2513 const std::string &Name,
bool isWeak) {
2514 llvm::Constant *ClassName = MakeConstantString(Name);
2526 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2532llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF,
2533 const ObjCInterfaceDecl *OID) {
2536 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2541llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
2542 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2543 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2544 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2549 const VarDecl *VD =
nullptr;
2551 if ((VD = dyn_cast<VarDecl>(
Result)))
2560llvm::Value *CGObjCGNU::GetTypedSelector(CodeGenFunction &CGF, Selector Sel,
2561 const std::string &TypeEncoding) {
2562 SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel];
2563 llvm::GlobalAlias *SelValue =
nullptr;
2565 for (
const TypedSelector &
Type : Types) {
2566 if (
Type.first == TypeEncoding) {
2567 SelValue =
Type.second;
2572 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2573 llvm::GlobalValue::PrivateLinkage,
2576 Types.emplace_back(TypeEncoding, SelValue);
2582Address CGObjCGNU::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2583 llvm::Value *SelValue = GetSelector(CGF, Sel);
2593llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2594 return GetTypedSelector(CGF, Sel, std::string());
2597llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF,
2598 const ObjCMethodDecl *
Method) {
2600 return GetTypedSelector(CGF,
Method->getSelector(), SelTypes);
2603llvm::Constant *CGObjCGNU::GetEHType(QualType
T) {
2610 return MakeConstantString(
"@id");
2617 const ObjCObjectPointerType *OPT =
T->
getAs<ObjCObjectPointerType>();
2618 assert(OPT &&
"Invalid @catch type.");
2619 const ObjCInterfaceDecl *IDecl = OPT->
getObjectType()->getInterface();
2620 assert(IDecl &&
"Invalid @catch type.");
2624llvm::Constant *CGObjCGNUstep::GetEHType(QualType
T) {
2625 if (usesSEHExceptions)
2628 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2629 return CGObjCGNU::GetEHType(
T);
2637 llvm::Constant *IDEHType =
2638 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2641 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2643 llvm::GlobalValue::ExternalLinkage,
2644 nullptr,
"__objc_id_type_info");
2648 const ObjCObjectPointerType *PT =
2649 T->
getAs<ObjCObjectPointerType>();
2650 assert(PT &&
"Invalid @catch type.");
2652 assert(IT &&
"Invalid @catch type.");
2653 std::string className =
2656 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2659 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2667 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2668 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2670 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2671 llvm::GlobalValue::ExternalLinkage,
2672 nullptr, vtableName);
2674 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2676 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2678 llvm::Constant *typeName =
2679 ExportUniqueString(className,
"__objc_eh_typename_");
2681 ConstantInitBuilder builder(CGM);
2682 auto fields = builder.beginStruct();
2683 fields.add(BVtable);
2684 fields.add(typeName);
2685 llvm::Constant *TI =
2686 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2689 llvm::GlobalValue::LinkOnceODRLinkage);
2694ConstantAddress CGObjCGNU::GenerateConstantString(
const StringLiteral *SL) {
2696 std::string Str = SL->
getString().str();
2700 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2701 if (old != ObjCStrings.end())
2702 return ConstantAddress(old->getValue(), Int8Ty, Align);
2706 if (StringClass.empty()) StringClass =
"NSConstantString";
2708 std::string Sym =
"_OBJC_CLASS_";
2711 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2714 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2715 llvm::GlobalValue::ExternalWeakLinkage,
2718 ConstantInitBuilder Builder(CGM);
2719 auto Fields = Builder.beginStruct();
2721 Fields.
add(MakeConstantString(Str));
2722 Fields.
addInt(IntTy, Str.size());
2724 ObjCStrings[Str] = ObjCStr;
2725 ConstantStrings.push_back(ObjCStr);
2726 return ConstantAddress(ObjCStr, Int8Ty, Align);
2733CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
2734 ReturnValueSlot Return,
2735 QualType ResultType,
2737 const ObjCInterfaceDecl *
Class,
2738 bool isCategoryImpl,
2739 llvm::Value *Receiver,
2740 bool IsClassMessage,
2741 const CallArgList &CallArgs,
2742 const ObjCMethodDecl *
Method) {
2743 CGBuilderTy &Builder = CGF.
Builder;
2744 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2745 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2749 if (Sel == ReleaseSel) {
2754 llvm::Value *cmd = GetSelector(CGF, Sel);
2755 CallArgList ActualArgs;
2757 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2761 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2763 llvm::Value *ReceiverClass =
nullptr;
2766 ReceiverClass = GetClassNamed(CGF,
2767 Class->getSuperClass()->getNameAsString(),
false);
2768 if (IsClassMessage) {
2771 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2773 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2775 if (isCategoryImpl) {
2776 llvm::FunctionCallee classLookupFunction =
nullptr;
2777 if (IsClassMessage) {
2779 IdTy, PtrTy,
true),
"objc_get_meta_class");
2782 IdTy, PtrTy,
true),
"objc_get_class");
2784 ReceiverClass = Builder.CreateCall(classLookupFunction,
2785 MakeConstantString(
Class->getNameAsString()));
2792 if (IsClassMessage) {
2793 if (!MetaClassPtrAlias) {
2794 MetaClassPtrAlias = llvm::GlobalAlias::create(
2795 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2796 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2798 ReceiverClass = MetaClassPtrAlias;
2800 if (!ClassPtrAlias) {
2801 ClassPtrAlias = llvm::GlobalAlias::create(
2802 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2803 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2805 ReceiverClass = ClassPtrAlias;
2809 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2811 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2814 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2817 llvm::StructType *ObjCSuperTy =
2818 llvm::StructType::get(Receiver->getType(), IdTy);
2823 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2824 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2827 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2828 imp = EnforceType(Builder, imp, MSI.MessengerType);
2830 llvm::Metadata *impMD[] = {
2831 llvm::MDString::get(VMContext, Sel.
getAsString()),
2832 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2833 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2834 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2835 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2837 CGCallee callee(CGCalleeInfo(), imp);
2839 llvm::CallBase *call;
2840 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2841 call->setMetadata(msgSendMDKind, node);
2847CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
2848 ReturnValueSlot Return,
2849 QualType ResultType,
2851 llvm::Value *Receiver,
2852 const CallArgList &CallArgs,
2853 const ObjCInterfaceDecl *
Class,
2854 const ObjCMethodDecl *
Method) {
2855 CGBuilderTy &Builder = CGF.
Builder;
2858 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2859 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2863 if (Sel == ReleaseSel) {
2874 cmd = GetSelector(CGF,
Method);
2876 cmd = GetSelector(CGF, Sel);
2877 cmd = EnforceType(Builder, cmd, SelectorTy);
2880 Receiver = EnforceType(Builder, Receiver, IdTy);
2882 llvm::Metadata *impMD[] = {
2883 llvm::MDString::get(VMContext, Sel.
getAsString()),
2884 llvm::MDString::get(VMContext,
Class ?
Class->getNameAsString() :
""),
2885 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2886 llvm::Type::getInt1Ty(VMContext),
Class !=
nullptr))};
2887 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2889 CallArgList ActualArgs;
2895 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2916 bool hasParamDestroyedInCallee =
false;
2917 bool requiresExplicitZeroResult =
false;
2918 bool requiresNilReceiverCheck = [&] {
2920 if (!canMessageReceiverBeNull(CGF,
Method,
false,
2926 hasParamDestroyedInCallee =
true;
2947 requiresExplicitZeroResult = !isDirect;
2951 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2957 bool requiresExplicitAggZeroing =
2961 llvm::BasicBlock *continueBB =
nullptr;
2963 llvm::BasicBlock *nilPathBB =
nullptr;
2965 llvm::BasicBlock *nilCleanupBB =
nullptr;
2968 if (requiresNilReceiverCheck) {
2975 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2978 nilPathBB = Builder.GetInsertBlock();
2981 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2982 llvm::Constant::getNullValue(Receiver->getType()));
2983 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2993 imp = GenerateMethod(
Method,
Method->getClassInterface());
3000 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
3004 StringRef
name =
"objc_msgSend";
3006 name =
"objc_msgSend_fpret";
3008 name =
"objc_msgSend_stret";
3012 bool shouldCheckForInReg =
3016 .isWindowsMSVCEnvironment() &&
3019 name =
"objc_msgSend_stret2";
3030 ActualArgs[0] = CallArg(
RValue::get(Receiver), ASTIdTy);
3032 imp = EnforceType(Builder, imp, MSI.MessengerType);
3034 llvm::CallBase *call;
3035 CGCallee callee(CGCalleeInfo(), imp);
3036 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
3038 call->setMetadata(msgSendMDKind, node);
3040 if (requiresNilReceiverCheck) {
3041 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
3042 CGF.
Builder.CreateBr(continueBB);
3048 if (hasParamDestroyedInCallee) {
3049 destroyCalleeDestroyedArguments(CGF,
Method, CallArgs);
3052 if (requiresExplicitAggZeroing) {
3058 nilPathBB = CGF.
Builder.GetInsertBlock();
3059 CGF.
Builder.CreateBr(continueBB);
3067 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
3068 phi->addIncoming(v, nonNilPathBB);
3075 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
3076 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
3077 phi->addIncoming(v.first, nonNilPathBB);
3078 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
3080 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
3081 phi2->addIncoming(v.second, nonNilPathBB);
3082 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
3092llvm::Constant *CGObjCGNU::
3093GenerateMethodList(StringRef ClassName,
3094 StringRef CategoryName,
3095 ArrayRef<const ObjCMethodDecl*> Methods,
3096 bool isClassMethodList) {
3097 if (Methods.empty())
3100 ConstantInitBuilder Builder(CGM);
3102 auto MethodList = Builder.beginStruct();
3103 MethodList.addNullPointer(CGM.
Int8PtrTy);
3104 MethodList.addInt(Int32Ty, Methods.size());
3107 llvm::StructType *ObjCMethodTy =
3116 const llvm::DataLayout &DL = TheModule.getDataLayout();
3117 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3133 auto MethodArray = MethodList.beginArray();
3135 for (
const auto *OMD : Methods) {
3136 llvm::Constant *FnPtr =
3137 TheModule.getFunction(getSymbolNameForMethod(OMD));
3138 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3139 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3150 Method.finishAndAddTo(MethodArray);
3152 MethodArray.finishAndAddTo(MethodList);
3155 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3160llvm::Constant *CGObjCGNU::
3161GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
3162 ArrayRef<llvm::Constant *> IvarTypes,
3163 ArrayRef<llvm::Constant *> IvarOffsets,
3164 ArrayRef<llvm::Constant *> IvarAlign,
3165 ArrayRef<Qualifiers::ObjCLifetime> IvarOwnership) {
3166 if (IvarNames.empty())
3169 ConstantInitBuilder Builder(CGM);
3172 auto IvarList = Builder.beginStruct();
3173 IvarList.addInt(IntTy, (
int)IvarNames.size());
3176 llvm::StructType *ObjCIvarTy =
3177 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3180 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3181 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3182 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3183 Ivar.
add(IvarNames[i]);
3184 Ivar.
add(IvarTypes[i]);
3185 Ivar.
add(IvarOffsets[i]);
3186 Ivar.finishAndAddTo(Ivars);
3188 Ivars.finishAndAddTo(IvarList);
3191 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3196llvm::Constant *CGObjCGNU::GenerateClassStructure(
3197 llvm::Constant *MetaClass,
3198 llvm::Constant *SuperClass,
3201 llvm::Constant *Version,
3202 llvm::Constant *InstanceSize,
3203 llvm::Constant *IVars,
3204 llvm::Constant *Methods,
3205 llvm::Constant *Protocols,
3206 llvm::Constant *IvarOffsets,
3207 llvm::Constant *Properties,
3208 llvm::Constant *StrongIvarBitmap,
3209 llvm::Constant *WeakIvarBitmap,
3218 llvm::StructType *ClassTy = llvm::StructType::get(
3235 IvarOffsets->getType(),
3236 Properties->getType(),
3241 ConstantInitBuilder Builder(CGM);
3242 auto Elements = Builder.beginStruct(ClassTy);
3247 Elements.add(MetaClass);
3249 Elements.add(SuperClass);
3251 Elements.add(MakeConstantString(Name,
".class_name"));
3253 Elements.addInt(LongTy, 0);
3255 Elements.addInt(LongTy, info);
3258 const llvm::DataLayout &DL = TheModule.getDataLayout();
3259 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3262 Elements.add(InstanceSize);
3264 Elements.add(IVars);
3266 Elements.add(Methods);
3269 Elements.add(NULLPtr);
3271 Elements.add(NULLPtr);
3273 Elements.add(NULLPtr);
3275 Elements.add(Protocols);
3277 Elements.add(NULLPtr);
3279 Elements.addInt(LongTy, ClassABIVersion);
3281 Elements.add(IvarOffsets);
3283 Elements.add(Properties);
3285 Elements.add(StrongIvarBitmap);
3287 Elements.add(WeakIvarBitmap);
3292 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3294 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3295 llvm::Constant *
Class =
3296 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3297 llvm::GlobalValue::ExternalLinkage);
3299 ClassRef->replaceAllUsesWith(
Class);
3300 ClassRef->removeFromParent();
3301 Class->setName(ClassSym);
3306llvm::Constant *CGObjCGNU::
3307GenerateProtocolMethodList(ArrayRef<const ObjCMethodDecl*> Methods) {
3309 llvm::StructType *ObjCMethodDescTy =
3310 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3312 ConstantInitBuilder Builder(CGM);
3313 auto MethodList = Builder.beginStruct();
3314 MethodList.addInt(IntTy, Methods.size());
3315 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3316 for (
auto *M : Methods) {
3317 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3318 Method.add(MakeConstantString(M->getSelector().getAsString()));
3320 Method.finishAndAddTo(MethodArray);
3322 MethodArray.finishAndAddTo(MethodList);
3323 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3329CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) {
3331 ConstantInitBuilder Builder(CGM);
3332 auto ProtocolList = Builder.beginStruct();
3333 ProtocolList.add(NULLPtr);
3334 ProtocolList.addInt(LongTy, Protocols.size());
3336 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3337 for (
const std::string &Protocol : Protocols) {
3338 llvm::Constant *protocol =
nullptr;
3339 llvm::StringMap<llvm::Constant *>::iterator value =
3340 ExistingProtocols.find(Protocol);
3341 if (value == ExistingProtocols.end()) {
3342 protocol = GenerateEmptyProtocol(Protocol);
3344 protocol = value->getValue();
3346 Elements.add(protocol);
3348 Elements.finishAndAddTo(ProtocolList);
3349 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3353llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
3354 const ObjCProtocolDecl *PD) {
3355 return GenerateProtocolRef(PD);
3358llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3361 GenerateProtocol(PD);
3362 assert(protocol &&
"Unknown protocol");
3367CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3368 llvm::Constant *ProtocolList = GenerateProtocolList({});
3369 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3372 ConstantInitBuilder Builder(CGM);
3373 auto Elements = Builder.beginStruct();
3377 Elements.add(llvm::ConstantExpr::getIntToPtr(
3378 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3380 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3381 Elements.add(ProtocolList);
3382 Elements.add(MethodList);
3383 Elements.add(MethodList);
3384 Elements.add(MethodList);
3385 Elements.add(MethodList);
3386 Elements.add(NULLPtr);
3387 Elements.add(NULLPtr);
3388 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3392void CGObjCGNU::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3402 SmallVector<std::string, 16> Protocols;
3404 Protocols.push_back(PI->getNameAsString());
3405 SmallVector<const ObjCMethodDecl*, 16> InstanceMethods;
3406 SmallVector<const ObjCMethodDecl*, 16> OptionalInstanceMethods;
3408 if (I->isOptional())
3409 OptionalInstanceMethods.push_back(I);
3411 InstanceMethods.push_back(I);
3413 SmallVector<const ObjCMethodDecl*, 16> ClassMethods;
3414 SmallVector<const ObjCMethodDecl*, 16> OptionalClassMethods;
3416 if (I->isOptional())
3417 OptionalClassMethods.push_back(I);
3419 ClassMethods.push_back(I);
3421 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3422 llvm::Constant *InstanceMethodList =
3423 GenerateProtocolMethodList(InstanceMethods);
3424 llvm::Constant *ClassMethodList =
3425 GenerateProtocolMethodList(ClassMethods);
3426 llvm::Constant *OptionalInstanceMethodList =
3427 GenerateProtocolMethodList(OptionalInstanceMethods);
3428 llvm::Constant *OptionalClassMethodList =
3429 GenerateProtocolMethodList(OptionalClassMethods);
3437 llvm::Constant *PropertyList =
3438 GeneratePropertyList(
nullptr, PD,
false,
false);
3439 llvm::Constant *OptionalPropertyList =
3440 GeneratePropertyList(
nullptr, PD,
false,
true);
3446 ConstantInitBuilder Builder(CGM);
3447 auto Elements = Builder.beginStruct();
3449 llvm::ConstantExpr::getIntToPtr(
3450 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3451 Elements.add(MakeConstantString(ProtocolName));
3452 Elements.add(ProtocolList);
3453 Elements.add(InstanceMethodList);
3454 Elements.add(ClassMethodList);
3455 Elements.add(OptionalInstanceMethodList);
3456 Elements.add(OptionalClassMethodList);
3457 Elements.add(PropertyList);
3458 Elements.add(OptionalPropertyList);
3459 ExistingProtocols[ProtocolName] =
3460 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3462void CGObjCGNU::GenerateProtocolHolderCategory() {
3465 ConstantInitBuilder Builder(CGM);
3466 auto Elements = Builder.beginStruct();
3468 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3469 const std::string CategoryName =
"AnotherHack";
3470 Elements.add(MakeConstantString(CategoryName));
3471 Elements.add(MakeConstantString(ClassName));
3473 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3475 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3478 ConstantInitBuilder ProtocolListBuilder(CGM);
3479 auto ProtocolList = ProtocolListBuilder.beginStruct();
3480 ProtocolList.add(NULLPtr);
3481 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3482 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3483 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3484 iter != endIter ; iter++) {
3485 ProtocolElements.add(iter->getValue());
3487 ProtocolElements.finishAndAddTo(ProtocolList);
3488 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3490 Categories.push_back(
3505llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) {
3506 int bitCount = bits.size();
3508 if (bitCount < ptrBits) {
3510 for (
int i=0 ; i<bitCount ; ++i) {
3511 if (bits[i]) val |= 1ULL<<(i+1);
3513 return llvm::ConstantInt::get(IntPtrTy, val);
3515 SmallVector<llvm::Constant *, 8> values;
3517 while (v < bitCount) {
3519 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3520 if (bits[v]) word |= 1<<i;
3523 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3526 ConstantInitBuilder builder(CGM);
3527 auto fields = builder.beginStruct();
3528 fields.addInt(Int32Ty, values.size());
3529 auto array = fields.beginArray();
3530 for (
auto *v : values) array.add(v);
3531 array.finishAndAddTo(fields);
3533 llvm::Constant *GS =
3535 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3539llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3540 ObjCCategoryDecl *OCD) {
3542 const auto RuntimeProtos =
3543 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3544 SmallVector<std::string, 16> Protocols;
3545 for (
const auto *PD : RuntimeProtos)
3547 return GenerateProtocolList(Protocols);
3550void CGObjCGNU::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3552 std::string ClassName =
Class->getNameAsString();
3558 ConstantInitBuilder Builder(CGM);
3559 auto Elements = Builder.beginStruct();
3560 Elements.add(MakeConstantString(CategoryName));
3561 Elements.add(MakeConstantString(ClassName));
3563 SmallVector<ObjCMethodDecl*, 16> InstanceMethods;
3564 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3567 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3571 SmallVector<ObjCMethodDecl*, 16> ClassMethods;
3574 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3577 Elements.add(GenerateCategoryProtocolList(CatDecl));
3579 const ObjCCategoryDecl *Category =
3583 Elements.add(GeneratePropertyList(OCD, Category,
false));
3585 Elements.add(GeneratePropertyList(OCD, Category,
true));
3587 Elements.addNullPointer(PtrTy);
3588 Elements.addNullPointer(PtrTy);
3592 Categories.push_back(Elements.finishAndCreateGlobal(
3593 std::string(
".objc_category_") + ClassName + CategoryName,
3597llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3598 const ObjCContainerDecl *OCD,
3599 bool isClassProperty,
3600 bool protocolOptionalProperties) {
3602 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3603 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3607 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3608 = [&](
const ObjCProtocolDecl *Proto) {
3609 for (
const auto *P : Proto->protocols())
3610 collectProtocolProperties(P);
3611 for (
const auto *PD : Proto->properties()) {
3612 if (isClassProperty != PD->isClassProperty())
3620 Properties.push_back(PD);
3624 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3626 for (
auto *PD : ClassExt->properties()) {
3627 if (isClassProperty != PD->isClassProperty())
3630 Properties.push_back(PD);
3634 if (isClassProperty != PD->isClassProperty())
3638 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3645 Properties.push_back(PD);
3648 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3650 collectProtocolProperties(P);
3651 else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD))
3652 for (
const auto *P : CD->protocols())
3653 collectProtocolProperties(P);
3655 auto numProperties = Properties.size();
3657 if (numProperties == 0)
3660 ConstantInitBuilder builder(CGM);
3661 auto propertyList = builder.beginStruct();
3662 auto properties = PushPropertyListHeader(propertyList, numProperties);
3666 for (
auto *property : Properties) {
3667 bool isSynthesized =
false;
3668 bool isDynamic =
false;
3672 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3674 isDynamic = (propertyImpl->getPropertyImplementation() ==
3678 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3680 properties.finishAndAddTo(propertyList);
3682 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3686void CGObjCGNU::RegisterAlias(
const ObjCCompatibleAliasDecl *OAD) {
3688 ObjCInterfaceDecl *ClassDecl =
3694void CGObjCGNU::GenerateClass(
const ObjCImplementationDecl *OID) {
3698 const ObjCInterfaceDecl * SuperClassDecl =
3700 std::string SuperClassName;
3701 if (SuperClassDecl) {
3703 EmitClassRef(SuperClassName);
3707 ObjCInterfaceDecl *ClassDecl =
3713 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3714 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3715 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3717 new llvm::GlobalVariable(TheModule, LongTy,
false,
3718 llvm::GlobalValue::ExternalLinkage,
3719 llvm::ConstantInt::get(LongTy, 0),
3729 SmallVector<llvm::Constant*, 16> IvarNames;
3730 SmallVector<llvm::Constant*, 16> IvarTypes;
3731 SmallVector<llvm::Constant*, 16> IvarOffsets;
3732 SmallVector<llvm::Constant*, 16> IvarAligns;
3733 SmallVector<Qualifiers::ObjCLifetime, 16> IvarOwnership;
3735 ConstantInitBuilder IvarOffsetBuilder(CGM);
3736 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3737 SmallVector<bool, 16> WeakIvars;
3738 SmallVector<bool, 16> StrongIvars;
3740 int superInstanceSize = !SuperClassDecl ? 0 :
3745 instanceSize = 0 - (instanceSize - superInstanceSize);
3751 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3753 std::string TypeStr;
3755 IvarTypes.push_back(MakeConstantString(TypeStr));
3756 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3759 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3762 Offset = BaseOffset - superInstanceSize;
3764 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3766 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3767 IVD->getNameAsString();
3769 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3771 OffsetVar->setInitializer(OffsetValue);
3775 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3777 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3778 false, llvm::GlobalValue::ExternalLinkage,
3779 OffsetValue, OffsetName);
3780 IvarOffsets.push_back(OffsetValue);
3781 IvarOffsetValues.add(OffsetVar);
3783 IvarOwnership.push_back(lt);
3786 StrongIvars.push_back(
true);
3787 WeakIvars.push_back(
false);
3790 StrongIvars.push_back(
false);
3791 WeakIvars.push_back(
true);
3794 StrongIvars.push_back(
false);
3795 WeakIvars.push_back(
false);
3798 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3799 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3800 llvm::GlobalVariable *IvarOffsetArray =
3801 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3805 SmallVector<const ObjCMethodDecl*, 16> InstanceMethods;
3806 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3809 SmallVector<const ObjCMethodDecl*, 16> ClassMethods;
3813 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3816 auto RefProtocols = ClassDecl->
protocols();
3817 auto RuntimeProtocols =
3818 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3819 SmallVector<std::string, 16> Protocols;
3820 for (
const auto *I : RuntimeProtocols)
3821 Protocols.push_back(I->getNameAsString());
3824 llvm::Constant *SuperClass;
3825 if (!SuperClassName.empty()) {
3826 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3828 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3831 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3832 InstanceMethods,
false);
3833 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3834 ClassMethods,
true);
3835 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3836 IvarOffsets, IvarAligns, IvarOwnership);
3847 llvm::Type *IndexTy = Int32Ty;
3848 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3849 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3850 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3852 unsigned ivarIndex = 0;
3855 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3856 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3858 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3860 offsetPointerIndexes);
3862 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3864 offset->setInitializer(offsetValue);
3868 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3871 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3872 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3875 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3878 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3879 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3880 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3881 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3886 llvm::Constant *ClassStruct = GenerateClassStructure(
3887 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3888 llvm::ConstantInt::getSigned(LongTy, instanceSize), IvarList, MethodList,
3889 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3890 StrongIvarBitmap, WeakIvarBitmap);
3895 if (ClassPtrAlias) {
3896 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3897 ClassPtrAlias->eraseFromParent();
3898 ClassPtrAlias =
nullptr;
3900 if (MetaClassPtrAlias) {
3901 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3902 MetaClassPtrAlias->eraseFromParent();
3903 MetaClassPtrAlias =
nullptr;
3907 Classes.push_back(ClassStruct);
3910llvm::Function *CGObjCGNU::ModuleInitFunction() {
3912 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3913 ExistingProtocols.empty() && SelectorTable.empty())
3917 GenerateProtocolHolderCategory();
3919 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3922 { PtrToInt8Ty, PtrToInt8Ty });
3926 llvm::Constant *statics = NULLPtr;
3927 if (!ConstantStrings.empty()) {
3928 llvm::GlobalVariable *fileStatics = [&] {
3929 ConstantInitBuilder builder(CGM);
3930 auto staticsStruct = builder.beginStruct();
3933 if (stringClass.empty()) stringClass =
"NXConstantString";
3934 staticsStruct.add(MakeConstantString(stringClass,
3935 ".objc_static_class_name"));
3937 auto array = staticsStruct.beginArray();
3938 array.addAll(ConstantStrings);
3940 array.finishAndAddTo(staticsStruct);
3942 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3946 ConstantInitBuilder builder(CGM);
3947 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3948 allStaticsArray.add(fileStatics);
3949 allStaticsArray.addNullPointer(fileStatics->getType());
3951 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3957 SmallVector<llvm::GlobalAlias*, 16> selectorAliases;
3958 unsigned selectorCount;
3961 llvm::GlobalVariable *selectorList = [&] {
3962 ConstantInitBuilder builder(CGM);
3963 auto selectors = builder.beginArray(selStructTy);
3964 auto &table = SelectorTable;
3965 std::vector<Selector> allSelectors;
3966 for (
auto &entry : table)
3967 allSelectors.push_back(entry.first);
3968 llvm::sort(allSelectors);
3970 for (
auto &untypedSel : allSelectors) {
3971 std::string selNameStr = untypedSel.getAsString();
3972 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3974 for (TypedSelector &sel : table[untypedSel]) {
3975 llvm::Constant *selectorTypeEncoding = NULLPtr;
3976 if (!sel.first.empty())
3977 selectorTypeEncoding =
3978 MakeConstantString(sel.first,
".objc_sel_types");
3980 auto selStruct = selectors.beginStruct(selStructTy);
3981 selStruct.add(selName);
3982 selStruct.add(selectorTypeEncoding);
3983 selStruct.finishAndAddTo(selectors);
3986 selectorAliases.push_back(sel.second);
3991 selectorCount = selectors.size();
3997 auto selStruct = selectors.beginStruct(selStructTy);
3998 selStruct.add(NULLPtr);
3999 selStruct.add(NULLPtr);
4000 selStruct.finishAndAddTo(selectors);
4002 return selectors.finishAndCreateGlobal(
".objc_selector_list",
4007 for (
unsigned i = 0; i < selectorCount; ++i) {
4008 llvm::Constant *idxs[] = {
4010 llvm::ConstantInt::get(Int32Ty, i)
4013 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
4014 selectorList->getValueType(), selectorList, idxs);
4015 selectorAliases[i]->replaceAllUsesWith(selPtr);
4016 selectorAliases[i]->eraseFromParent();
4019 llvm::GlobalVariable *symtab = [&] {
4020 ConstantInitBuilder builder(CGM);
4021 auto symtab = builder.beginStruct();
4024 symtab.addInt(LongTy, selectorCount);
4026 symtab.add(selectorList);
4029 symtab.addInt(CGM.
Int16Ty, Classes.size());
4031 symtab.addInt(CGM.
Int16Ty, Categories.size());
4034 auto classList = symtab.beginArray(PtrToInt8Ty);
4035 classList.addAll(Classes);
4036 classList.addAll(Categories);
4038 classList.add(statics);
4039 classList.add(NULLPtr);
4040 classList.finishAndAddTo(symtab);
4048 llvm::Constant *module = [&] {
4049 llvm::Type *moduleEltTys[] = {
4050 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
4052 llvm::StructType *moduleTy = llvm::StructType::get(
4054 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
4056 ConstantInitBuilder builder(CGM);
4057 auto module = builder.beginStruct(moduleTy);
4059 module.addInt(LongTy, RuntimeVersion);
4061 module.addInt(LongTy, CGM.getDataLayout().getTypeStoreSize(moduleTy));
4068 module.add(MakeConstantString(path, ".objc_source_file_name"));
4071 if (RuntimeVersion >= 10) {
4073 case LangOptions::GCOnly:
4074 module.addInt(IntTy, 2);
4076 case LangOptions::NonGC:
4078 module.addInt(IntTy, 1);
4080 module.addInt(IntTy, 0);
4082 case LangOptions::HybridGC:
4083 module.addInt(IntTy, 1);
4088 return module.finishAndCreateGlobal("", CGM.getPointerAlign());
4093 llvm::Function * LoadFunction = llvm::Function::Create(
4094 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4095 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4097 llvm::BasicBlock *EntryBB =
4098 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4099 CGBuilderTy Builder(CGM, VMContext);
4100 Builder.SetInsertPoint(EntryBB);
4102 llvm::FunctionType *FT =
4103 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4104 llvm::FunctionCallee Register =
4106 Builder.CreateCall(Register, module);
4108 if (!ClassAliases.empty()) {
4109 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4110 llvm::FunctionType *RegisterAliasTy =
4111 llvm::FunctionType::get(Builder.getVoidTy(),
4113 llvm::Function *RegisterAlias = llvm::Function::Create(
4115 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4117 llvm::BasicBlock *AliasBB =
4118 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4119 llvm::BasicBlock *NoAliasBB =
4120 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4123 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4124 llvm::Constant::getNullValue(RegisterAlias->getType()));
4125 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4128 Builder.SetInsertPoint(AliasBB);
4130 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4131 iter != ClassAliases.end(); ++iter) {
4132 llvm::Constant *TheClass =
4133 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4135 Builder.CreateCall(RegisterAlias,
4136 {TheClass, MakeConstantString(iter->second)});
4140 Builder.CreateBr(NoAliasBB);
4143 Builder.SetInsertPoint(NoAliasBB);
4145 Builder.CreateRetVoid();
4147 return LoadFunction;
4150llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4151 const ObjCContainerDecl *CD) {
4152 CodeGenTypes &Types = CGM.
getTypes();
4153 llvm::FunctionType *MethodTy =
4157 std::string FunctionName =
4158 getSymbolNameForMethod(OMD, !isDirect);
4161 return llvm::Function::Create(MethodTy,
4162 llvm::GlobalVariable::InternalLinkage,
4163 FunctionName, &TheModule);
4166 auto I = DirectMethodDefinitions.find(COMD);
4167 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
4169 if (I == DirectMethodDefinitions.end()) {
4171 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4172 FunctionName, &TheModule);
4173 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4190 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4192 Fn->takeName(OldFn);
4193 OldFn->replaceAllUsesWith(Fn);
4194 OldFn->eraseFromParent();
4201void CGObjCGNU::GenerateDirectMethodPrologue(CodeGenFunction &CGF,
4203 const ObjCMethodDecl *OMD,
4204 const ObjCContainerDecl *CD) {
4208llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4209 return GetPropertyFn;
4212llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4213 return SetPropertyFn;
4216llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4221llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4222 return GetStructPropertyFn;
4225llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4226 return SetStructPropertyFn;
4229llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4233llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4237llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4238 return EnumerationMutationFn;
4241void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF,
4242 const ObjCAtSynchronizedStmt &S) {
4243 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4247void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF,
4248 const ObjCAtTryStmt &S) {
4260 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4263void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
4264 const ObjCAtThrowStmt &S,
4265 bool ClearInsertionPoint) {
4266 llvm::Value *ExceptionAsObject;
4267 bool isRethrow =
false;
4271 ExceptionAsObject = Exception;
4274 "Unexpected rethrow outside @catch block.");
4278 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4287 Throw->setDoesNotReturn();
4289 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4290 llvm::CallBase *Throw =
4292 Throw->setDoesNotReturn();
4294 CGF.
Builder.CreateUnreachable();
4295 if (ClearInsertionPoint)
4296 CGF.
Builder.ClearInsertionPoint();
4299llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF,
4300 Address AddrWeakObj) {
4302 return B.CreateCall(
4303 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4306void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
4307 llvm::Value *src, Address dst) {
4309 src = EnforceType(B, src, IdTy);
4310 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4311 B.CreateCall(WeakAssignFn, {src, dstVal});
4314void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
4315 llvm::Value *src, Address dst,
4318 src = EnforceType(B, src, IdTy);
4319 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4321 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4322 B.CreateCall(GlobalAssignFn, {src, dstVal});
4325void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
4326 llvm::Value *src, Address dst,
4327 llvm::Value *ivarOffset) {
4329 src = EnforceType(B, src, IdTy);
4330 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), IdTy);
4331 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4334void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
4335 llvm::Value *src, Address dst) {
4337 src = EnforceType(B, src, IdTy);
4338 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4339 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4342void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
4345 llvm::Value *Size) {
4347 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4348 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4350 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4353llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4354 const ObjCInterfaceDecl *ID,
4355 const ObjCIvarDecl *Ivar) {
4356 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4360 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4361 if (!IvarOffsetPointer)
4362 IvarOffsetPointer =
new llvm::GlobalVariable(
4363 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4364 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4365 return IvarOffsetPointer;
4368LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF,
4370 llvm::Value *BaseValue,
4371 const ObjCIvarDecl *Ivar,
4372 unsigned CVRQualifiers) {
4373 const ObjCInterfaceDecl *
ID =
4374 ObjectTy->
castAs<ObjCObjectType>()->getInterface();
4375 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4376 EmitIvarOffset(CGF, ID, Ivar));
4395llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
4397 const ObjCIvarDecl *Ivar) {
4404 if (RuntimeVersion < 10 ||
4406 return CGF.
Builder.CreateZExtOrBitCast(
4410 llvm::PointerType::getUnqual(VMContext),
4411 ObjCIvarOffsetVariable(
Interface, Ivar),
4415 std::string
name =
"__objc_ivar_offset_value_" +
4418 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4420 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4421 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4422 llvm::Constant::getNullValue(IntTy), name);
4427 if (Offset->getType() != PtrDiffTy)
4428 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4432 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4438 switch (Runtime.getKind()) {
4440 if (Runtime.getVersion() >= VersionTuple(2, 0))
4441 return new CGObjCGNUstep2(CGM);
4442 return new CGObjCGNUstep(CGM);
4445 return new CGObjCGCC(CGM);
4448 return new CGObjCObjFW(CGM);
4454 llvm_unreachable(
"these runtimes are not GNU runtimes");
4456 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
QualType getObjCIdType() const
Represents the Objective-CC id type.
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.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
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 fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Implements runtime-specific code generation functions.
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...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
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...
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,...
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
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.
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
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
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, StringRef GlobalName=".str")
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.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
void add(llvm::Constant *value)
Add a new value to this initializer.
void addInt(llvm::IntegerType *intTy, uint64_t value, bool isSigned=false)
Add an integer value of a specific type.
void addNullPointer(llvm::PointerType *ptrTy)
Add a null pointer of a specific type.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
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.
llvm::Value * getPointer() const
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
const Expr * getThrowExpr() const
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryDecl * getCategoryDecl() const
const ObjCInterfaceDecl * getClassInterface() const
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
Represents an ObjC class declaration.
all_protocol_iterator all_referenced_protocol_end() const
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
all_protocol_iterator all_referenced_protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ImplicitParamDecl * getSelfDecl() const
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
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ 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.
std::string getAsString() const
Derive the full selector name (e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
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.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
StringRef getName(const HeaderType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Type
The name was classified as a type.
U cast(CodeGen::Address addr)
@ 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.
const half4 dst(half4 Src0, half4 Src1)
int const char * function
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const