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 &sectionVec = 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