LLVM: lib/TextAPI/TextStubV5.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

15#include

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71using namespace llvm;

74

75namespace {

76struct JSONSymbol {

78 std::string Name;

80};

81

82using AttrToTargets = std::map<std::string, TargetList>;

83using TargetsToSymbols =

85

86

87

88

89class InOrderAttrToTargets {

90 using EntryT = std::pair<std::string, TargetList>;

91

92public:

93 void insert(EntryT &&Entry) {

94 auto &Element = get(Entry.first);

95 Element.second = Entry.second;

96 }

97

98 const EntryT *begin() { return Container.begin(); }

99 const EntryT *end() { return Container.end(); }

100

101private:

102 EntryT &get(std::string &Key) {

103 auto *It = find_if(Container,

104 [&Key](EntryT &Input) { return Input.first == Key; });

105 if (It != Container.end())

106 return *It;

107 Container.push_back(EntryT(Key, {}));

108 return Container.back();

109 }

111};

112

113enum TBDKey : size_t {

114 TBDVersion = 0U,

115 MainLibrary,

116 Documents,

117 TargetInfo,

118 Targets,

120 Deployment,

121 Flags,

122 Attributes,

123 InstallName,

125 CompatibilityVersion,

126 Version,

127 SwiftABI,

128 ABI,

129 ParentUmbrella,

130 Umbrella,

131 AllowableClients,

132 Clients,

133 ReexportLibs,

134 Names,

136 Exports,

137 Reexports,

138 Undefineds,

142 ThreadLocal,

143 Globals,

144 ObjCClass,

145 ObjCEHType,

146 ObjCIvar,

148 Paths,

149};

150

151std::array<StringRef, 64> Keys = {

152 "tapi_tbd_version",

153 "main_library",

154 "libraries",

155 "target_info",

156 "targets",

157 "target",

158 "min_deployment",

159 "flags",

160 "attributes",

161 "install_names",

162 "current_versions",

163 "compatibility_versions",

164 "version",

165 "swift_abi",

166 "abi",

167 "parent_umbrellas",

168 "umbrella",

169 "allowable_clients",

170 "clients",

171 "reexported_libraries",

172 "names",

173 "name",

174 "exported_symbols",

175 "reexported_symbols",

176 "undefined_symbols",

177 "data",

178 "text",

179 "weak",

180 "thread_local",

181 "global",

182 "objc_class",

183 "objc_eh_type",

184 "objc_ivar",

185 "rpaths",

186 "paths",

187};

188

190 return {"invalid ", Keys[Key], " section"};

191}

192

194 return {"missing ", Keys[Key], " information"};

195}

196

197class JSONStubError : public llvm::ErrorInfollvm::json::ParseError {

198public:

199 JSONStubError(Twine ErrMsg) : Message(ErrMsg.str()) {}

200

201 void log(llvm::raw_ostream &OS) const override { OS << Message << "\n"; }

202 std::error_code convertToErrorCode() const override {

204 }

205

206private:

207 std::string Message;

208};

209

210template <typename JsonT, typename StubT = JsonT>

213 std::function<std::optional(const Object *, StringRef)> GetValue,

214 std::function<std::optional(JsonT)> Validate = nullptr) {

215 std::optional Val = GetValue(Obj, Keys[Key]);

216 if (!Val)

218

219 if (Validate == nullptr)

220 return static_cast<StubT>(*Val);

221

222 std::optional Result = Validate(*Val);

223 if (Result.has_value())

225 return Result.value();

226}

227

228template <typename JsonT, typename StubT = JsonT>

231 std::function<std::optional(const Object *, StringRef)> const

232 GetValue,

233 StubT DefaultValue, function_ref<std::optional(JsonT)> Validate) {

234 std::optional Val = GetValue(Obj, Keys[Key]);

235 if (!Val)

236 return DefaultValue;

237

238 std::optional Result;

239 Result = Validate(*Val);

240 if (Result.has_value())

242 return Result.value();

243}

244

247 bool IsRequired = false) {

248 const auto *Values = Obj->getArray(Keys[Key]);

249 if (!Values) {

250 if (IsRequired)

253 }

254

255 for (const Value &Val : *Values) {

256 auto ValStr = Val.getAsString();

257 if (!ValStr.has_value())

259 Append(ValStr.value());

260 }

261

263}

264

266

268 auto VersionOrErr = getRequiredValue<int64_t, FileType>(

270 [](int64_t Val) -> std::optional {

271 unsigned Result = Val;

272 if (Result != 5)

273 return std::nullopt;

275 });

276

277 if (!VersionOrErr)

279 return *VersionOrErr;

280}

281

283 const auto *Targets = Section->getArray(Keys[TBDKey::Targets]);

284 if (!Targets)

286

288 for (const Value &JSONTarget : *Targets) {

289 auto TargetStr = JSONTarget.getAsString();

290 if (!TargetStr.has_value())

292 auto TargetOrErr = Target::create(TargetStr.value());

293 if (!TargetOrErr)

295 IFTargets.push_back(*TargetOrErr);

296 }

297 return std::move(IFTargets);

298}

299

301 const Array *Targets = Section->getArray(Keys[TBDKey::TargetInfo]);

302 if (!Targets)

304

306 for (const Value &JSONTarget : *Targets) {

307 const auto *Obj = JSONTarget.getAsObject();

308 if (!Obj)

310 auto TargetStr =

311 getRequiredValue(TBDKey::Target, Obj, &Object::getString);

312 if (!TargetStr)

315 if (!TargetOrErr)

317

318 auto VersionStr = Obj->getString(Keys[TBDKey::Deployment]);

320 if (VersionStr && Version.tryParse(*VersionStr))

322 TargetOrErr->MinDeployment = Version;

323

324

325

328 }

329 return std::move(IFTargets);

330}

331

332Error collectSymbolsFromSegment(const Object *Segment, TargetsToSymbols &Result,

334 auto Err = collectFromArray(

335 TBDKey::Globals, Segment, [&Result, &SectionFlag](StringRef Name) {

337 Result.back().second.emplace_back(Sym);

338 });

339 if (Err)

340 return Err;

341

342 Err = collectFromArray(

343 TBDKey::ObjCClass, Segment, [&Result, &SectionFlag](StringRef Name) {

345 Result.back().second.emplace_back(Sym);

346 });

347 if (Err)

348 return Err;

349

350 Err = collectFromArray(TBDKey::ObjCEHType, Segment,

351 [&Result, &SectionFlag](StringRef Name) {

353 Name.str(), SectionFlag};

354 Result.back().second.emplace_back(Sym);

355 });

356 if (Err)

357 return Err;

358

359 Err = collectFromArray(

360 TBDKey::ObjCIvar, Segment, [&Result, &SectionFlag](StringRef Name) {

362 SectionFlag};

363 Result.back().second.emplace_back(Sym);

364 });

365 if (Err)

366 return Err;

367

369 SectionFlag |

373 Err = collectFromArray(

374 TBDKey::Weak, Segment, [&Result, WeakFlag](StringRef Name) {

376 Result.back().second.emplace_back(Sym);

377 });

378 if (Err)

379 return Err;

380

381 Err = collectFromArray(

382 TBDKey::ThreadLocal, Segment, [&Result, SectionFlag](StringRef Name) {

385 Result.back().second.emplace_back(Sym);

386 });

387 if (Err)

388 return Err;

389

391}

392

394 const Array *Section = File->getArray(Keys[TBDKey::InstallName]);

395 if (!Section)

397

398 assert(!Section->empty() && "unexpected missing install name");

399

400 const auto *Obj = Section->front().getAsObject();

401 if (!Obj)

403

404 return getRequiredValue(TBDKey::Name, Obj, &Object::getString);

405}

406

409

410 const Array *Section = File->getArray(Keys[Key]);

411 if (!Section)

412 return TargetsToSymbols();

413

415 switch (Key) {

416 case TBDKey::Reexports:

418 break;

419 case TBDKey::Undefineds:

421 break;

422 default:

424 break;

425 };

426

427 TargetsToSymbols Result;

429 for (auto Val : *Section) {

430 auto *Obj = Val.getAsObject();

431 if (!Obj)

432 continue;

433

434 auto TargetsOrErr = getTargets(Obj);

435 if (!TargetsOrErr) {

436 MappedTargets = Targets;

438 } else {

439 MappedTargets = *TargetsOrErr;

440 }

441 Result.emplace_back(

442 std::make_pair(std::move(MappedTargets), std::vector()));

443

444 auto *DataSection = Obj->getObject(Keys[TBDKey::Data]);

445 auto *TextSection = Obj->getObject(Keys[TBDKey::Text]);

446

447 if (!DataSection && !TextSection)

449

450 if (DataSection) {

451 auto Err = collectSymbolsFromSegment(DataSection, Result,

453 if (Err)

454 return std::move(Err);

455 }

456 if (TextSection) {

457 auto Err = collectSymbolsFromSegment(TextSection, Result,

459 if (Err)

460 return std::move(Err);

461 }

462 }

463

464 return std::move(Result);

465}

466

467template

470 auto *Section = File->getArray(Keys[Key]);

471 if (!Section)

472 return ReturnT();

473

474 ReturnT Result;

476 for (auto Val : *Section) {

477 auto *Obj = Val.getAsObject();

478 if (!Obj)

479 continue;

480

481 auto TargetsOrErr = getTargets(Obj);

482 if (!TargetsOrErr) {

483 MappedTargets = Targets;

485 } else {

486 MappedTargets = *TargetsOrErr;

487 }

488 auto Err =

489 collectFromArray(SubKey, Obj, [&Result, &MappedTargets](StringRef Key) {

490 Result.insert({Key.str(), MappedTargets});

491 });

492 if (Err)

493 return std::move(Err);

494 }

495

496 return std::move(Result);

497}

498

501 const auto *Umbrella = File->getArray(Keys[TBDKey::ParentUmbrella]);

502 if (!Umbrella)

503 return AttrToTargets();

504

505 AttrToTargets Result;

507 for (auto Val : *Umbrella) {

508 auto *Obj = Val.getAsObject();

509 if (!Obj)

511 getParseErrorMsg(TBDKey::ParentUmbrella));

512

513

514 auto TargetsOrErr = getTargets(Obj);

515 if (!TargetsOrErr) {

516 MappedTargets = Targets;

518 } else {

519 MappedTargets = *TargetsOrErr;

520 }

521

522 auto UmbrellaOrErr =

523 getRequiredValue(TBDKey::Umbrella, Obj, &Object::getString);

524 if (!UmbrellaOrErr)

525 return UmbrellaOrErr.takeError();

526 Result[UmbrellaOrErr->str()] = Targets;

527 }

528 return std::move(Result);

529}

530

532 const Array *Versions = File->getArray(Keys[TBDKey::SwiftABI]);

533 if (!Versions)

534 return 0;

535

536 for (const auto &Val : *Versions) {

537 const auto *Obj = Val.getAsObject();

538 if (!Obj)

540

541

542 return getRequiredValue<int64_t, uint8_t>(TBDKey::ABI, Obj,

544 }

545

546 return 0;

547}

548

550 const Array *Versions = File->getArray(Keys[Key]);

551 if (!Versions)

553

554 for (const auto &Val : *Versions) {

555 const auto *Obj = Val.getAsObject();

556 if (!Obj)

558

559 auto ValidatePV = [](StringRef Version) -> std::optional {

563 return std::nullopt;

564 return PV;

565 };

566

567 return getRequiredValue<StringRef, PackedVersion>(

569 ValidatePV);

570 }

571

573}

574

577 const Array *Section = File->getArray(Keys[TBDKey::Flags]);

578 if (!Section || Section->empty())

579 return Flags;

580

581 for (auto &Val : *Section) {

582

583 const auto *Obj = Val.getAsObject();

584 if (!Obj)

586

587 auto FlagsOrErr =

588 collectFromArray(TBDKey::Attributes, Obj, [&Flags](StringRef Flag) {

589 TBDFlags TBDFlag =

592 .Case("not_app_extension_safe",

595 .Case("not_for_dyld_shared_cache",

598 Flags |= TBDFlag;

599 });

600

601 if (FlagsOrErr)

602 return std::move(FlagsOrErr);

603

604 return Flags;

605 }

606

607 return Flags;

608}

609

610using IFPtr = std::unique_ptr;

612 auto TargetsOrErr = getTargetsSection(File);

613 if (!TargetsOrErr)

614 return TargetsOrErr.takeError();

616

617 auto NameOrErr = getNameSection(File);

618 if (!NameOrErr)

619 return NameOrErr.takeError();

621

622 auto CurrVersionOrErr = getPackedVersion(File, TBDKey::CurrentVersion);

623 if (!CurrVersionOrErr)

624 return CurrVersionOrErr.takeError();

626

627 auto CompVersionOrErr = getPackedVersion(File, TBDKey::CompatibilityVersion);

628 if (!CompVersionOrErr)

629 return CompVersionOrErr.takeError();

631

632 auto SwiftABIOrErr = getSwiftVersion(File);

633 if (!SwiftABIOrErr)

634 return SwiftABIOrErr.takeError();

635 uint8_t SwiftABI = *SwiftABIOrErr;

636

637 auto FlagsOrErr = getFlags(File);

638 if (!FlagsOrErr)

639 return FlagsOrErr.takeError();

640 TBDFlags Flags = *FlagsOrErr;

641

642 auto UmbrellasOrErr = getUmbrellaSection(File, Targets);

643 if (!UmbrellasOrErr)

644 return UmbrellasOrErr.takeError();

645 AttrToTargets Umbrellas = *UmbrellasOrErr;

646

647 auto ClientsOrErr =

648 getLibSection(File, TBDKey::AllowableClients, TBDKey::Clients, Targets);

649 if (!ClientsOrErr)

650 return ClientsOrErr.takeError();

651 AttrToTargets Clients = *ClientsOrErr;

652

653 auto RLOrErr =

654 getLibSection(File, TBDKey::ReexportLibs, TBDKey::Names, Targets);

655 if (!RLOrErr)

656 return RLOrErr.takeError();

657 AttrToTargets ReexportLibs = std::move(*RLOrErr);

658

659 auto RPathsOrErr = getLibSection(

660 File, TBDKey::RPath, TBDKey::Paths, Targets);

661 if (!RPathsOrErr)

662 return RPathsOrErr.takeError();

663 InOrderAttrToTargets RPaths = std::move(*RPathsOrErr);

664

665 auto ExportsOrErr = getSymbolSection(File, TBDKey::Exports, Targets);

666 if (!ExportsOrErr)

667 return ExportsOrErr.takeError();

668 TargetsToSymbols Exports = std::move(*ExportsOrErr);

669

670 auto ReexportsOrErr = getSymbolSection(File, TBDKey::Reexports, Targets);

671 if (!ReexportsOrErr)

672 return ReexportsOrErr.takeError();

673 TargetsToSymbols Reexports = std::move(*ReexportsOrErr);

674

675 auto UndefinedsOrErr = getSymbolSection(File, TBDKey::Undefineds, Targets);

676 if (!UndefinedsOrErr)

677 return UndefinedsOrErr.takeError();

678 TargetsToSymbols Undefineds = std::move(*UndefinedsOrErr);

679

681 F->setInstallName(Name);

682 F->setCurrentVersion(CurrVersion);

683 F->setCompatibilityVersion(CompVersion);

684 F->setSwiftABIVersion(SwiftABI);

686 F->setApplicationExtensionSafe(

690 for (auto &T : Targets)

691 F->addTarget(T);

692 for (auto &[Lib, Targets] : Clients)

693 for (auto Target : Targets)

695 for (auto &[Lib, Targets] : ReexportLibs)

696 for (auto Target : Targets)

697 F->addReexportedLibrary(Lib, Target);

698 for (auto &[Lib, Targets] : Umbrellas)

699 for (auto Target : Targets)

701 for (auto &[Path, Targets] : RPaths)

702 for (auto Target : Targets)

704 for (auto &[Targets, Symbols] : Exports)

705 for (auto &Sym : Symbols)

706 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);

707 for (auto &[Targets, Symbols] : Reexports)

708 for (auto &Sym : Symbols)

709 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);

710 for (auto &[Targets, Symbols] : Undefineds)

711 for (auto &Sym : Symbols)

712 F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);

713

714 return std::move(F);

715}

716

718 std::vector IFs;

719 const Array *Files = File->getArray(Keys[TBDKey::Documents]);

720 if (!Files)

721 return std::move(IFs);

722

723 for (auto Lib : *Files) {

724 auto IFOrErr = parseToInterfaceFile(Lib.getAsObject());

725 if (!IFOrErr)

726 return IFOrErr.takeError();

727 auto IF = std::move(*IFOrErr);

728 IFs.emplace_back(std::move(IF));

729 }

730 return std::move(IFs);

731}

732

733}

734}

735

738 auto ValOrErr = parse(JSON);

739 if (!ValOrErr)

740 return ValOrErr.takeError();

741

742 auto *Root = ValOrErr->getAsObject();

743 auto VersionOrErr = StubParser::getVersion(Root);

744 if (!VersionOrErr)

745 return VersionOrErr.takeError();

747

748 Object *MainLib = Root->getObject(Keys[TBDKey::MainLibrary]);

749 auto IFOrErr = StubParser::parseToInterfaceFile(MainLib);

750 if (!IFOrErr)

751 return IFOrErr.takeError();

752 (*IFOrErr)->setFileType(Version);

753 std::unique_ptr IF(std::move(*IFOrErr));

754

755 auto IFsOrErr = StubParser::getInlinedLibs(Root);

756 if (!IFsOrErr)

757 return IFsOrErr.takeError();

758 for (auto &File : *IFsOrErr) {

759 File->setFileType(Version);

760 IF->addDocument(std::shared_ptr(std::move(File)));

761 }

762 return std::move(IF);

763}

764

765namespace {

766

767template

768bool insertNonEmptyValues(Object &Obj, TBDKey Key, ContainerT &&Contents) {

769 if (Contents.empty())

770 return false;

771 Obj[Keys[Key]] = std::move(Contents);

772 return true;

773}

774

775std::string getFormattedStr(const MachO::Target &Targ) {

776 std::string PlatformStr = Targ.Platform == PLATFORM_MACCATALYST

777 ? "maccatalyst"

780}

781

782template

783std::vectorstd::string serializeTargets(const AggregateT Targets,

785 std::vectorstd::string TargetsStr;

786 if (Targets.size() == ActiveTargets.size())

787 return TargetsStr;

788

790 TargetsStr.emplace_back(getFormattedStr(Target));

791

792 return TargetsStr;

793}

794

795Array serializeTargetInfo(const TargetList &ActiveTargets) {

797 for (const auto Targ : ActiveTargets) {

801 TargetInfo[Keys[TBDKey::Target]] = getFormattedStr(Targ);

803 }

804 return Targets;

805}

806

807template <typename ValueT, typename EntryT = ValueT>

810 return {};

813

814 Container.emplace_back(std::move(ScalarObj));

815 return Container;

816}

817

818using TargetsToValuesMap =

819 std::map<std::vectorstd::string, std::vectorstd::string>;

820

821template

822Array serializeAttrToTargets(AggregateT &Entries, TBDKey Key) {

824 for (const auto &[Targets, Values] : Entries) {

826 insertNonEmptyValues(Obj, TBDKey::Targets, std::move(Targets));

827 Obj[Keys[Key]] = Values;

829 }

830 return Container;

831}

832

833

834

835template <typename ValueT = std::string,

836 typename AggregateT = std::vector<std::pair<MachO::Target, ValueT>>>

837Array serializeField(TBDKey Key, const AggregateT &Values,

838 const TargetList &ActiveTargets, bool IsArray = true) {

839 std::map<ValueT, std::setMachO::Target> Entries;

840 for (const auto &[Target, Val] : Values)

842

843 if (!IsArray) {

844 std::map<std::vectorstd::string, std::string> FinalEntries;

845 for (const auto &[Val, Targets] : Entries)

846 FinalEntries[serializeTargets(Targets, ActiveTargets)] = Val;

847 return serializeAttrToTargets(FinalEntries, Key);

848 }

849

850 TargetsToValuesMap FinalEntries;

851 for (const auto &[Val, Targets] : Entries)

852 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(Val);

853 return serializeAttrToTargets(FinalEntries, Key);

854}

855

856Array serializeField(TBDKey Key, const std::vector &Values,

858 TargetsToValuesMap FinalEntries;

859 for (const auto &Ref : Values) {

860 TargetList Targets{Ref.targets().begin(), Ref.targets().end()};

861 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(

862 Ref.getInstallName());

863 }

864 return serializeAttrToTargets(FinalEntries, Key);

865}

866

867template <

868 typename AggregateT = std::vector<std::pair<MachO::Target, std::string>>>

869Array serializeFieldInInsertionOrder(TBDKey Key, const AggregateT &Values,

872 for (const auto &[Target, Val] : Values)

874

875 TargetsToValuesMap FinalEntries;

876 for (const auto &[Val, Targets] : Entries)

877 FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(

878 Val.str());

879 return serializeAttrToTargets(FinalEntries, Key);

880}

881

882struct SymbolFields {

883 struct SymbolTypes {

884 std::vector Weaks;

885 std::vector Globals;

886 std::vector TLV;

887 std::vector ObjCClasses;

888 std::vector IVars;

889 std::vector EHTypes;

890

891 bool empty() const {

892 return Weaks.empty() && Globals.empty() && TLV.empty() &&

893 ObjCClasses.empty() && IVars.empty() && EHTypes.empty();

894 }

895 };

896 SymbolTypes Data;

897 SymbolTypes Text;

898};

899

902 auto AssignForSymbolType = [](SymbolFields::SymbolTypes &Assignment,

904 switch (Sym->getKind()) {

906 Assignment.ObjCClasses.emplace_back(Sym->getName());

907 return;

909 Assignment.EHTypes.emplace_back(Sym->getName());

910 return;

912 Assignment.IVars.emplace_back(Sym->getName());

913 return;

915 if (Sym->isWeakReferenced() || Sym->isWeakDefined())

916 Assignment.Weaks.emplace_back(Sym->getName());

917 else if (Sym->isThreadLocalValue())

918 Assignment.TLV.emplace_back(Sym->getName());

919 else

920 Assignment.Globals.emplace_back(Sym->getName());

921 return;

922 }

923 }

924 };

925

926 std::map<std::vectorstd::string, SymbolFields> Entries;

927 for (const auto *Sym : Symbols) {

928 std::setMachO::Target Targets{Sym->targets().begin(),

929 Sym->targets().end()};

930 auto JSONTargets = serializeTargets(Targets, ActiveTargets);

931 if (Sym->isData())

932 AssignForSymbolType(Entries[std::move(JSONTargets)].Data, Sym);

933 else if (Sym->isText())

934 AssignForSymbolType(Entries[std::move(JSONTargets)].Text, Sym);

935 else

937 }

938

939 auto InsertSymbolsToJSON = [](Object &SymSection, TBDKey SegmentKey,

940 SymbolFields::SymbolTypes &SymField) {

941 if (SymField.empty())

942 return;

950 insertNonEmptyValues(Segment, TBDKey::Globals, std::move(SymField.Globals));

951 insertNonEmptyValues(Segment, TBDKey::ThreadLocal, std::move(SymField.TLV));

952 insertNonEmptyValues(Segment, TBDKey::Weak, std::move(SymField.Weaks));

953 insertNonEmptyValues(Segment, TBDKey::ObjCClass,

954 std::move(SymField.ObjCClasses));

955 insertNonEmptyValues(Segment, TBDKey::ObjCEHType,

956 std::move(SymField.EHTypes));

957 insertNonEmptyValues(Segment, TBDKey::ObjCIvar, std::move(SymField.IVars));

958 insertNonEmptyValues(SymSection, SegmentKey, std::move(Segment));

959 };

960

961 Array SymbolSection;

962 for (auto &[Targets, Fields] : Entries) {

964 insertNonEmptyValues(AllSyms, TBDKey::Targets, std::move(Targets));

965 InsertSymbolsToJSON(AllSyms, TBDKey::Data, Fields.Data);

966 InsertSymbolsToJSON(AllSyms, TBDKey::Text, Fields.Text);

967 SymbolSection.emplace_back(std::move(AllSyms));

968 }

969

970 return SymbolSection;

971}

972

974

976 if (File->isTwoLevelNamespace())

978 if (File->isApplicationExtensionSafe())

979 Flags.emplace_back("not_app_extension_safe");

980 if (File->hasSimulatorSupport())

981 Flags.emplace_back("sim_support");

982 if (File->isOSLibNotForSharedCache())

983 Flags.emplace_back("not_for_dyld_shared_cache");

984 return serializeScalar(TBDKey::Attributes, std::move(Flags));

985}

986

989

990

991 TargetList ActiveTargets{File->targets().begin(), File->targets().end()};

992 if (!insertNonEmptyValues(Library, TBDKey::TargetInfo,

993 serializeTargetInfo(ActiveTargets)))

995

996 Array Name = serializeScalar(TBDKey::Name, File->getInstallName());

997 if (!insertNonEmptyValues(Library, TBDKey::InstallName, std::move(Name)))

999

1000

1001 Array Flags = serializeFlags(File);

1002 insertNonEmptyValues(Library, TBDKey::Flags, std::move(Flags));

1003

1004 Array CurrentV = serializeScalar<PackedVersion, std::string>(

1005 TBDKey::Version, File->getCurrentVersion(), PackedVersion(1, 0, 0));

1006 insertNonEmptyValues(Library, TBDKey::CurrentVersion, std::move(CurrentV));

1007

1008 Array CompatV = serializeScalar<PackedVersion, std::string>(

1009 TBDKey::Version, File->getCompatibilityVersion(), PackedVersion(1, 0, 0));

1010 insertNonEmptyValues(Library, TBDKey::CompatibilityVersion,

1011 std::move(CompatV));

1012

1013 Array SwiftABI = serializeScalar<uint8_t, int64_t>(

1014 TBDKey::ABI, File->getSwiftABIVersion(), 0u);

1015 insertNonEmptyValues(Library, TBDKey::SwiftABI, std::move(SwiftABI));

1016

1017 Array RPaths = serializeFieldInInsertionOrder(TBDKey::Paths, File->rpaths(),

1018 ActiveTargets);

1019 insertNonEmptyValues(Library, TBDKey::RPath, std::move(RPaths));

1020

1021 Array Umbrellas = serializeField(TBDKey::Umbrella, File->umbrellas(),

1022 ActiveTargets, false);

1023 insertNonEmptyValues(Library, TBDKey::ParentUmbrella, std::move(Umbrellas));

1024

1026 serializeField(TBDKey::Clients, File->allowableClients(), ActiveTargets);

1027 insertNonEmptyValues(Library, TBDKey::AllowableClients, std::move(Clients));

1028

1029 Array ReexportLibs =

1030 serializeField(TBDKey::Names, File->reexportedLibraries(), ActiveTargets);

1031 insertNonEmptyValues(Library, TBDKey::ReexportLibs, std::move(ReexportLibs));

1032

1033

1034 Array Exports = serializeSymbols(File->exports(), ActiveTargets);

1035 insertNonEmptyValues(Library, TBDKey::Exports, std::move(Exports));

1036

1037 Array Reexports = serializeSymbols(File->reexports(), ActiveTargets);

1038 insertNonEmptyValues(Library, TBDKey::Reexports, std::move(Reexports));

1039

1040 if (File->isTwoLevelNamespace()) {

1041 Array Undefineds = serializeSymbols(File->undefineds(), ActiveTargets);

1042 insertNonEmptyValues(Library, TBDKey::Undefineds, std::move(Undefineds));

1043 }

1044

1045 return std::move(Library);

1046}

1047

1051

1052 auto MainLibOrErr = serializeIF(File);

1053 if (!MainLibOrErr)

1054 return MainLibOrErr;

1055 Root[Keys[TBDKey::MainLibrary]] = std::move(*MainLibOrErr);

1056 Array Documents;

1057 for (const auto &Doc : File->documents()) {

1058 auto LibOrErr = serializeIF(Doc.get());

1059 if (!LibOrErr)

1060 return LibOrErr;

1061 Documents.emplace_back(std::move(*LibOrErr));

1062 }

1063

1064 Root[Keys[TBDKey::TBDVersion]] = 5;

1065 insertNonEmptyValues(Root, TBDKey::Documents, std::move(Documents));

1066 return std::move(Root);

1067}

1068

1069}

1070

1074 bool Compact) {

1075 auto TextFile = getJSON(&File, FileKind);

1076 if (!TextFile)

1077 return TextFile.takeError();

1078 if (Compact)

1079 OS << formatv("{0}", Value(std::move(*TextFile))) << "\n";

1080 else

1081 OS << formatv("{0:2}", Value(std::move(*TextFile))) << "\n";

1083}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file supports working with JSON data.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static uint32_t getFlags(const Symbol *Sym)

@ NotApplicationExtensionSafe

Base class for user error types.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

Defines the interface file.

SymbolSet::const_filtered_symbol_range const_filtered_symbol_range

LLVM_ABI std::pair< bool, bool > parse64(StringRef Str)

static LLVM_ABI llvm::Expected< Target > create(StringRef Target)

VersionTuple MinDeployment

This class implements a map that also provides access to all stored values in a deterministic order.

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

LLVM Value Representation.

Represents a version number in the form major[.minor[.subminor[.build]]].

LLVM_ABI std::string getAsString() const

Retrieve a string representation of the version number.

bool empty() const

Determine whether this version information is empty (e.g., all version components are zero).

An efficient, type-erasing, non-owning reference to a callable.

An Array is a JSON array, which contains heterogeneous JSON values.

void emplace_back(Args &&...A)

iterator insert(const_iterator P, const Value &E)

An Object is a JSON object, which maps strings to heterogenous JSON values.

LLVM_ABI const json::Object * getObject(StringRef K) const

LLVM_ABI std::optional< llvm::StringRef > getString(StringRef K) const

LLVM_ABI std::optional< int64_t > getInteger(StringRef K) const

A "cursor" marking a position within a Value.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

Definition TextStubV5.cpp:265

LLVM_ABI std::string getTargetTripleName(const Target &Targ)

FileType

Defines the file type TextAPI files can represent.

@ TBD_V5

Text-based stub file (.tbd) version 5.0.

LLVM_ABI StringRef getArchitectureName(Architecture Arch)

Convert an architecture slice to a string.

LLVM_ABI std::string getOSAndEnvironmentName(PlatformType Platform, std::string Version="")

Error serializeInterfaceFileToJSON(raw_ostream &OS, const InterfaceFile &File, const FileType FileKind, bool Compact)

Definition TextStubV5.cpp:1071

Expected< std::unique_ptr< InterfaceFile > > getInterfaceFileFromJSON(StringRef JSON)

Definition TextStubV5.cpp:737

EncodeKind

Mapping of entry types in TextStubs.

@ ObjectiveCInstanceVariable

@ ThreadLocalValue

Thread-local value symbol.

@ WeakReferenced

Weak referenced symbol.

@ WeakDefined

Weak defined symbol.

SmallVector< Target, 5 > TargetList

LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)

Parses the provided JSON source, or returns a ParseError.

LLVM_ABI iterator begin() const

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

FunctionAddr VTableAddr uintptr_t uintptr_t Version

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

void sort(IteratorTy Start, IteratorTy End)

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

@ Ref

The access may reference the value stored in memory.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

LogicalResult success(bool IsSuccess=true)

Utility function to generate a LogicalResult.

void consumeError(Error Err)

Consume a Error without doing anything.