clang: lib/CodeGen/CGObjCGNU.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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"
39#include
40
41using namespace clang;
42using namespace CodeGen;
43
44namespace {
45
46
47
48
49class LazyRuntimeFunction {
51 llvm::FunctionType *FTy = nullptr;
52 const char *FunctionName = nullptr;
53 llvm::FunctionCallee Function = nullptr;
54
55public:
56 LazyRuntimeFunction() = default;
57
58
59
60 template <typename... Tys>
61 void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy,
62 Tys *... Types) {
63 CGM = Mod;
64 FunctionName = name;
66 if(sizeof...(Tys)) {
68 FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
69 }
70 else {
71 FTy = llvm::FunctionType::get(RetTy, {}, false);
72 }
73 }
74
75 llvm::FunctionType *getType() { return FTy; }
76
77
78
79 operator llvm::FunctionCallee() {
80 if (!Function) {
81 if (!FunctionName)
82 return nullptr;
84 }
86 }
87};
88
89
90
91
92
94protected:
95
96 llvm::Module &TheModule;
97
98
99 llvm::StructType *ObjCSuperTy;
100
101
102 llvm::PointerType *PtrToObjCSuperTy;
103
104
105
106 llvm::PointerType *SelectorTy;
107
108 llvm::Type *SelectorElemTy;
109
110
111 llvm::IntegerType *Int8Ty;
112
113
114 llvm::PointerType *PtrToInt8Ty;
115
116 llvm::StructType *ProtocolTy;
117
118 llvm::PointerType *ProtocolPtrTy;
119
120
121
122
123
124 llvm::PointerType *IMPTy;
125
126
127
128
129 llvm::PointerType *IdTy;
130
131 llvm::Type *IdElemTy;
132
133
134 llvm::PointerType *PtrToIdTy;
135
136
138
139 llvm::IntegerType *IntTy;
140
141
142
143 llvm::PointerType *PtrTy;
144
145
146
147 llvm::IntegerType *LongTy;
148
149 llvm::IntegerType *SizeTy;
150
151 llvm::IntegerType *IntPtrTy;
152
153 llvm::IntegerType *PtrDiffTy;
154
155
156 llvm::PointerType *PtrToIntTy;
157
158 llvm::Type *BoolTy;
159
160 llvm::IntegerType *Int32Ty;
161
162 llvm::IntegerType *Int64Ty;
163
164 llvm::StructType *PropertyMetadataTy;
165
166
167
168 unsigned msgSendMDKind;
169
170
171 bool usesSEHExceptions;
172
173 bool usesCxxExceptions;
174
175
176 bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) {
178 return (R.getKind() == kind) &&
179 (R.getVersion() >= VersionTuple(major, minor));
180 }
181
182 std::string ManglePublicSymbol(StringRef Name) {
183 return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + Name).str();
184 }
185
186 std::string SymbolForProtocol(Twine Name) {
187 return (ManglePublicSymbol("OBJC_PROTOCOL_") + Name).str();
188 }
189
190 std::string SymbolForProtocolRef(StringRef Name) {
191 return (ManglePublicSymbol("OBJC_REF_PROTOCOL_") + Name).str();
192 }
193
194
195
196
197
198 llvm::Constant *MakeConstantString(StringRef Str, const char *Name = "") {
201 return Array.getPointer();
202 }
203
204
205
206
207
208 llvm::Constant *ExportUniqueString(const std::string &Str,
209 const std::string &prefix,
210 bool Private=false) {
211 std::string name = prefix + Str;
212 auto *ConstStr = TheModule.getGlobalVariable(name);
213 if (!ConstStr) {
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));
218 if (Private)
219 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
220 ConstStr = GV;
221 }
222 return ConstStr;
223 }
224
225
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);
239 }
241 }
242
243
245 const ObjCPropertyDecl *property, bool isSynthesized=true, bool
246 isDynamic=true) {
247 int attrs = property->getPropertyAttributes();
248
250 attrs &= ~ObjCPropertyAttribute::kind_copy;
251 attrs &= ~ObjCPropertyAttribute::kind_retain;
252 attrs &= ~ObjCPropertyAttribute::kind_weak;
253 attrs &= ~ObjCPropertyAttribute::kind_strong;
254 }
255
256 Fields.addInt(Int8Ty, attrs & 0xff);
257 attrs >>= 8;
258 attrs <<= 2;
259
260
261
262 attrs |= isSynthesized ? (1<<0) : 0;
263 attrs |= isDynamic ? (1<<1) : 0;
264
265
266 Fields.addInt(Int8Ty, attrs & 0xff);
267
268 Fields.addInt(Int8Ty, 0);
269 Fields.addInt(Int8Ty, 0);
270 }
271
272 virtual llvm::Constant *GenerateCategoryProtocolList(const
275 int count) {
276
277 Fields.addInt(IntTy, count);
278
280 const llvm::DataLayout &DL = TheModule.getDataLayout();
281 Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
283 }
284
285 Fields.add(NULLPtr);
286
287 return Fields.beginArray(PropertyMetadataTy);
288 }
291 const Decl *OCD,
292 bool isSynthesized=true, bool
293 isDynamic=true) {
294 auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy);
296 Fields.add(MakePropertyEncodingString(property, OCD));
297 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
298 auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) {
299 if (accessor) {
301 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
303 Fields.add(TypeEncoding);
304 } else {
305 Fields.add(NULLPtr);
306 Fields.add(NULLPtr);
307 }
308 };
312 }
313
314
315
316
317 llvm::Value *EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) {
318 if (V->getType() == Ty)
319 return V;
320 return B.CreateBitCast(V, Ty);
321 }
322
323
324 llvm::Constant *Zeros[2];
325
326 llvm::Constant *NULLPtr;
327
328 llvm::LLVMContext &VMContext;
329
330protected:
331
332
333
334
335
336 llvm::GlobalAlias *ClassPtrAlias;
337
338
339
340
341 llvm::GlobalAlias *MetaClassPtrAlias;
342
343 std::vectorllvm::Constant\* Classes;
344
345 std::vectorllvm::Constant\* Categories;
346
347
348 std::vectorllvm::Constant\* ConstantStrings;
349
350
351
352 llvm::StringMapllvm::Constant\* ObjCStrings;
353
354 llvm::StringMapllvm::Constant\* ExistingProtocols;
355
356
357
358
359
360 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
361
362
363
364 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
365 SelectorMap;
366
367
369
370
371
372 Selector RetainSel, ReleaseSel, AutoreleaseSel;
373
374
375
376 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377 WeakAssignFn, GlobalAssignFn;
378
379 typedef std::pair<std::string, std::string> ClassAliasPair;
380
381 std::vector ClassAliases;
382
383protected:
384
385 LazyRuntimeFunction ExceptionThrowFn;
386
387
388 LazyRuntimeFunction ExceptionReThrowFn;
389
390
391 LazyRuntimeFunction EnterCatchFn;
392
393
394 LazyRuntimeFunction ExitCatchFn;
395
396 LazyRuntimeFunction SyncEnterFn;
397
398 LazyRuntimeFunction SyncExitFn;
399
400private:
401
402
403 LazyRuntimeFunction EnumerationMutationFn;
404
405
406 LazyRuntimeFunction GetPropertyFn;
407
408
409 LazyRuntimeFunction SetPropertyFn;
410
411 LazyRuntimeFunction GetStructPropertyFn;
412
413 LazyRuntimeFunction SetStructPropertyFn;
414
415protected:
416
417
418 int RuntimeVersion;
419
420
421
422
423
424
425 const int ProtocolVersion;
426
427
428 const int ClassABIVersion;
429
430
431
432
438
439
440
441
442
443
444 llvm::Constant *GenerateMethodList(StringRef ClassName,
445 StringRef CategoryName,
447 bool isClassMethodList);
448
449
450
451
452 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
453
454
455
456 llvm::Constant *GeneratePropertyList(const Decl *Container,
458 bool isClassProperty=false,
459 bool protocolOptionalProperties=false);
460
461
462
464
465
466
467
468
469 void GenerateProtocolHolderCategory();
470
471
472 llvm::Constant *GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
475 unsigned info,
476 const char *Name,
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,
486 bool isMeta=false);
487
488
489
490 virtual llvm::Constant *GenerateProtocolMethodList(
492
493 template
494 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required,
498 for (const auto *I : Methods)
499 if (I->isOptional())
500 OptionalMethods.push_back(I);
501 else
502 RequiredMethods.push_back(I);
503 Required = GenerateProtocolMethodList(RequiredMethods);
504 Optional = GenerateProtocolMethodList(OptionalMethods);
505 }
506
507
508
510 const std::string &TypeEncoding);
511
512
513
514
515 virtual std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID,
517 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
519 return Name;
520 }
521
522 llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
524
525
526 void EmitClassRef(const std::string &className);
527
528
530 const std::string &Name, bool isWeak);
531
532
533
534
536 llvm::Value *&Receiver,
537 llvm::Value *cmd,
538 llvm::MDNode *node,
539 MessageSendInfo &MSI) = 0;
540
541
542
543
544 virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
546 llvm::Value *cmd,
547 MessageSendInfo &MSI) = 0;
548
549
550
551
552
553
554
555
556
557
558
559
561
562public:
563 CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
564 unsigned protocolClassVersion, unsigned classABI=1);
565
567
571 llvm::Value *Receiver, const CallArgList &CallArgs,
578 bool isCategoryImpl, llvm::Value *Receiver,
579 bool IsClassMessage, const CallArgList &CallArgs,
587 virtual llvm::Constant *GetConstantSelector(Selector Sel,
588 const std::string &TypeEncoding) {
589 llvm_unreachable("Runtime unable to generate constant selector");
590 }
591 llvm::Constant *GetConstantSelector(const ObjCMethodDecl *M) {
592 return GetConstantSelector(M->getSelector(),
594 }
596
599
600
601 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602 DirectMethodDefinitions;
612
614
617 }
618
623 bool copy) override;
629
636 bool ClearInsertionPoint=true) override;
638 Address AddrWeakObj) override;
640 llvm::Value *src, Address dst) override;
642 llvm::Value *src, Address dest,
643 bool threadlocal=false) override;
645 Address dest, llvm::Value *ivarOffset) override;
647 llvm::Value *src, Address dest) override;
650 llvm::Value *Size) override;
652 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
653 unsigned CVRQualifiers) override;
660 return NULLPtr;
661 }
664 return NULLPtr;
665 }
666
668 return NULLPtr;
669 }
670};
671
672
673
674
675
676
677
678
679
680class CGObjCGCC : public CGObjCGNU {
681
682
683 LazyRuntimeFunction MsgLookupFn;
684
685
686
687 LazyRuntimeFunction MsgLookupSuperFn;
688
689protected:
690 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
691 llvm::Value *cmd, llvm::MDNode *node,
692 MessageSendInfo &MSI) override {
694 llvm::Value *args[] = {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
699 return imp;
700 }
701
703 llvm::Value *cmd, MessageSendInfo &MSI) override {
705 llvm::Value *lookupArgs[] = {
706 EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy),
707 cmd};
709 }
710
711public:
712 CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
713
714 MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy);
715
716 MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
717 PtrToObjCSuperTy, SelectorTy);
718 }
719};
720
721
722class CGObjCGNUstep : public CGObjCGNU {
723
724
725 LazyRuntimeFunction SlotLookupFn;
726
727
728
729
730 LazyRuntimeFunction SlotLookupSuperFn;
731
732 LazyRuntimeFunction SetPropertyAtomic;
733
734 LazyRuntimeFunction SetPropertyAtomicCopy;
735
736 LazyRuntimeFunction SetPropertyNonAtomic;
737
738 LazyRuntimeFunction SetPropertyNonAtomicCopy;
739
740
741 LazyRuntimeFunction CxxAtomicObjectGetFn;
742
743
744 LazyRuntimeFunction CxxAtomicObjectSetFn;
745
746
747 llvm::Type *SlotTy;
748
749 llvm::Type *SlotStructTy;
750
751 public:
752 llvm::Constant *GetEHType(QualType T) override;
753
754 protected:
755 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
756 llvm::Value *cmd, llvm::MDNode *node,
757 MessageSendInfo &MSI) override {
759 llvm::FunctionCallee LookupFn = SlotLookupFn;
760
761
764 Builder.CreateStore(Receiver, ReceiverPtr);
765
766 llvm::Value *self;
767
768 if (isa(CGF.CurCodeDecl)) {
770 } else {
771 self = llvm::ConstantPointerNull::get(IdTy);
772 }
773
774
775 if (auto *LookupFn2 = dyn_castllvm::Function(LookupFn.getCallee()))
776 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
777
778 llvm::Value *args[] = {
779 EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy),
780 EnforceType(Builder, cmd, SelectorTy),
781 EnforceType(Builder, self, IdTy)};
783 slot->setOnlyReadsMemory();
784 slot->setMetadata(msgSendMDKind, node);
785
786
787 llvm::Value *imp = Builder.CreateAlignedLoad(
788 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
790
791
792
793 Receiver = Builder.CreateLoad(ReceiverPtr, true);
794 return imp;
795 }
796
798 llvm::Value *cmd,
799 MessageSendInfo &MSI) override {
801 llvm::Value *lookupArgs[] = {ObjCSuper.emitRawPointer(CGF), cmd};
802
803 llvm::CallInst *slot =
805 slot->setOnlyReadsMemory();
806
807 return Builder.CreateAlignedLoad(
808 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
810 }
811
812 public:
813 CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
814 CGObjCGNUstep(CodeGenModule &Mod, unsigned ABI, unsigned ProtocolABI,
815 unsigned ClassABI) :
816 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
818
819 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
820 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
821
822 SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy,
823 SelectorTy, IdTy);
824
825 SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
826 PtrToObjCSuperTy, SelectorTy);
827
828 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
829 if (usesCxxExceptions) {
830
831 EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
832
833 ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy);
834
835 ExceptionReThrowFn.init(&CGM, "__cxa_rethrow", PtrTy);
836 } else if (usesSEHExceptions) {
837
838 ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy);
839 } else if (CGM.getLangOpts().CPlusPlus) {
840
841 EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
842
843 ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy);
844
845 ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
846 PtrTy);
847 } else if (R.getVersion() >= VersionTuple(1, 7)) {
848
849 EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy);
850
851 ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy);
852
853 ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, PtrTy);
854 }
855 SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
856 SelectorTy, IdTy, PtrDiffTy);
857 SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
858 IdTy, SelectorTy, IdTy, PtrDiffTy);
859 SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy,
860 IdTy, SelectorTy, IdTy, PtrDiffTy);
861 SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy",
862 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
863
864
865 CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy,
866 PtrTy, PtrTy);
867
868
869 CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy,
870 PtrTy, PtrTy);
871 }
872
873 llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {
874
875
877 VersionTuple(1, 7));
878 return CxxAtomicObjectGetFn;
879 }
880
881 llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {
882
883
885 VersionTuple(1, 7));
886 return CxxAtomicObjectSetFn;
887 }
888
889 llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
890 bool copy) override {
891
892
893
894 assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC));
895
896
898 VersionTuple(1, 7));
899
900 if (atomic) {
901 if (copy) return SetPropertyAtomicCopy;
902 return SetPropertyAtomic;
903 }
904
905 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
906 }
907};
908
909
910
911
912class CGObjCGNUstep2 : public CGObjCGNUstep {
913 enum SectionKind
914 {
915 SelectorSection = 0,
916 ClassSection,
917 ClassReferenceSection,
918 CategorySection,
919 ProtocolSection,
920 ProtocolReferenceSection,
921 ClassAliasSection,
922 ConstantStringSection
923 };
924
925 enum ClassFlags {
926
927 ClassFlagMeta = (1 << 0),
928
929
930 ClassFlagInitialized = (1 << 8),
931 };
932 static const char *const SectionsBaseNames[8];
933 static const char *const PECOFFSectionsBaseNames[8];
934 template
935 std::string sectionName() {
936 if (CGM.getTriple().isOSBinFormatCOFF()) {
937 std::string name(PECOFFSectionsBaseNames[K]);
938 name += "$m";
940 }
941 return SectionsBaseNames[K];
942 }
943
944
945
946 LazyRuntimeFunction MsgLookupSuperFn;
947
948 LazyRuntimeFunction SentInitializeFn;
949
950
951
952 bool EmittedProtocol = false;
953
954
955
956
957 bool EmittedProtocolRef = false;
958
959
960
961 bool EmittedClass = false;
962
963
964
965 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
966 EarlyInitPair;
967 std::vector EarlyInitList;
968
969 std::string SymbolForClassRef(StringRef Name, bool isWeak) {
970 if (isWeak)
971 return (ManglePublicSymbol("OBJC_WEAK_REF_CLASS_") + Name).str();
972 else
973 return (ManglePublicSymbol("OBJC_REF_CLASS_") + Name).str();
974 }
975
976 std::string SymbolForClass(StringRef Name) {
977 return (ManglePublicSymbol("OBJC_CLASS_") + Name).str();
978 }
979 void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName,
982 for (auto *Arg : Args)
983 Types.push_back(Arg->getType());
984 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
985 false);
987 B.CreateCall(Fn, Args);
988 }
989
991
994
995
996 llvm::StringMapllvm::Constant\*::iterator old = ObjCStrings.find(Str);
997 if (old != ObjCStrings.end())
998 return ConstantAddress(old->getValue(), IdElemTy, Align);
999
1001
1002 auto LiteralLength = SL->getLength();
1003
1005 (LiteralLength < 9) && !isNonASCII) {
1006
1007
1008
1010
1011 for (unsigned i=0 ; i<LiteralLength ; i++)
1012 str |= ((uint64_t)SL->getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1013
1014 str |= LiteralLength << 3;
1015
1016 str |= 4;
1017 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1018 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1019 ObjCStrings[Str] = ObjCStr;
1021 }
1022
1024
1025 if (StringClass.empty()) StringClass = "NSConstantString";
1026
1027 std::string Sym = SymbolForClass(StringClass);
1028
1029 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
1030
1031 if (!isa) {
1032 isa = new llvm::GlobalVariable(TheModule, IdTy, false,
1033 llvm::GlobalValue::ExternalLinkage, nullptr, Sym);
1034 if (CGM.getTriple().isOSBinFormatCOFF()) {
1035 castllvm::GlobalValue(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1036 }
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1050 auto Fields = Builder.beginStruct();
1051 if (!CGM.getTriple().isOSBinFormatCOFF()) {
1052 Fields.add(isa);
1053 } else {
1054 Fields.addNullPointer(PtrTy);
1055 }
1056
1057
1058
1059
1060 if (isNonASCII) {
1061 unsigned NumU8CodeUnits = Str.size();
1062
1063
1064
1066 const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)Str.data();
1067 llvm::UTF16 *ToPtr = &ToBuf[0];
1068 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1069 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1070 uint32_t StringLength = ToPtr - &ToBuf[0];
1071
1072 *ToPtr = 0;
1073
1074 Fields.addInt(Int32Ty, 2);
1075
1076 Fields.addInt(Int32Ty, StringLength);
1077
1078 Fields.addInt(Int32Ty, StringLength * 2);
1079
1080 Fields.addInt(Int32Ty, 0);
1081
1083 auto *C = llvm::ConstantDataArray::get(VMContext, Arr);
1084 auto *Buffer = new llvm::GlobalVariable(TheModule, C->getType(),
1085 true, llvm::GlobalValue::PrivateLinkage, C, ".str");
1086 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1087 Fields.add(Buffer);
1088 } else {
1089
1090 Fields.addInt(Int32Ty, 0);
1091
1092 Fields.addInt(Int32Ty, Str.size());
1093
1094 Fields.addInt(Int32Ty, Str.size());
1095
1096 Fields.addInt(Int32Ty, 0);
1097
1098 Fields.add(MakeConstantString(Str));
1099 }
1100 std::string StringName;
1101 bool isNamed = !isNonASCII;
1103 StringName = ".objc_str_";
1104 for (int i=0,e=Str.size() ; i<e ; ++i) {
1105 unsigned char c = Str[i];
1106 if (isalnum(c))
1107 StringName += c;
1108 else if (c == ' ')
1109 StringName += '_';
1110 else {
1112 break;
1113 }
1114 }
1115 }
1116 llvm::GlobalVariable *ObjCStrGV =
1118 isNamed ? StringRef(StringName) : ".objc_string",
1119 Align, false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1120 : llvm::GlobalValue::PrivateLinkage);
1121 ObjCStrGV->setSection(sectionName());
1123 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1124 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1125 }
1126 if (CGM.getTriple().isOSBinFormatCOFF()) {
1127 std::pair<llvm::GlobalVariable*, int> v{ObjCStrGV, 0};
1128 EarlyInitList.emplace_back(Sym, v);
1129 }
1130 ObjCStrings[Str] = ObjCStrGV;
1131 ConstantStrings.push_back(ObjCStrGV);
1133 }
1134
1137 const Decl *OCD,
1138 bool isSynthesized=true, bool
1139 isDynamic=true) override {
1140
1141
1142
1143
1144
1145
1146
1147
1148 auto Fields = PropertiesArray.beginStruct(PropertyMetadataTy);
1150 Fields.add(MakeConstantString(property->getNameAsString()));
1151 std::string TypeStr =
1153 Fields.add(MakeConstantString(TypeStr));
1154 std::string typeStr;
1156 Fields.add(MakeConstantString(typeStr));
1157 auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) {
1158 if (accessor) {
1160 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1161 } else {
1162 Fields.add(NULLPtr);
1163 }
1164 };
1168 }
1169
1170 llvm::Constant *
1172
1173
1174
1175
1176
1177 llvm::StructType *ObjCMethodDescTy =
1179 { PtrToInt8Ty, PtrToInt8Ty });
1182
1183
1184
1185
1186
1187
1188 auto MethodList = Builder.beginStruct();
1189
1190 MethodList.addInt(IntTy, Methods.size());
1191
1192 const llvm::DataLayout &DL = TheModule.getDataLayout();
1193 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1195
1196 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1197 for (auto *M : Methods) {
1198 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1199 Method.add(CGObjCGNU::GetConstantSelector(M));
1201 Method.finishAndAddTo(MethodArray);
1202 }
1203 MethodArray.finishAndAddTo(MethodList);
1204 return MethodList.finishAndCreateGlobal(".objc_protocol_method_list",
1206 }
1207 llvm::Constant *GenerateCategoryProtocolList(const ObjCCategoryDecl *OCD)
1208 override {
1210 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1211 ReferencedProtocols.end());
1213 for (const auto *PI : RuntimeProtocols)
1214 Protocols.push_back(GenerateProtocolRef(PI));
1215 return GenerateProtocolList(Protocols);
1216 }
1217
1219 llvm::Value *cmd, MessageSendInfo &MSI) override {
1220
1222 llvm::Value *lookupArgs[] = {
1223 CGObjCGNU::EnforceType(Builder, ObjCSuper.emitRawPointer(CGF),
1224 PtrToObjCSuperTy),
1225 cmd};
1227 }
1228
1229 llvm::GlobalVariable *GetClassVar(StringRef Name, bool isWeak=false) {
1230 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1231 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1232 if (ClassSymbol)
1233 return ClassSymbol;
1234 ClassSymbol = new llvm::GlobalVariable(TheModule,
1235 IdTy, false, llvm::GlobalValue::ExternalLinkage,
1236 nullptr, SymbolName);
1237
1238
1239
1240
1241 if (isWeak)
1242 ClassSymbol->setInitializer(new llvm::GlobalVariable(TheModule,
1243 Int8Ty, false, llvm::GlobalValue::ExternalWeakLinkage,
1244 nullptr, SymbolForClass(Name)));
1245 else {
1246 if (CGM.getTriple().isOSBinFormatCOFF()) {
1250
1252 for (const auto *Result : DC->lookup(&II))
1253 if ((OID = dyn_cast(Result)))
1254 break;
1255
1256
1257
1258
1259 assert(OID && "Failed to find ObjCInterfaceDecl");
1261 if (OIDDef != nullptr)
1262 OID = OIDDef;
1263
1264 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1265 if (OID->hasAttr())
1266 Storage = llvm::GlobalValue::DLLImportStorageClass;
1267 else if (OID->hasAttr())
1268 Storage = llvm::GlobalValue::DLLExportStorageClass;
1269
1270 castllvm::GlobalValue(ClassSymbol)->setDLLStorageClass(Storage);
1271 }
1272 }
1273 assert(ClassSymbol->getName() == SymbolName);
1274 return ClassSymbol;
1275 }
1277 const std::string &Name,
1278 bool isWeak) override {
1281 }
1283
1284
1285
1286
1287
1288
1289 int Flag;
1290 switch (Ownership) {
1292 Flag = 1;
1293 break;
1295 Flag = 2;
1296 break;
1298 Flag = 3;
1299 break;
1303 Flag = 0;
1304 }
1305 return Flag;
1306 }
1312 llvm_unreachable("Method should not be called!");
1313 }
1314
1315 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName) override {
1316 std::string Name = SymbolForProtocol(ProtocolName);
1317 auto *GV = TheModule.getGlobalVariable(Name);
1318 if (!GV) {
1319
1320 GV = new llvm::GlobalVariable(TheModule, ProtocolTy, false,
1321 llvm::GlobalValue::ExternalLinkage, nullptr, Name);
1323 }
1324 return GV;
1325 }
1326
1327
1328 llvm::StringMapllvm::Constant\* ExistingProtocolRefs;
1329
1333 auto *&Ref = ExistingProtocolRefs[Name];
1334 if (!Ref) {
1335 auto *&Protocol = ExistingProtocols[Name];
1336 if (!Protocol)
1337 Protocol = GenerateProtocolRef(PD);
1338 std::string RefName = SymbolForProtocolRef(Name);
1339 assert(!TheModule.getGlobalVariable(RefName));
1340
1341 auto GV = new llvm::GlobalVariable(TheModule, ProtocolPtrTy, false,
1342 llvm::GlobalValue::LinkOnceODRLinkage,
1343 Protocol, RefName);
1344 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1345 GV->setSection(sectionName());
1347 Ref = GV;
1348 }
1349 EmittedProtocolRef = true;
1352 }
1353
1355 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1356 Protocols.size());
1357 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1358 Protocols);
1360 auto ProtocolBuilder = builder.beginStruct();
1361 ProtocolBuilder.addNullPointer(PtrTy);
1362 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1363 ProtocolBuilder.add(ProtocolArray);
1364 return ProtocolBuilder.finishAndCreateGlobal(".objc_protocol_list",
1365 CGM.getPointerAlign(), false, llvm::GlobalValue::InternalLinkage);
1366 }
1367
1368 void GenerateProtocol(const ObjCProtocolDecl *PD) override {
1369
1370 }
1371 llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) override {
1373 auto *&Protocol = ExistingProtocols[ProtocolName];
1374 if (Protocol)
1376
1377 EmittedProtocol = true;
1378
1379 auto SymName = SymbolForProtocol(ProtocolName);
1380 auto *OldGV = TheModule.getGlobalVariable(SymName);
1381
1382
1384 PD = Def;
1385 else {
1386
1387
1388
1389 assert(!OldGV);
1390 Protocol = new llvm::GlobalVariable(TheModule, ProtocolTy,
1391 false,
1392 llvm::GlobalValue::ExternalLinkage, nullptr, SymName);
1394 }
1395
1397 auto RuntimeProtocols =
1399 for (const auto *PI : RuntimeProtocols)
1400 Protocols.push_back(GenerateProtocolRef(PI));
1401 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1402
1403
1404 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1405 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1406 EmitProtocolMethodList(PD->instance_methods(), InstanceMethodList,
1407 OptionalInstanceMethodList);
1408 EmitProtocolMethodList(PD->class_methods(), ClassMethodList,
1409 OptionalClassMethodList);
1410
1411
1412
1414 auto ProtocolBuilder = builder.beginStruct();
1415 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1416 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1417 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1418 ProtocolBuilder.add(ProtocolList);
1419 ProtocolBuilder.add(InstanceMethodList);
1420 ProtocolBuilder.add(ClassMethodList);
1421 ProtocolBuilder.add(OptionalInstanceMethodList);
1422 ProtocolBuilder.add(OptionalClassMethodList);
1423
1424 ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, false));
1425
1426 ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, false, true));
1427
1428 ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, false));
1429
1430 ProtocolBuilder.add(GeneratePropertyList(nullptr, PD, true, true));
1431
1432 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1433 CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage);
1434 GV->setSection(sectionName());
1435 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1436 if (OldGV) {
1437 OldGV->replaceAllUsesWith(GV);
1438 OldGV->removeFromParent();
1439 GV->setName(SymName);
1440 }
1442 return GV;
1443 }
1445 const std::string &TypeEncoding) override {
1446 return GetConstantSelector(Sel, TypeEncoding);
1447 }
1448 std::string GetSymbolNameForTypeEncoding(const std::string &TypeEncoding) {
1449 std::string MangledTypes = std::string(TypeEncoding);
1450
1451
1452
1453
1454 if (CGM.getTriple().isOSBinFormatELF())
1455 std::replace(MangledTypes.begin(), MangledTypes.end(), '@', '\1');
1456
1457 if (CGM.getTriple().isOSWindows())
1458 std::replace(MangledTypes.begin(), MangledTypes.end(), '=', '\2');
1459 return MangledTypes;
1460 }
1461 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1462 if (TypeEncoding.empty())
1463 return NULLPtr;
1464 std::string MangledTypes =
1465 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1466 std::string TypesVarName = ".objc_sel_types_" + MangledTypes;
1467 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1468 if (!TypesGlobal) {
1469 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1470 TypeEncoding);
1471 auto *GV = new llvm::GlobalVariable(TheModule, Init->getType(),
1472 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1473 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1474 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1475 TypesGlobal = GV;
1476 }
1477 return TypesGlobal;
1478 }
1479 llvm::Constant *GetConstantSelector(Selector Sel,
1480 const std::string &TypeEncoding) override {
1481 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1482 auto SelVarName = (StringRef(".objc_selector_") + Sel.getAsString() + "_" +
1483 MangledTypes).str();
1484 if (auto *GV = TheModule.getNamedGlobal(SelVarName))
1485 return GV;
1487 auto SelBuilder = builder.beginStruct();
1488 SelBuilder.add(ExportUniqueString(Sel.getAsString(), ".objc_sel_name_",
1489 true));
1490 SelBuilder.add(GetTypeString(TypeEncoding));
1491 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1492 CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
1493 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1494 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1495 GV->setSection(sectionName());
1496 return GV;
1497 }
1498 llvm::StructType *emptyStruct = nullptr;
1499
1500
1501
1502
1503
1504
1505
1506
1507 std::pairllvm::Constant\*,llvm::Constant\*
1508 GetSectionBounds(StringRef Section) {
1509 if (CGM.getTriple().isOSBinFormatCOFF()) {
1510 if (emptyStruct == nullptr) {
1511 emptyStruct = llvm::StructType::create(
1512 VMContext, {}, ".objc_section_sentinel", true);
1513 }
1514 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1515 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1516 auto *Sym = new llvm::GlobalVariable(TheModule, emptyStruct,
1517 false,
1518 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1519 Section);
1520 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1521 Sym->setSection((Section + SecSuffix).str());
1522 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1523 Section).str()));
1525 return Sym;
1526 };
1527 return { Sym("__start_", "$a"), Sym("__stop", "$z") };
1528 }
1529 auto *Start = new llvm::GlobalVariable(TheModule, PtrTy,
1530 false,
1531 llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__start_") +
1532 Section);
1533 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1534 auto *Stop = new llvm::GlobalVariable(TheModule, PtrTy,
1535 false,
1536 llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__stop_") +
1537 Section);
1538 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1539 return { Start, Stop };
1540 }
1543 }
1544 llvm::Function *ModuleInitFunction() override {
1545 llvm::Function *LoadFunction = llvm::Function::Create(
1546 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
1547 llvm::GlobalValue::LinkOnceODRLinkage, ".objcv2_load_function",
1548 &TheModule);
1549 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1550 LoadFunction->setComdat(TheModule.getOrInsertComdat(".objcv2_load_function"));
1551
1552 llvm::BasicBlock *EntryBB =
1553 llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
1555 B.SetInsertPoint(EntryBB);
1557 auto InitStructBuilder = builder.beginStruct();
1558 InitStructBuilder.addInt(Int64Ty, 0);
1559 auto §ionVec = CGM.getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1560 for (auto *s : sectionVec) {
1561 auto bounds = GetSectionBounds(s);
1562 InitStructBuilder.add(bounds.first);
1563 InitStructBuilder.add(bounds.second);
1564 }
1565 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init",
1566 CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
1567 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1568 InitStruct->setComdat(TheModule.getOrInsertComdat(".objc_init"));
1569
1570 CallRuntimeFunction(B, "__objc_load", {InitStruct});;
1571 B.CreateRetVoid();
1572
1574
1575
1576
1577 auto *InitVar = new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1578 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1579 LoadFunction, ".objc_ctor");
1580
1581
1582 assert(InitVar->getName() == ".objc_ctor");
1583
1584
1585
1586
1587
1588 if (CGM.getTriple().isOSBinFormatCOFF())
1589 InitVar->setSection(".CRT$XCLz");
1590 else
1591 {
1593 InitVar->setSection(".init_array");
1594 else
1595 InitVar->setSection(".ctors");
1596 }
1597 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1598 InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor"));
1600 for (auto *C : Categories) {
1601 auto *Cat = castllvm::GlobalVariable(C->stripPointerCasts());
1602 Cat->setSection(sectionName());
1604 }
1606 StringRef Section) {
1607 auto nullBuilder = builder.beginStruct();
1608 for (auto *F : Init)
1609 nullBuilder.add(F);
1610 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.getPointerAlign(),
1611 false, llvm::GlobalValue::LinkOnceODRLinkage);
1612 GV->setSection(Section);
1613 GV->setComdat(TheModule.getOrInsertComdat(Name));
1614 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1616 return GV;
1617 };
1618 for (auto clsAlias : ClassAliases)
1619 createNullGlobal(std::string(".objc_class_alias") +
1620 clsAlias.second, { MakeConstantString(clsAlias.second),
1621 GetClassVar(clsAlias.first) }, sectionName());
1622
1623
1624
1625
1626 if (!CGM.getTriple().isOSBinFormatCOFF()) {
1627 createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr},
1628 sectionName());
1629 if (Categories.empty())
1630 createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr,
1631 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1632 sectionName());
1633 if (!EmittedClass) {
1634 createNullGlobal(".objc_null_cls_init_ref", NULLPtr,
1635 sectionName());
1636 createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
1637 sectionName());
1638 }
1639 if (!EmittedProtocol)
1640 createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1641 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1642 NULLPtr}, sectionName());
1643 if (!EmittedProtocolRef)
1644 createNullGlobal(".objc_null_protocol_ref", {NULLPtr},
1645 sectionName());
1646 if (ClassAliases.empty())
1647 createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr },
1648 sectionName());
1649 if (ConstantStrings.empty()) {
1650 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1651 createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero,
1652 i32Zero, i32Zero, i32Zero, NULLPtr },
1653 sectionName());
1654 }
1655 }
1656 ConstantStrings.clear();
1657 Categories.clear();
1658 Classes.clear();
1659
1660 if (EarlyInitList.size() > 0) {
1661 auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy,
1662 {}), llvm::GlobalValue::InternalLinkage, ".objc_early_init",
1664 llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",
1666 for (const auto &lateInit : EarlyInitList) {
1667 auto *global = TheModule.getGlobalVariable(lateInit.first);
1668 if (global) {
1669 llvm::GlobalVariable *GV = lateInit.second.first;
1670 b.CreateAlignedStore(
1671 global,
1672 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1674 }
1675 }
1676 b.CreateRetVoid();
1677
1678
1679 auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
1680 true, llvm::GlobalValue::InternalLinkage,
1681 Init, ".objc_early_init_ptr");
1682 InitVar->setSection(".CRT$XCLb");
1684 }
1685 return nullptr;
1686 }
1687
1688
1689 std::string GetIVarOffsetVariableName(const ObjCInterfaceDecl *ID,
1691 std::string TypeEncoding;
1693 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1694 const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
1696 return Name;
1697 }
1703 const std::string Name =
1704 GetIVarOffsetVariableName(ContainingInterface, Ivar);
1705 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1706 if (!IvarOffsetPointer) {
1707 IvarOffsetPointer = new llvm::GlobalVariable(TheModule, IntTy, false,
1708 llvm::GlobalValue::ExternalLinkage, nullptr, Name);
1711 CGM.setGVProperties(IvarOffsetPointer, ContainingInterface);
1712 }
1714 llvm::Value *Offset =
1716 if (Offset->getType() != PtrDiffTy)
1717 Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1718 return Offset;
1719 }
1722 bool IsCOFF = CGM.getTriple().isOSBinFormatCOFF();
1723
1724
1728 auto *classNameConstant = MakeConstantString(className);
1729
1731 auto metaclassFields = builder.beginStruct();
1732
1733 metaclassFields.addNullPointer(PtrTy);
1734
1735 metaclassFields.addNullPointer(PtrTy);
1736
1737 metaclassFields.add(classNameConstant);
1738
1739 metaclassFields.addInt(LongTy, 0);
1740
1741
1742 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1743
1744
1745
1746 metaclassFields.addInt(LongTy, 0);
1747
1748 metaclassFields.addNullPointer(PtrTy);
1749
1750
1751
1753 metaclassFields.addNullPointer(PtrTy);
1754 else {
1756 ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(),
1758 metaclassFields.add(
1759 GenerateMethodList(className, "", ClassMethods, true));
1760 }
1761
1762 metaclassFields.addNullPointer(PtrTy);
1763
1764 metaclassFields.addNullPointer(PtrTy);
1765
1766 metaclassFields.addNullPointer(PtrTy);
1767
1768 metaclassFields.addNullPointer(PtrTy);
1769
1770 metaclassFields.addNullPointer(PtrTy);
1771
1772 metaclassFields.addNullPointer(PtrTy);
1773
1774 metaclassFields.addNullPointer(PtrTy);
1775
1776 metaclassFields.addInt(LongTy, 0);
1777
1778 metaclassFields.add(GeneratePropertyList(OID, classDecl, true));
1779
1780 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1781 ManglePublicSymbol("OBJC_METACLASS_") + className,
1783
1784 auto classFields = builder.beginStruct();
1785
1786 classFields.add(metaclass);
1787
1788
1791 llvm::Constant *SuperClass = nullptr;
1792 if (SuperClassDecl) {
1793 auto SuperClassName = SymbolForClass(SuperClassDecl->getNameAsString());
1794 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1795 if (!SuperClass)
1796 {
1797 SuperClass = new llvm::GlobalVariable(TheModule, PtrTy, false,
1798 llvm::GlobalValue::ExternalLinkage, nullptr, SuperClassName);
1799 if (IsCOFF) {
1800 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1801 if (SuperClassDecl->hasAttr())
1802 Storage = llvm::GlobalValue::DLLImportStorageClass;
1803 else if (SuperClassDecl->hasAttr())
1804 Storage = llvm::GlobalValue::DLLExportStorageClass;
1805
1806 castllvm::GlobalValue(SuperClass)->setDLLStorageClass(Storage);
1807 }
1808 }
1809 if (!IsCOFF)
1810 classFields.add(SuperClass);
1811 else
1812 classFields.addNullPointer(PtrTy);
1813 } else
1814 classFields.addNullPointer(PtrTy);
1815
1816 classFields.add(classNameConstant);
1817
1818 classFields.addInt(LongTy, 0);
1819
1820
1821 classFields.addInt(LongTy, 0);
1822
1823 int superInstanceSize = !SuperClassDecl ? 0 :
1825
1826
1827 classFields.addInt(LongTy,
1829 superInstanceSize));
1830
1832 classFields.addNullPointer(PtrTy);
1833 else {
1834 int ivar_count = 0;
1837 const llvm::DataLayout &DL = TheModule.getDataLayout();
1838
1840 auto ivarListBuilder = b.beginStruct();
1841
1842 ivarListBuilder.addInt(IntTy, ivar_count);
1843
1844 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1845 PtrToInt8Ty,
1846 PtrToInt8Ty,
1847 PtrToInt8Ty,
1848 Int32Ty,
1849 Int32Ty);
1850 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1852
1853 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1856 auto ivarTy = IVD->getType();
1857 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1858
1859 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1860
1861 std::string TypeStr;
1862
1864 ivarBuilder.add(MakeConstantString(TypeStr));
1865
1866 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1867 uint64_t Offset = BaseOffset - superInstanceSize;
1868 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1869 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1870 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1871 if (OffsetVar)
1872 OffsetVar->setInitializer(OffsetValue);
1873 else
1874 OffsetVar = new llvm::GlobalVariable(TheModule, IntTy,
1875 false, llvm::GlobalValue::ExternalLinkage,
1876 OffsetValue, OffsetName);
1877 auto ivarVisibility =
1881 llvm::GlobalValue::HiddenVisibility :
1882 llvm::GlobalValue::DefaultVisibility;
1883 OffsetVar->setVisibility(ivarVisibility);
1884 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1886 ivarBuilder.add(OffsetVar);
1887
1888 ivarBuilder.addInt(Int32Ty,
1890
1891 unsigned align =
1893
1894 assert(align < 64);
1895
1896
1897
1898
1899 ivarBuilder.addInt(Int32Ty,
1900 (align << 3) | (1<<2) |
1901 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1902 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1903 }
1904 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1905 auto ivarList = ivarListBuilder.finishAndCreateGlobal(".objc_ivar_list",
1907 llvm::GlobalValue::PrivateLinkage);
1908 classFields.add(ivarList);
1909 }
1910
1912 InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(),
1915 if (propImpl->getPropertyImplementation() ==
1918 if (OMD && OMD->hasBody())
1919 InstanceMethods.push_back(OMD);
1920 };
1921 addIfExists(propImpl->getGetterMethodDecl());
1922 addIfExists(propImpl->getSetterMethodDecl());
1923 }
1924
1925 if (InstanceMethods.size() == 0)
1926 classFields.addNullPointer(PtrTy);
1927 else
1928 classFields.add(
1929 GenerateMethodList(className, "", InstanceMethods, false));
1930
1931
1932 classFields.addNullPointer(PtrTy);
1933
1934 classFields.addNullPointer(PtrTy);
1935
1936 classFields.addNullPointer(PtrTy);
1937
1938 classFields.addNullPointer(PtrTy);
1939
1940 classFields.addNullPointer(PtrTy);
1941
1942 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->protocol_begin(),
1945 for (const auto *I : RuntimeProtocols)
1946 Protocols.push_back(GenerateProtocolRef(I));
1947
1948 if (Protocols.empty())
1949 classFields.addNullPointer(PtrTy);
1950 else
1951 classFields.add(GenerateProtocolList(Protocols));
1952
1953 classFields.addNullPointer(PtrTy);
1954
1955 classFields.addInt(LongTy, 0);
1956
1957 classFields.add(GeneratePropertyList(OID, classDecl));
1958
1959 llvm::GlobalVariable *classStruct =
1960 classFields.finishAndCreateGlobal(SymbolForClass(className),
1961 CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage);
1962
1963 auto *classRefSymbol = GetClassVar(className);
1964 classRefSymbol->setSection(sectionName());
1965 classRefSymbol->setInitializer(classStruct);
1966
1967 if (IsCOFF) {
1968
1970 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1971 castllvm::GlobalValue(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1972 }
1973
1974 if (SuperClass) {
1975 std::pair<llvm::GlobalVariable*, int> v{classStruct, 1};
1976 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1977 std::move(v));
1978 }
1979
1980 }
1981
1982
1983
1984
1985 if (ClassPtrAlias) {
1986 ClassPtrAlias->replaceAllUsesWith(classStruct);
1987 ClassPtrAlias->eraseFromParent();
1988 ClassPtrAlias = nullptr;
1989 }
1990 if (auto Placeholder =
1991 TheModule.getNamedGlobal(SymbolForClass(className)))
1992 if (Placeholder != classStruct) {
1993 Placeholder->replaceAllUsesWith(classStruct);
1994 Placeholder->eraseFromParent();
1995 classStruct->setName(SymbolForClass(className));
1996 }
1997 if (MetaClassPtrAlias) {
1998 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1999 MetaClassPtrAlias->eraseFromParent();
2000 MetaClassPtrAlias = nullptr;
2001 }
2002 assert(classStruct->getName() == SymbolForClass(className));
2003
2004 auto classInitRef = new llvm::GlobalVariable(TheModule,
2005 classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage,
2006 classStruct, ManglePublicSymbol("OBJC_INIT_CLASS_") + className);
2007 classInitRef->setSection(sectionName());
2009
2010 EmittedClass = true;
2011 }
2012 public:
2013 CGObjCGNUstep2(CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2014 MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
2015 PtrToObjCSuperTy, SelectorTy);
2016 SentInitializeFn.init(&CGM, "objc_send_initialize",
2017 llvm::Type::getVoidTy(VMContext), IdTy);
2018
2019
2020
2021
2022
2023
2024
2025
2026 PropertyMetadataTy =
2028 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2029 }
2030
2031 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
2034 auto &Builder = CGF.Builder;
2035 bool ReceiverCanBeNull = true;
2037 auto selfValue = Builder.CreateLoad(selfAddr);
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2058
2059
2060
2061
2062 ReceiverCanBeNull = isWeakLinkedClass(OID);
2063 }
2064
2066 if (ReceiverCanBeNull) {
2067 llvm::BasicBlock *SelfIsNilBlock =
2069 llvm::BasicBlock *ContBlock =
2071
2072
2073 auto selfTy = castllvm::PointerType(selfValue->getType());
2074 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2075
2076 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2077 SelfIsNilBlock, ContBlock,
2078 MDHelper.createUnlikelyBranchWeights());
2079
2081
2082
2084 Builder.SetInsertPoint(SelfIsNilBlock);
2085 if (!retTy->isVoidType()) {
2087 }
2089
2090
2091
2093 Builder.SetInsertPoint(ContBlock);
2094 }
2095
2097
2098 auto *classStart =
2099 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2100 auto &astContext = CGM.getContext();
2101
2102
2103
2104
2105
2106 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2108 astContext.getTypeAlign(astContext.UnsignedLongTy));
2109 auto flags = Builder.CreateLoad(Address{Val, LongTy, Align});
2110 auto isInitialized =
2111 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2112 llvm::BasicBlock *notInitializedBlock =
2113 CGF.createBasicBlock("objc_direct_method.class_uninitialized");
2114 llvm::BasicBlock *initializedBlock =
2115 CGF.createBasicBlock("objc_direct_method.class_initialized");
2116 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2117 notInitializedBlock, initializedBlock,
2118 MDHelper.createUnlikelyBranchWeights());
2119 CGF.EmitBlock(notInitializedBlock);
2120 Builder.SetInsertPoint(notInitializedBlock);
2122 Builder.CreateBr(initializedBlock);
2123 CGF.EmitBlock(initializedBlock);
2124 Builder.SetInsertPoint(initializedBlock);
2125 }
2126
2127
2129
2130
2132 Builder.CreateStore(GetSelector(CGF, OMD),
2134 }
2135 }
2136};
2137
2138const char *const CGObjCGNUstep2::SectionsBaseNames[8] =
2139{
2140"__objc_selectors",
2141"__objc_classes",
2142"__objc_class_refs",
2143"__objc_cats",
2144"__objc_protocols",
2145"__objc_protocol_refs",
2146"__objc_class_aliases",
2147"__objc_constant_string"
2148};
2149
2150const char *const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2151{
2152".objcrt$SEL",
2153".objcrt$CLS",
2154".objcrt$CLR",
2155".objcrt$CAT",
2156".objcrt$PCL",
2157".objcrt$PCR",
2158".objcrt$CAL",
2159".objcrt$STR"
2160};
2161
2162
2163class CGObjCObjFW: public CGObjCGNU {
2164protected:
2165
2166
2167 LazyRuntimeFunction MsgLookupFn;
2168
2169
2170 LazyRuntimeFunction MsgLookupFnSRet;
2171
2172
2173
2174 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2175
2176 llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
2177 llvm::Value *cmd, llvm::MDNode *node,
2178 MessageSendInfo &MSI) override {
2180 llvm::Value *args[] = {
2181 EnforceType(Builder, Receiver, IdTy),
2182 EnforceType(Builder, cmd, SelectorTy) };
2183
2184 llvm::CallBase *imp;
2187 else
2189
2190 imp->setMetadata(msgSendMDKind, node);
2191 return imp;
2192 }
2193
2195 llvm::Value *cmd, MessageSendInfo &MSI) override {
2197 llvm::Value *lookupArgs[] = {
2198 EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy),
2199 cmd,
2200 };
2201
2204 else
2206 }
2207
2208 llvm::Value *GetClassNamed(CodeGenFunction &CGF, const std::string &Name,
2209 bool isWeak) override {
2210 if (isWeak)
2211 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2212
2213 EmitClassRef(Name);
2214 std::string SymbolName = "_OBJC_CLASS_" + Name;
2215 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2216 if (!ClassSymbol)
2217 ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
2218 llvm::GlobalValue::ExternalLinkage,
2219 nullptr, SymbolName);
2220 return ClassSymbol;
2221 }
2222
2223public:
2224 CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
2225
2226 MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2227 MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy,
2228 SelectorTy);
2229
2230 MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
2231 PtrToObjCSuperTy, SelectorTy);
2232 MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy,
2233 PtrToObjCSuperTy, SelectorTy);
2234 }
2235};
2236}
2237
2238
2239
2240
2241void CGObjCGNU::EmitClassRef(const std::string &className) {
2242 std::string symbolRef = "__objc_class_ref_" + className;
2243
2244 if (TheModule.getGlobalVariable(symbolRef))
2245 return;
2246 std::string symbolName = "__objc_class_name_" + className;
2247 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2248 if (!ClassSymbol) {
2249 ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
2250 llvm::GlobalValue::ExternalLinkage,
2251 nullptr, symbolName);
2252 }
2253 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
2254 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2255}
2256
2257CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
2258 unsigned protocolClassVersion, unsigned classABI)
2259 : CGObjCRuntime(cgm), TheModule(CGM.getModule()),
2260 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2261 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2262 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2263
2264 msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
2265 usesSEHExceptions =
2267 usesCxxExceptions =
2270
2272 IntTy = castllvm::IntegerType(
2274 LongTy = castllvm::IntegerType(
2276 SizeTy = castllvm::IntegerType(
2278 PtrDiffTy = castllvm::IntegerType(
2281
2282 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2283
2284 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2285 ProtocolPtrTy = llvm::PointerType::getUnqual(
2287
2288 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2289 Zeros[1] = Zeros[0];
2290 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2291
2294 SelectorTy = PtrToInt8Ty;
2295 SelectorElemTy = Int8Ty;
2296 } else {
2297 SelectorTy = castllvm::PointerType(CGM.getTypes().ConvertType(selTy));
2299 }
2300
2301 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2302 PtrTy = PtrToInt8Ty;
2303
2304 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2305 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2306
2307 IntPtrTy =
2308 CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2309
2310
2313 if (UnqualIdTy != QualType()) {
2318 } else {
2319 IdTy = PtrToInt8Ty;
2320 IdElemTy = Int8Ty;
2321 }
2322 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2323 ProtocolTy = llvm::StructType::get(IdTy,
2324 PtrToInt8Ty,
2325 PtrToInt8Ty,
2326 PtrToInt8Ty,
2327 PtrToInt8Ty,
2328 PtrToInt8Ty,
2329 PtrToInt8Ty,
2330 PtrToInt8Ty,
2331 PtrToInt8Ty);
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345 PropertyMetadataTy = llvm::StructType::get(CGM.getLLVMContext(), {
2346 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2347 PtrToInt8Ty, PtrToInt8Ty });
2348
2349 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2350 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2351
2352 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2353
2354
2355 ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy);
2356 ExceptionReThrowFn.init(&CGM,
2357 usesCxxExceptions ? "objc_exception_rethrow"
2358 : "objc_exception_throw",
2359 VoidTy, IdTy);
2360
2361 SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy);
2362
2363 SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy);
2364
2365
2366 EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy, IdTy);
2367
2368
2369 GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy,
2370 PtrDiffTy, BoolTy);
2371
2372 SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy,
2373 PtrDiffTy, IdTy, BoolTy, BoolTy);
2374
2375 GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2376 PtrDiffTy, BoolTy, BoolTy);
2377
2378 SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2379 PtrDiffTy, BoolTy, BoolTy);
2380
2381
2382 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2383 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2384 true));
2385
2387 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2388 RuntimeVersion = 10;
2389
2390
2391 if (Opts.getGC() != LangOptions::NonGC) {
2392
2393
2394
2395
2399
2400
2401
2402
2403 IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2404
2405 StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy,
2406 PtrToIdTy);
2407
2408 GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy);
2409
2410 WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2411
2412 WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy);
2413
2414 MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2415 SizeTy);
2416 }
2417}
2418
2419llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF,
2420 const std::string &Name, bool isWeak) {
2421 llvm::Constant *ClassName = MakeConstantString(Name);
2422
2423
2424
2425
2426
2427
2428
2429 if (!isWeak)
2430 EmitClassRef(Name);
2431
2433 llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class");
2435}
2436
2437
2438
2443 if (auto *ClassSymbol = dyn_castllvm::GlobalVariable(Value))
2446}
2447
2448llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
2449 auto *Value = GetClassNamed(CGF, "NSAutoreleasePool", false);
2450 if (CGM.getTriple().isOSBinFormatCOFF()) {
2451 if (auto *ClassSymbol = dyn_castllvm::GlobalVariable(Value)) {
2455
2456 const VarDecl *VD = nullptr;
2457 for (const auto *Result : DC->lookup(&II))
2458 if ((VD = dyn_cast(Result)))
2459 break;
2460
2462 }
2463 }
2465}
2466
2468 const std::string &TypeEncoding) {
2470 llvm::GlobalAlias *SelValue = nullptr;
2471
2473 e = Types.end() ; i!=e ; i++) {
2474 if (i->first == TypeEncoding) {
2475 SelValue = i->second;
2476 break;
2477 }
2478 }
2479 if (!SelValue) {
2480 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2481 llvm::GlobalValue::PrivateLinkage,
2483 &TheModule);
2484 Types.emplace_back(TypeEncoding, SelValue);
2485 }
2486
2487 return SelValue;
2488}
2489
2491 llvm::Value *SelValue = GetSelector(CGF, Sel);
2492
2493
2494
2498 return tmp;
2499}
2500
2502 return GetTypedSelector(CGF, Sel, std::string());
2503}
2504
2505llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF,
2508 return GetTypedSelector(CGF, Method->getSelector(), SelTypes);
2509}
2510
2511llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
2513
2514
2515
2516
2518 return MakeConstantString("@id");
2519 } else {
2520 return nullptr;
2521 }
2522 }
2523
2524
2526 assert(OPT && "Invalid @catch type.");
2528 assert(IDecl && "Invalid @catch type.");
2530}
2531
2532llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
2533 if (usesSEHExceptions)
2535
2536 if (!CGM.getLangOpts().CPlusPlus && !usesCxxExceptions)
2537 return CGObjCGNU::GetEHType(T);
2538
2539
2540
2541
2542
2545 llvm::Constant *IDEHType =
2546 CGM.getModule().getGlobalVariable("__objc_id_type_info");
2547 if (!IDEHType)
2548 IDEHType =
2549 new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
2550 false,
2551 llvm::GlobalValue::ExternalLinkage,
2552 nullptr, "__objc_id_type_info");
2553 return IDEHType;
2554 }
2555
2558 assert(PT && "Invalid @catch type.");
2560 assert(IT && "Invalid @catch type.");
2561 std::string className =
2563
2564 std::string typeinfoName = "__objc_eh_typeinfo_" + className;
2565
2566
2567 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2568 return typeinfo;
2569
2570
2571
2572
2573
2574
2575 const char *vtableName = "_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2576 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2577 if (!Vtable) {
2578 Vtable = new llvm::GlobalVariable(TheModule, PtrToInt8Ty, true,
2579 llvm::GlobalValue::ExternalLinkage,
2580 nullptr, vtableName);
2581 }
2582 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2583 auto *BVtable =
2584 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2585
2586 llvm::Constant *typeName =
2587 ExportUniqueString(className, "__objc_eh_typename_");
2588
2590 auto fields = builder.beginStruct();
2591 fields.add(BVtable);
2592 fields.add(typeName);
2593 llvm::Constant *TI =
2594 fields.finishAndCreateGlobal("__objc_eh_typeinfo_" + className,
2596 false,
2597 llvm::GlobalValue::LinkOnceODRLinkage);
2598 return TI;
2599}
2600
2601
2603
2604 std::string Str = SL->getString().str();
2606
2607
2608 llvm::StringMapllvm::Constant\*::iterator old = ObjCStrings.find(Str);
2609 if (old != ObjCStrings.end())
2611
2613
2614 if (StringClass.empty()) StringClass = "NSConstantString";
2615
2616 std::string Sym = "_OBJC_CLASS_";
2617 Sym += StringClass;
2618
2619 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
2620
2621 if (!isa)
2622 isa = new llvm::GlobalVariable(TheModule, IdTy, false,
2623 llvm::GlobalValue::ExternalWeakLinkage,
2624 nullptr, Sym);
2625
2627 auto Fields = Builder.beginStruct();
2628 Fields.add(isa);
2629 Fields.add(MakeConstantString(Str));
2630 Fields.addInt(IntTy, Str.size());
2632 ObjCStrings[Str] = ObjCStr;
2633 ConstantStrings.push_back(ObjCStr);
2635}
2636
2637
2638
2639
2641CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
2646 bool isCategoryImpl,
2647 llvm::Value *Receiver,
2648 bool IsClassMessage,
2652 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
2653 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2654 return RValue::get(EnforceType(Builder, Receiver,
2656 }
2657 if (Sel == ReleaseSel) {
2659 }
2660 }
2661
2662 llvm::Value *cmd = GetSelector(CGF, Sel);
2664
2665 ActualArgs.add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2667 ActualArgs.addFrom(CallArgs);
2668
2669 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2670
2671 llvm::Value *ReceiverClass = nullptr;
2673 if (isV2ABI) {
2674 ReceiverClass = GetClassNamed(CGF,
2675 Class->getSuperClass()->getNameAsString(), false);
2676 if (IsClassMessage) {
2677
2678 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2679 llvm::PointerType::getUnqual(IdTy));
2680 ReceiverClass =
2681 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign());
2682 }
2683 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2684 } else {
2685 if (isCategoryImpl) {
2686 llvm::FunctionCallee classLookupFunction = nullptr;
2687 if (IsClassMessage) {
2689 IdTy, PtrTy, true), "objc_get_meta_class");
2690 } else {
2692 IdTy, PtrTy, true), "objc_get_class");
2693 }
2694 ReceiverClass = Builder.CreateCall(classLookupFunction,
2695 MakeConstantString(Class->getNameAsString()));
2696 } else {
2697
2698
2699
2700
2701
2702 if (IsClassMessage) {
2703 if (!MetaClassPtrAlias) {
2704 MetaClassPtrAlias = llvm::GlobalAlias::create(
2705 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2706 ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule);
2707 }
2708 ReceiverClass = MetaClassPtrAlias;
2709 } else {
2710 if (!ClassPtrAlias) {
2711 ClassPtrAlias = llvm::GlobalAlias::create(
2712 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2713 ".objc_class_ref" + Class->getNameAsString(), &TheModule);
2714 }
2715 ReceiverClass = ClassPtrAlias;
2716 }
2717 }
2718
2719 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2720 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2721 llvm::PointerType::getUnqual(CastTy));
2722
2723 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2724
2725 ReceiverClass =
2726 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.getPointerAlign());
2727 }
2728
2729 llvm::StructType *ObjCSuperTy =
2730 llvm::StructType::get(Receiver->getType(), IdTy);
2731
2734
2735 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2736 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2737
2738
2739 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2740 imp = EnforceType(Builder, imp, MSI.MessengerType);
2741
2742 llvm::Metadata *impMD[] = {
2743 llvm::MDString::get(VMContext, Sel.getAsString()),
2744 llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()),
2745 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2746 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2747 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2748
2750
2751 llvm::CallBase *call;
2752 RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2753 call->setMetadata(msgSendMDKind, node);
2754 return msgRet;
2755}
2756
2757
2763 llvm::Value *Receiver,
2768
2769
2770 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
2771 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2772 return RValue::get(EnforceType(Builder, Receiver,
2774 }
2775 if (Sel == ReleaseSel) {
2777 }
2778 }
2779
2781
2783 llvm::Value *cmd;
2784 if (!isDirect) {
2785 if (Method)
2786 cmd = GetSelector(CGF, Method);
2787 else
2788 cmd = GetSelector(CGF, Sel);
2789 cmd = EnforceType(Builder, cmd, SelectorTy);
2790 }
2791
2792 Receiver = EnforceType(Builder, Receiver, IdTy);
2793
2794 llvm::Metadata *impMD[] = {
2795 llvm::MDString::get(VMContext, Sel.getAsString()),
2796 llvm::MDString::get(VMContext, Class ? Class->getNameAsString() : ""),
2797 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2798 llvm::Type::getInt1Ty(VMContext), Class != nullptr))};
2799 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2800
2803 if (!isDirect)
2805 ActualArgs.addFrom(CallArgs);
2806
2807 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828 bool hasParamDestroyedInCallee = false;
2829 bool requiresExplicitZeroResult = false;
2830 bool requiresNilReceiverCheck = [&] {
2831
2832 if (!canMessageReceiverBeNull(CGF, Method, false,
2833 Class, Receiver))
2834 return false;
2835
2836
2838 hasParamDestroyedInCallee = true;
2839 }
2840
2841
2842
2843
2846
2849
2850
2851
2853
2854
2855
2856 } else {
2857
2858
2859 requiresExplicitZeroResult = !isDirect;
2860 }
2861 }
2862
2863 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2864 }();
2865
2866
2867
2868
2869 bool requiresExplicitAggZeroing =
2871
2872
2873 llvm::BasicBlock *continueBB = nullptr;
2874
2875 llvm::BasicBlock *nilPathBB = nullptr;
2876
2877 llvm::BasicBlock *nilCleanupBB = nullptr;
2878
2879
2880 if (requiresNilReceiverCheck) {
2881 llvm::BasicBlock *messageBB = CGF.createBasicBlock("msgSend");
2883
2884
2885
2886
2887 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2889 } else {
2890 nilPathBB = Builder.GetInsertBlock();
2891 }
2892
2893 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2894 llvm::Constant::getNullValue(Receiver->getType()));
2895 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2896 messageBB);
2898 }
2899
2900
2901 llvm::Value *imp;
2902
2903
2904 if (isDirect)
2906 else
2907
2908
2909
2910 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
2912 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2913 break;
2916 StringRef name = "objc_msgSend";
2918 name = "objc_msgSend_fpret";
2920 name = "objc_msgSend_stret";
2921
2922
2923
2924 bool shouldCheckForInReg =
2928 .isWindowsMSVCEnvironment() &&
2931 name = "objc_msgSend_stret2";
2932 }
2933 }
2934
2935
2937 name)
2938 .getCallee();
2939 }
2940
2941
2943
2944 imp = EnforceType(Builder, imp, MSI.MessengerType);
2945
2946 llvm::CallBase *call;
2948 RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2949 if (!isDirect)
2950 call->setMetadata(msgSendMDKind, node);
2951
2952 if (requiresNilReceiverCheck) {
2953 llvm::BasicBlock *nonNilPathBB = CGF.Builder.GetInsertBlock();
2954 CGF.Builder.CreateBr(continueBB);
2955
2956
2957 if (nilCleanupBB) {
2959
2960 if (hasParamDestroyedInCallee) {
2961 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2962 }
2963
2964 if (requiresExplicitAggZeroing) {
2968 }
2969
2970 nilPathBB = CGF.Builder.GetInsertBlock();
2971 CGF.Builder.CreateBr(continueBB);
2972 }
2973
2974
2977
2979 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
2980 phi->addIncoming(v, nonNilPathBB);
2981 phi->addIncoming(CGM.EmitNullConstant(ResultType), nilPathBB);
2983 }
2985
2986 } else {
2987 std::pairllvm::Value\*,llvm::Value\* v = msgRet.getComplexVal();
2988 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
2989 phi->addIncoming(v.first, nonNilPathBB);
2990 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
2991 nilPathBB);
2992 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
2993 phi2->addIncoming(v.second, nonNilPathBB);
2994 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
2995 nilPathBB);
2997 }
2998 }
2999 return msgRet;
3000}
3001
3002
3003
3004llvm::Constant *CGObjCGNU::
3005GenerateMethodList(StringRef ClassName,
3006 StringRef CategoryName,
3008 bool isClassMethodList) {
3009 if (Methods.empty())
3010 return NULLPtr;
3011
3013
3014 auto MethodList = Builder.beginStruct();
3015 MethodList.addNullPointer(CGM.Int8PtrTy);
3016 MethodList.addInt(Int32Ty, Methods.size());
3017
3018
3019 llvm::StructType *ObjCMethodTy =
3021 PtrToInt8Ty,
3022 PtrToInt8Ty,
3023 IMPTy
3024 });
3026 if (isV2ABI) {
3027
3028 const llvm::DataLayout &DL = TheModule.getDataLayout();
3029 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3031 ObjCMethodTy =
3033 IMPTy,
3034 PtrToInt8Ty,
3035 PtrToInt8Ty
3036 });
3037 } else {
3038 ObjCMethodTy =
3040 PtrToInt8Ty,
3041 PtrToInt8Ty,
3042 IMPTy
3043 });
3044 }
3045 auto MethodArray = MethodList.beginArray();
3047 for (const auto *OMD : Methods) {
3048 llvm::Constant *FnPtr =
3049 TheModule.getFunction(getSymbolNameForMethod(OMD));
3050 assert(FnPtr && "Can't generate metadata for method that doesn't exist");
3051 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3052 if (isV2ABI) {
3053 Method.add(FnPtr);
3057 } else {
3060 Method.add(FnPtr);
3061 }
3062 Method.finishAndAddTo(MethodArray);
3063 }
3064 MethodArray.finishAndAddTo(MethodList);
3065
3066
3067 return MethodList.finishAndCreateGlobal(".objc_method_list",
3069}
3070
3071
3072llvm::Constant *CGObjCGNU::
3078 if (IvarNames.empty())
3079 return NULLPtr;
3080
3082
3083
3084 auto IvarList = Builder.beginStruct();
3085 IvarList.addInt(IntTy, (int)IvarNames.size());
3086
3087
3088 llvm::StructType *ObjCIvarTy =
3089 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3090
3091
3092 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3093 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3094 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3095 Ivar.add(IvarNames[i]);
3096 Ivar.add(IvarTypes[i]);
3097 Ivar.add(IvarOffsets[i]);
3098 Ivar.finishAndAddTo(Ivars);
3099 }
3100 Ivars.finishAndAddTo(IvarList);
3101
3102
3103 return IvarList.finishAndCreateGlobal(".objc_ivar_list",
3105}
3106
3107
3108llvm::Constant *CGObjCGNU::GenerateClassStructure(
3109 llvm::Constant *MetaClass,
3110 llvm::Constant *SuperClass,
3111 unsigned info,
3112 const char *Name,
3113 llvm::Constant *Version,
3114 llvm::Constant *InstanceSize,
3115 llvm::Constant *IVars,
3116 llvm::Constant *Methods,
3117 llvm::Constant *Protocols,
3118 llvm::Constant *IvarOffsets,
3119 llvm::Constant *Properties,
3120 llvm::Constant *StrongIvarBitmap,
3121 llvm::Constant *WeakIvarBitmap,
3122 bool isMeta) {
3123
3124
3125
3126
3127
3128
3129
3130 llvm::StructType *ClassTy = llvm::StructType::get(
3131 PtrToInt8Ty,
3132 PtrToInt8Ty,
3133 PtrToInt8Ty,
3134 LongTy,
3135 LongTy,
3136 LongTy,
3137 IVars->getType(),
3138 Methods->getType(),
3139
3140 PtrTy,
3141 PtrTy,
3142 PtrTy,
3143 PtrTy,
3144 PtrTy,
3145
3146 LongTy,
3147 IvarOffsets->getType(),
3148 Properties->getType(),
3149 IntPtrTy,
3150 IntPtrTy
3151 );
3152
3154 auto Elements = Builder.beginStruct(ClassTy);
3155
3156
3157
3158
3159 Elements.add(MetaClass);
3160
3161 Elements.add(SuperClass);
3162
3163 Elements.add(MakeConstantString(Name, ".class_name"));
3164
3165 Elements.addInt(LongTy, 0);
3166
3167 Elements.addInt(LongTy, info);
3168
3169 if (isMeta) {
3170 const llvm::DataLayout &DL = TheModule.getDataLayout();
3171 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3173 } else
3174 Elements.add(InstanceSize);
3175
3176 Elements.add(IVars);
3177
3178 Elements.add(Methods);
3179
3180
3181 Elements.add(NULLPtr);
3182
3183 Elements.add(NULLPtr);
3184
3185 Elements.add(NULLPtr);
3186
3187 Elements.add(Protocols);
3188
3189 Elements.add(NULLPtr);
3190
3191 Elements.addInt(LongTy, ClassABIVersion);
3192
3193 Elements.add(IvarOffsets);
3194
3195 Elements.add(Properties);
3196
3197 Elements.add(StrongIvarBitmap);
3198
3199 Elements.add(WeakIvarBitmap);
3200
3201
3202
3203
3204 std::string ClassSym((isMeta ? "_OBJC_METACLASS_": "_OBJC_CLASS_") +
3205 std::string(Name));
3206 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3207 llvm::Constant *Class =
3208 Elements.finishAndCreateGlobal(ClassSym, CGM.getPointerAlign(), false,
3209 llvm::GlobalValue::ExternalLinkage);
3210 if (ClassRef) {
3211 ClassRef->replaceAllUsesWith(Class);
3212 ClassRef->removeFromParent();
3213 Class->setName(ClassSym);
3214 }
3216}
3217
3218llvm::Constant *CGObjCGNU::
3220
3221 llvm::StructType *ObjCMethodDescTy =
3222 llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3225 auto MethodList = Builder.beginStruct();
3226 MethodList.addInt(IntTy, Methods.size());
3227 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3228 for (auto *M : Methods) {
3229 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3230 Method.add(MakeConstantString(M->getSelector().getAsString()));
3232 Method.finishAndAddTo(MethodArray);
3233 }
3234 MethodArray.finishAndAddTo(MethodList);
3235 return MethodList.finishAndCreateGlobal(".objc_method_list",
3237}
3238
3239
3240llvm::Constant *
3242
3244 auto ProtocolList = Builder.beginStruct();
3245 ProtocolList.add(NULLPtr);
3246 ProtocolList.addInt(LongTy, Protocols.size());
3247
3248 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3249 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3250 iter != endIter ; iter++) {
3251 llvm::Constant *protocol = nullptr;
3252 llvm::StringMapllvm::Constant\*::iterator value =
3253 ExistingProtocols.find(*iter);
3254 if (value == ExistingProtocols.end()) {
3255 protocol = GenerateEmptyProtocol(*iter);
3256 } else {
3257 protocol = value->getValue();
3258 }
3259 Elements.add(protocol);
3260 }
3261 Elements.finishAndAddTo(ProtocolList);
3262 return ProtocolList.finishAndCreateGlobal(".objc_protocol_list",
3264}
3265
3266llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
3268 auto protocol = GenerateProtocolRef(PD);
3269 llvm::Type *T =
3271 return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
3272}
3273
3274llvm::Constant *CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD) {
3275 llvm::Constant *&protocol = ExistingProtocols[PD->getNameAsString()];
3276 if (!protocol)
3277 GenerateProtocol(PD);
3278 assert(protocol && "Unknown protocol");
3279 return protocol;
3280}
3281
3282llvm::Constant *
3283CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3284 llvm::Constant *ProtocolList = GenerateProtocolList({});
3285 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3286
3287
3289 auto Elements = Builder.beginStruct();
3290
3291
3292
3293 Elements.add(llvm::ConstantExpr::getIntToPtr(
3294 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3295
3296 Elements.add(MakeConstantString(ProtocolName, ".objc_protocol_name"));
3297 Elements.add(ProtocolList);
3298 Elements.add(MethodList);
3299 Elements.add(MethodList);
3300 Elements.add(MethodList);
3301 Elements.add(MethodList);
3302 Elements.add(NULLPtr);
3303 Elements.add(NULLPtr);
3304 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3306}
3307
3308void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
3310 return;
3311
3313
3314
3316 PD = Def;
3317
3319 for (const auto *PI : PD->protocols())
3320 Protocols.push_back(PI->getNameAsString());
3324 if (I->isOptional())
3325 OptionalInstanceMethods.push_back(I);
3326 else
3327 InstanceMethods.push_back(I);
3328
3332 if (I->isOptional())
3333 OptionalClassMethods.push_back(I);
3334 else
3335 ClassMethods.push_back(I);
3336
3337 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3338 llvm::Constant *InstanceMethodList =
3339 GenerateProtocolMethodList(InstanceMethods);
3340 llvm::Constant *ClassMethodList =
3341 GenerateProtocolMethodList(ClassMethods);
3342 llvm::Constant *OptionalInstanceMethodList =
3343 GenerateProtocolMethodList(OptionalInstanceMethods);
3344 llvm::Constant *OptionalClassMethodList =
3345 GenerateProtocolMethodList(OptionalClassMethods);
3346
3347
3348
3349
3350
3351
3352
3353 llvm::Constant *PropertyList =
3354 GeneratePropertyList(nullptr, PD, false, false);
3355 llvm::Constant *OptionalPropertyList =
3356 GeneratePropertyList(nullptr, PD, false, true);
3357
3358
3359
3360
3361
3363 auto Elements = Builder.beginStruct();
3364 Elements.add(
3365 llvm::ConstantExpr::getIntToPtr(
3366 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3367 Elements.add(MakeConstantString(ProtocolName));
3368 Elements.add(ProtocolList);
3369 Elements.add(InstanceMethodList);
3370 Elements.add(ClassMethodList);
3371 Elements.add(OptionalInstanceMethodList);
3372 Elements.add(OptionalClassMethodList);
3373 Elements.add(PropertyList);
3374 Elements.add(OptionalPropertyList);
3375 ExistingProtocols[ProtocolName] =
3376 Elements.finishAndCreateGlobal(".objc_protocol", CGM.getPointerAlign());
3377}
3378void CGObjCGNU::GenerateProtocolHolderCategory() {
3379
3380
3382 auto Elements = Builder.beginStruct();
3383
3384 const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
3385 const std::string CategoryName = "AnotherHack";
3386 Elements.add(MakeConstantString(CategoryName));
3387 Elements.add(MakeConstantString(ClassName));
3388
3389 Elements.add(GenerateMethodList(ClassName, CategoryName, {}, false));
3390
3391 Elements.add(GenerateMethodList(ClassName, CategoryName, {}, true));
3392
3393
3395 auto ProtocolList = ProtocolListBuilder.beginStruct();
3396 ProtocolList.add(NULLPtr);
3397 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3398 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3399 for (auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3400 iter != endIter ; iter++) {
3401 ProtocolElements.add(iter->getValue());
3402 }
3403 ProtocolElements.finishAndAddTo(ProtocolList);
3404 Elements.add(ProtocolList.finishAndCreateGlobal(".objc_protocol_list",
3406 Categories.push_back(
3407 Elements.finishAndCreateGlobal("", CGM.getPointerAlign()));
3408}
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef bits) {
3422 int bitCount = bits.size();
3423 int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
3424 if (bitCount < ptrBits) {
3426 for (int i=0 ; i<bitCount ; ++i) {
3427 if (bits[i]) val |= 1ULL<<(i+1);
3428 }
3429 return llvm::ConstantInt::get(IntPtrTy, val);
3430 }
3432 int v=0;
3433 while (v < bitCount) {
3435 for (int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3436 if (bits[v]) word |= 1<<i;
3437 v++;
3438 }
3439 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3440 }
3441
3443 auto fields = builder.beginStruct();
3444 fields.addInt(Int32Ty, values.size());
3445 auto array = fields.beginArray();
3446 for (auto *v : values) array.add(v);
3447 array.finishAndAddTo(fields);
3448
3449 llvm::Constant *GS =
3451 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3452 return ptr;
3453}
3454
3455llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(const
3458 const auto RuntimeProtos =
3459 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3461 for (const auto *PD : RuntimeProtos)
3463 return GenerateProtocolList(Protocols);
3464}
3465
3468 std::string ClassName = Class->getNameAsString();
3470
3471
3473
3475 auto Elements = Builder.beginStruct();
3476 Elements.add(MakeConstantString(CategoryName));
3477 Elements.add(MakeConstantString(ClassName));
3478
3480 InstanceMethods.insert(InstanceMethods.begin(), OCD->instmeth_begin(),
3482 Elements.add(
3483 GenerateMethodList(ClassName, CategoryName, InstanceMethods, false));
3484
3485
3486
3488 ClassMethods.insert(ClassMethods.begin(), OCD->classmeth_begin(),
3490 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods, true));
3491
3492
3493 Elements.add(GenerateCategoryProtocolList(CatDecl));
3498
3499 Elements.add(GeneratePropertyList(OCD, Category, false));
3500
3501 Elements.add(GeneratePropertyList(OCD, Category, true));
3502 } else {
3503 Elements.addNullPointer(PtrTy);
3504 Elements.addNullPointer(PtrTy);
3505 }
3506 }
3507
3508 Categories.push_back(Elements.finishAndCreateGlobal(
3509 std::string(".objc_category_") + ClassName + CategoryName,
3511}
3512
3513llvm::Constant *CGObjCGNU::GeneratePropertyList(const Decl *Container,
3515 bool isClassProperty,
3516 bool protocolOptionalProperties) {
3517
3520 bool isProtocol = isa(OCD);
3522
3523 std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties
3525 for (const auto *P : Proto->protocols())
3526 collectProtocolProperties(P);
3527 for (const auto *PD : Proto->properties()) {
3528 if (isClassProperty != PD->isClassProperty())
3529 continue;
3530
3531
3533 continue;
3534 if (!PropertySet.insert(PD->getIdentifier()).second)
3535 continue;
3536 Properties.push_back(PD);
3537 }
3538 };
3539
3540 if (const ObjCInterfaceDecl *OID = dyn_cast(OCD))
3542 for (auto *PD : ClassExt->properties()) {
3543 if (isClassProperty != PD->isClassProperty())
3544 continue;
3546 Properties.push_back(PD);
3547 }
3548
3549 for (const auto *PD : OCD->properties()) {
3550 if (isClassProperty != PD->isClassProperty())
3551 continue;
3552
3553
3554 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3555 continue;
3556
3557
3558 if (!PropertySet.insert(PD->getIdentifier()).second)
3559 continue;
3560
3561 Properties.push_back(PD);
3562 }
3563
3564 if (const ObjCInterfaceDecl *OID = dyn_cast(OCD))
3566 collectProtocolProperties(P);
3567 else if (const ObjCCategoryDecl *CD = dyn_cast(OCD))
3568 for (const auto *P : CD->protocols())
3569 collectProtocolProperties(P);
3570
3571 auto numProperties = Properties.size();
3572
3573 if (numProperties == 0)
3574 return NULLPtr;
3575
3577 auto propertyList = builder.beginStruct();
3578 auto properties = PushPropertyListHeader(propertyList, numProperties);
3579
3580
3581
3582 for (auto *property : Properties) {
3583 bool isSynthesized = false;
3584 bool isDynamic = false;
3585 if (!isProtocol) {
3587 if (propertyImpl) {
3588 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3590 isDynamic = (propertyImpl->getPropertyImplementation() ==
3592 }
3593 }
3594 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3595 }
3596 properties.finishAndAddTo(propertyList);
3597
3598 return propertyList.finishAndCreateGlobal(".objc_property_list",
3600}
3601
3603
3608}
3609
3612
3613
3616 std::string SuperClassName;
3617 if (SuperClassDecl) {
3619 EmitClassRef(SuperClassName);
3620 }
3621
3622
3626
3627
3628
3629 std::string classSymbolName = "__objc_class_name_" + ClassName;
3630 if (auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3631 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3632 } else {
3633 new llvm::GlobalVariable(TheModule, LongTy, false,
3634 llvm::GlobalValue::ExternalLinkage,
3635 llvm::ConstantInt::get(LongTy, 0),
3636 classSymbolName);
3637 }
3638
3639
3640 int instanceSize =
3642
3643
3649
3651 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3654
3655 int superInstanceSize = !SuperClassDecl ? 0 :
3657
3658
3660 instanceSize = 0 - (instanceSize - superInstanceSize);
3661 }
3662
3665
3666 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3667
3668 std::string TypeStr;
3670 IvarTypes.push_back(MakeConstantString(TypeStr));
3671 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3673
3674 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3675 uint64_t Offset = BaseOffset;
3677 Offset = BaseOffset - superInstanceSize;
3678 }
3679 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3680
3681 std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." +
3682 IVD->getNameAsString();
3683
3684 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3685 if (OffsetVar) {
3686 OffsetVar->setInitializer(OffsetValue);
3687
3688
3689
3690 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3691 } else
3692 OffsetVar = new llvm::GlobalVariable(TheModule, Int32Ty,
3693 false, llvm::GlobalValue::ExternalLinkage,
3694 OffsetValue, OffsetName);
3695 IvarOffsets.push_back(OffsetValue);
3696 IvarOffsetValues.add(OffsetVar);
3698 IvarOwnership.push_back(lt);
3699 switch (lt) {
3701 StrongIvars.push_back(true);
3702 WeakIvars.push_back(false);
3703 break;
3705 StrongIvars.push_back(false);
3706 WeakIvars.push_back(true);
3707 break;
3708 default:
3709 StrongIvars.push_back(false);
3710 WeakIvars.push_back(false);
3711 }
3712 }
3713 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3714 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3715 llvm::GlobalVariable *IvarOffsetArray =
3716 IvarOffsetValues.finishAndCreateGlobal(".ivar.offsets",
3718
3719
3721 InstanceMethods.insert(InstanceMethods.begin(), OID->instmeth_begin(),
3723
3725 ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(),
3727
3728 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3729
3730
3731 auto RefProtocols = ClassDecl->protocols();
3732 auto RuntimeProtocols =
3733 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3735 for (const auto *I : RuntimeProtocols)
3736 Protocols.push_back(I->getNameAsString());
3737
3738
3739 llvm::Constant *SuperClass;
3740 if (!SuperClassName.empty()) {
3741 SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
3742 } else {
3743 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3744 }
3745
3747
3748 llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
3749 InstanceMethods, false);
3750 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
3751 ClassMethods, true);
3752 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3753 IvarOffsets, IvarAligns, IvarOwnership);
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764 llvm::Type *IndexTy = Int32Ty;
3765 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3766 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1), nullptr,
3767 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3768
3769 unsigned ivarIndex = 0;
3772 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3773 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3774
3775 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3776 castllvm::GlobalVariable(IvarList)->getValueType(), IvarList,
3777 offsetPointerIndexes);
3778
3779 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3780 if (offset) {
3781 offset->setInitializer(offsetValue);
3782
3783
3784
3785 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3786 } else
3787
3788 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3789 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3790 ++ivarIndex;
3791 }
3792 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3793
3794
3795 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3796 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0],
3797 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3798 GeneratePropertyList(OID, ClassDecl, true), ZeroPtr, ZeroPtr, true);
3799 CGM.setGVProperties(castllvm::GlobalValue(MetaClassStruct),
3801
3802
3803 llvm::Constant *ClassStruct = GenerateClassStructure(
3804 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(), nullptr,
3805 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3806 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3807 StrongIvarBitmap, WeakIvarBitmap);
3808 CGM.setGVProperties(castllvm::GlobalValue(ClassStruct),
3810
3811
3812 if (ClassPtrAlias) {
3813 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3814 ClassPtrAlias->eraseFromParent();
3815 ClassPtrAlias = nullptr;
3816 }
3817 if (MetaClassPtrAlias) {
3818 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3819 MetaClassPtrAlias->eraseFromParent();
3820 MetaClassPtrAlias = nullptr;
3821 }
3822
3823
3824 Classes.push_back(ClassStruct);
3825}
3826
3827llvm::Function *CGObjCGNU::ModuleInitFunction() {
3828
3829 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3830 ExistingProtocols.empty() && SelectorTable.empty())
3831 return nullptr;
3832
3833
3834 GenerateProtocolHolderCategory();
3835
3836 llvm::StructType *selStructTy = dyn_castllvm::StructType(SelectorElemTy);
3837 if (!selStructTy) {
3838 selStructTy = llvm::StructType::get(CGM.getLLVMContext(),
3839 { PtrToInt8Ty, PtrToInt8Ty });
3840 }
3841
3842
3843 llvm::Constant *statics = NULLPtr;
3844 if (!ConstantStrings.empty()) {
3845 llvm::GlobalVariable *fileStatics = [&] {
3847 auto staticsStruct = builder.beginStruct();
3848
3850 if (stringClass.empty()) stringClass = "NXConstantString";
3851 staticsStruct.add(MakeConstantString(stringClass,
3852 ".objc_static_class_name"));
3853
3854 auto array = staticsStruct.beginArray();
3855 array.addAll(ConstantStrings);
3856 array.add(NULLPtr);
3857 array.finishAndAddTo(staticsStruct);
3858
3859 return staticsStruct.finishAndCreateGlobal(".objc_statics",
3861 }();
3862
3864 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3865 allStaticsArray.add(fileStatics);
3866 allStaticsArray.addNullPointer(fileStatics->getType());
3867
3868 statics = allStaticsArray.finishAndCreateGlobal(".objc_statics_ptr",
3870 }
3871
3872
3873
3875 unsigned selectorCount;
3876
3877
3878 llvm::GlobalVariable *selectorList = [&] {
3880 auto selectors = builder.beginArray(selStructTy);
3882 std::vector allSelectors;
3883 for (auto &entry : table)
3884 allSelectors.push_back(entry.first);
3885 llvm::sort(allSelectors);
3886
3887 for (auto &untypedSel : allSelectors) {
3888 std::string selNameStr = untypedSel.getAsString();
3889 llvm::Constant *selName = ExportUniqueString(selNameStr, ".objc_sel_name");
3890
3891 for (TypedSelector &sel : table[untypedSel]) {
3892 llvm::Constant *selectorTypeEncoding = NULLPtr;
3893 if (!sel.first.empty())
3894 selectorTypeEncoding =
3895 MakeConstantString(sel.first, ".objc_sel_types");
3896
3897 auto selStruct = selectors.beginStruct(selStructTy);
3898 selStruct.add(selName);
3899 selStruct.add(selectorTypeEncoding);
3900 selStruct.finishAndAddTo(selectors);
3901
3902
3903 selectorAliases.push_back(sel.second);
3904 }
3905 }
3906
3907
3908 selectorCount = selectors.size();
3909
3910
3911
3912
3913
3914 auto selStruct = selectors.beginStruct(selStructTy);
3915 selStruct.add(NULLPtr);
3916 selStruct.add(NULLPtr);
3917 selStruct.finishAndAddTo(selectors);
3918
3919 return selectors.finishAndCreateGlobal(".objc_selector_list",
3921 }();
3922
3923
3924 for (unsigned i = 0; i < selectorCount; ++i) {
3925 llvm::Constant *idxs[] = {
3926 Zeros[0],
3927 llvm::ConstantInt::get(Int32Ty, i)
3928 };
3929
3930 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3931 selectorList->getValueType(), selectorList, idxs);
3932 selectorAliases[i]->replaceAllUsesWith(selPtr);
3933 selectorAliases[i]->eraseFromParent();
3934 }
3935
3936 llvm::GlobalVariable *symtab = [&] {
3938 auto symtab = builder.beginStruct();
3939
3940
3941 symtab.addInt(LongTy, selectorCount);
3942
3943 symtab.add(selectorList);
3944
3945
3946 symtab.addInt(CGM.Int16Ty, Classes.size());
3947
3948 symtab.addInt(CGM.Int16Ty, Categories.size());
3949
3950
3951 auto classList = symtab.beginArray(PtrToInt8Ty);
3952 classList.addAll(Classes);
3953 classList.addAll(Categories);
3954
3955 classList.add(statics);
3956 classList.add(NULLPtr);
3957 classList.finishAndAddTo(symtab);
3958
3959
3960 return symtab.finishAndCreateGlobal("", CGM.getPointerAlign());
3961 }();
3962
3963
3964
3965 llvm::Constant *module = [&] {
3966 llvm::Type *moduleEltTys[] = {
3967 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3968 };
3969 llvm::StructType *moduleTy = llvm::StructType::get(
3971 ArrayRef(moduleEltTys).drop_back(unsigned(RuntimeVersion < 10)));
3972
3974 auto module = builder.beginStruct(moduleTy);
3975
3976 module.addInt(LongTy, RuntimeVersion);
3977
3978 module.addInt(LongTy, CGM.getDataLayout().getTypeStoreSize(moduleTy));
3979
3980
3983 std::string path =
3985 module.add(MakeConstantString(path, ".objc_source_file_name"));
3986 module.add(symtab);
3987
3988 if (RuntimeVersion >= 10) {
3990 case LangOptions::GCOnly:
3991 module.addInt(IntTy, 2);
3992 break;
3993 case LangOptions::NonGC:
3995 module.addInt(IntTy, 1);
3996 else
3997 module.addInt(IntTy, 0);
3998 break;
3999 case LangOptions::HybridGC:
4000 module.addInt(IntTy, 1);
4001 break;
4002 }
4003 }
4004
4005 return module.finishAndCreateGlobal("", CGM.getPointerAlign());
4006 }();
4007
4008
4009
4010 llvm::Function * LoadFunction = llvm::Function::Create(
4011 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
4012 llvm::GlobalValue::InternalLinkage, ".objc_load_function",
4013 &TheModule);
4014 llvm::BasicBlock *EntryBB =
4015 llvm::BasicBlock::Create(VMContext, "entry", LoadFunction);
4017 Builder.SetInsertPoint(EntryBB);
4018
4019 llvm::FunctionType *FT =
4020 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(), true);
4021 llvm::FunctionCallee Register =
4023 Builder.CreateCall(Register, module);
4024
4025 if (!ClassAliases.empty()) {
4026 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4027 llvm::FunctionType *RegisterAliasTy =
4028 llvm::FunctionType::get(Builder.getVoidTy(),
4029 ArgTypes, false);
4030 llvm::Function *RegisterAlias = llvm::Function::Create(
4031 RegisterAliasTy,
4032 llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np",
4033 &TheModule);
4034 llvm::BasicBlock *AliasBB =
4035 llvm::BasicBlock::Create(VMContext, "alias", LoadFunction);
4036 llvm::BasicBlock *NoAliasBB =
4037 llvm::BasicBlock::Create(VMContext, "no_alias", LoadFunction);
4038
4039
4040 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4041 llvm::Constant::getNullValue(RegisterAlias->getType()));
4042 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4043
4044
4045 Builder.SetInsertPoint(AliasBB);
4046
4047 for (std::vector::iterator iter = ClassAliases.begin();
4048 iter != ClassAliases.end(); ++iter) {
4049 llvm::Constant *TheClass =
4050 TheModule.getGlobalVariable("_OBJC_CLASS_" + iter->first, true);
4051 if (TheClass) {
4052 Builder.CreateCall(RegisterAlias,
4053 {TheClass, MakeConstantString(iter->second)});
4054 }
4055 }
4056
4057 Builder.CreateBr(NoAliasBB);
4058
4059
4060 Builder.SetInsertPoint(NoAliasBB);
4061 }
4062 Builder.CreateRetVoid();
4063
4064 return LoadFunction;
4065}
4066
4067llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
4070 llvm::FunctionType *MethodTy =
4071 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4072
4074 std::string FunctionName =
4075 getSymbolNameForMethod(OMD, !isDirect);
4076
4077 if (!isDirect)
4078 return llvm::Function::Create(MethodTy,
4079 llvm::GlobalVariable::InternalLinkage,
4080 FunctionName, &TheModule);
4081
4083 auto I = DirectMethodDefinitions.find(COMD);
4084 llvm::Function *OldFn = nullptr, *Fn = nullptr;
4085
4086 if (I == DirectMethodDefinitions.end()) {
4087 auto *F =
4088 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4089 FunctionName, &TheModule);
4090 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4091 return F;
4092 }
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4104 return I->second;
4105
4106 OldFn = I->second;
4107 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage, "",
4109 Fn->takeName(OldFn);
4110 OldFn->replaceAllUsesWith(Fn);
4111 OldFn->eraseFromParent();
4112
4113
4114 I->second = Fn;
4115 return Fn;
4116}
4117
4118void CGObjCGNU::GenerateDirectMethodPrologue(CodeGenFunction &CGF,
4119 llvm::Function *Fn,
4122
4123}
4124
4125llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4126 return GetPropertyFn;
4127}
4128
4129llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4130 return SetPropertyFn;
4131}
4132
4133llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
4134 bool copy) {
4135 return nullptr;
4136}
4137
4138llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4139 return GetStructPropertyFn;
4140}
4141
4142llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4143 return SetStructPropertyFn;
4144}
4145
4146llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4147 return nullptr;
4148}
4149
4150llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4151 return nullptr;
4152}
4153
4154llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4155 return EnumerationMutationFn;
4156}
4157
4158void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF,
4160 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4161}
4162
4163
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4178}
4179
4182 bool ClearInsertionPoint) {
4183 llvm::Value *ExceptionAsObject;
4184 bool isRethrow = false;
4185
4186 if (const Expr *ThrowExpr = S.getThrowExpr()) {
4188 ExceptionAsObject = Exception;
4189 } else {
4191 "Unexpected rethrow outside @catch block.");
4193 isRethrow = true;
4194 }
4195 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4196
4197
4198
4199
4200
4201
4202
4204 Throw->setDoesNotReturn();
4205 } else {
4206 ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
4207 llvm::CallBase *Throw =
4209 Throw->setDoesNotReturn();
4210 }
4211 CGF.Builder.CreateUnreachable();
4212 if (ClearInsertionPoint)
4213 CGF.Builder.ClearInsertionPoint();
4214}
4215
4216llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF,
4219 return B.CreateCall(
4220 WeakReadFn, EnforceType(B, AddrWeakObj.emitRawPointer(CGF), PtrToIdTy));
4221}
4222
4224 llvm::Value *src, Address dst) {
4226 src = EnforceType(B, src, IdTy);
4227 llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy);
4228 B.CreateCall(WeakAssignFn, {src, dstVal});
4229}
4230
4231void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
4232 llvm::Value *src, Address dst,
4233 bool threadlocal) {
4235 src = EnforceType(B, src, IdTy);
4236 llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy);
4237
4238 assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI");
4239 B.CreateCall(GlobalAssignFn, {src, dstVal});
4240}
4241
4243 llvm::Value *src, Address dst,
4244 llvm::Value *ivarOffset) {
4246 src = EnforceType(B, src, IdTy);
4247 llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), IdTy);
4248 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4249}
4250
4251void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
4252 llvm::Value *src, Address dst) {
4254 src = EnforceType(B, src, IdTy);
4255 llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy);
4256 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4257}
4258
4259void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
4262 llvm::Value *Size) {
4264 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.emitRawPointer(CGF), PtrTy);
4265 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.emitRawPointer(CGF), PtrTy);
4266
4267 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal, Size});
4268}
4269
4270llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4273 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4274
4275
4276
4277 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4278 if (!IvarOffsetPointer)
4279 IvarOffsetPointer = new llvm::GlobalVariable(
4280 TheModule, llvm::PointerType::getUnqual(VMContext), false,
4281 llvm::GlobalValue::ExternalLinkage, nullptr, Name);
4282 return IvarOffsetPointer;
4283}
4284
4287 llvm::Value *BaseValue,
4289 unsigned CVRQualifiers) {
4292 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4293 EmitIvarOffset(CGF, ID, Ivar));
4294}
4295
4301 if (OIVD == next)
4302 return OID;
4303 }
4304
4305
4308
4309 return nullptr;
4310}
4311
4312llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
4317
4318
4319
4320
4321 if (RuntimeVersion < 10 ||
4323 return CGF.Builder.CreateZExtOrBitCast(
4325 Int32Ty,
4327 llvm::PointerType::getUnqual(VMContext),
4328 ObjCIvarOffsetVariable(Interface, Ivar),
4331 PtrDiffTy);
4332 std::string name = "__objc_ivar_offset_value_" +
4335 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4336 if (!Offset) {
4337 auto GV = new llvm::GlobalVariable(TheModule, IntTy,
4338 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4339 llvm::Constant::getNullValue(IntTy), name);
4340 GV->setAlignment(Align.getAsAlign());
4341 Offset = GV;
4342 }
4344 if (Offset->getType() != PtrDiffTy)
4345 Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4346 return Offset;
4347 }
4349 return llvm::ConstantInt::get(PtrDiffTy, Offset, true);
4350}
4351
4355 switch (Runtime.getKind()) {
4357 if (Runtime.getVersion() >= VersionTuple(2, 0))
4358 return new CGObjCGNUstep2(CGM);
4359 return new CGObjCGNUstep(CGM);
4360
4362 return new CGObjCGCC(CGM);
4363
4365 return new CGObjCObjFW(CGM);
4366
4371 llvm_unreachable("these runtimes are not GNU runtimes");
4372 }
4373 llvm_unreachable("bad runtime");
4374}
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.
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.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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 & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
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...
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.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
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()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
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.
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, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
A specialization of Address that requires the address to be an LLVM Constant.
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...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
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
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
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...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
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
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
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
protocol_iterator protocol_end() const
protocol_iterator 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
Interfaces are the core concept in Objective-C for object oriented design.
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()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
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.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
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
The basic abstraction for the target Objective-C runtime.
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.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, 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.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs.
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'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const