clang: lib/APINotes/APINotesYAMLCompiler.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

21#include "llvm/ADT/StringSet.h"

22#include "llvm/Support/SourceMgr.h"

23#include "llvm/Support/VersionTuple.h"

24#include "llvm/Support/YAMLTraits.h"

25#include

26#include <type_traits>

27#include

28

29using namespace clang;

30using namespace api_notes;

31

32namespace {

33enum class APIAvailability {

34 Available = 0,

36 NonSwift,

37};

38}

39

40namespace llvm {

41namespace yaml {

42template <> struct ScalarEnumerationTraits {

43 static void enumeration(IO &IO, APIAvailability &AA) {

44 IO.enumCase(AA, "none", APIAvailability::None);

45 IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);

46 IO.enumCase(AA, "available", APIAvailability::Available);

47 }

48};

49}

50}

51

52namespace {

53enum class MethodKind {

55 Instance,

56};

57}

58

59namespace llvm {

60namespace yaml {

61template <> struct ScalarEnumerationTraits {

63 IO.enumCase(MK, "Class", MethodKind::Class);

64 IO.enumCase(MK, "Instance", MethodKind::Instance);

65 }

66};

67}

68}

69

70namespace {

71struct Param {

72 int Position;

73 std::optional NoEscape = false;

74 std::optional Lifetimebound = false;

75 std::optional Nullability;

76 std::optional RetainCountConvention;

77 StringRef Type;

78};

79

80typedef std::vector ParamsSeq;

81}

82

83LLVM_YAML_IS_SEQUENCE_VECTOR(Param)

85

86namespace llvm {

87namespace yaml {

90 IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);

91 IO.enumCase(NK, "Optional", NullabilityKind::Nullable);

92 IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);

93 IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);

94

95

96 IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);

97

98

99 IO.enumCase(NK, "N", NullabilityKind::NonNull);

100 IO.enumCase(NK, "O", NullabilityKind::Nullable);

101 IO.enumCase(NK, "U", NullabilityKind::Unspecified);

102 IO.enumCase(NK, "S", NullabilityKind::Unspecified);

103 }

104};

105

108 IO.enumCase(RCCK, "none", RetainCountConventionKind::None);

109 IO.enumCase(RCCK, "CFReturnsRetained",

110 RetainCountConventionKind::CFReturnsRetained);

111 IO.enumCase(RCCK, "CFReturnsNotRetained",

112 RetainCountConventionKind::CFReturnsNotRetained);

113 IO.enumCase(RCCK, "NSReturnsRetained",

114 RetainCountConventionKind::NSReturnsRetained);

115 IO.enumCase(RCCK, "NSReturnsNotRetained",

116 RetainCountConventionKind::NSReturnsNotRetained);

117 }

118};

119

120template <> struct MappingTraits {

122 IO.mapRequired("Position", P.Position);

123 IO.mapOptional("Nullability", P.Nullability, std::nullopt);

124 IO.mapOptional("RetainCountConvention", P.RetainCountConvention);

125 IO.mapOptional("NoEscape", P.NoEscape);

126 IO.mapOptional("Lifetimebound", P.Lifetimebound);

127 IO.mapOptional("Type", P.Type, StringRef(""));

128 }

129};

130}

131}

132

133namespace {

134typedef std::vector NullabilitySeq;

135

136struct AvailabilityItem {

137 APIAvailability Mode = APIAvailability::Available;

138 StringRef Msg;

139};

140

141

142enum class FactoryAsInitKind {

143

144 Infer,

145

146 AsClassMethod,

147

148 AsInitializer,

149};

150

151struct Method {

153 MethodKind Kind;

154 ParamsSeq Params;

156 std::optional NullabilityOfRet;

157 std::optional RetainCountConvention;

158 AvailabilityItem Availability;

159 std::optional SwiftPrivate;

160 StringRef SwiftName;

161 FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;

162 bool DesignatedInit = false;

164 StringRef ResultType;

165 StringRef SwiftReturnOwnership;

166};

167

168typedef std::vector MethodsSeq;

169}

170

171LLVM_YAML_IS_SEQUENCE_VECTOR(Method)

172

173namespace llvm {

174namespace yaml {

175template <> struct ScalarEnumerationTraits {

176 static void enumeration(IO &IO, FactoryAsInitKind &FIK) {

177 IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);

178 IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);

179 IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);

180 }

181};

182

183template <> struct MappingTraits {

184 static void mapping(IO &IO, Method &M) {

185 IO.mapRequired("Selector", M.Selector);

186 IO.mapRequired("MethodKind", M.Kind);

187 IO.mapOptional("Parameters", M.Params);

188 IO.mapOptional("Nullability", M.Nullability);

189 IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, std::nullopt);

190 IO.mapOptional("RetainCountConvention", M.RetainCountConvention);

191 IO.mapOptional("Availability", M.Availability.Mode,

192 APIAvailability::Available);

193 IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));

194 IO.mapOptional("SwiftPrivate", M.SwiftPrivate);

195 IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));

196 IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);

197 IO.mapOptional("DesignatedInit", M.DesignatedInit, false);

198 IO.mapOptional("Required", M.Required, false);

199 IO.mapOptional("ResultType", M.ResultType, StringRef(""));

200 IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership,

201 StringRef(""));

202 }

203};

204}

205}

206

207namespace {

209 StringRef Name;

210 std::optional Kind;

211 std::optional Nullability;

212 AvailabilityItem Availability;

213 std::optional SwiftPrivate;

214 StringRef SwiftName;

215 std::optional SwiftImportAsAccessors;

216 StringRef Type;

217};

218

219typedef std::vector PropertiesSeq;

220}

221

222LLVM_YAML_IS_SEQUENCE_VECTOR(Property)

223

224namespace llvm {

225namespace yaml {

226template <> struct MappingTraits<Property> {

227 static void mapping(IO &IO, Property &P) {

228 IO.mapRequired("Name", P.Name);

229 IO.mapOptional("PropertyKind", P.Kind);

230 IO.mapOptional("Nullability", P.Nullability, std::nullopt);

231 IO.mapOptional("Availability", P.Availability.Mode,

232 APIAvailability::Available);

233 IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));

234 IO.mapOptional("SwiftPrivate", P.SwiftPrivate);

235 IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));

236 IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);

237 IO.mapOptional("Type", P.Type, StringRef(""));

238 }

239};

240}

241}

242

243namespace {

245 StringRef Name;

246 bool AuditedForNullability = false;

247 AvailabilityItem Availability;

248 std::optional SwiftPrivate;

249 StringRef SwiftName;

250 std::optional SwiftBridge;

251 std::optional NSErrorDomain;

252 std::optional SwiftImportAsNonGeneric;

253 std::optional SwiftObjCMembers;

254 MethodsSeq Methods;

255 PropertiesSeq Properties;

256};

257

258typedef std::vector ClassesSeq;

259}

260

261LLVM_YAML_IS_SEQUENCE_VECTOR(Class)

262

263namespace llvm {

264namespace yaml {

265template <> struct MappingTraits<Class> {

267 IO.mapRequired("Name", C.Name);

268 IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);

269 IO.mapOptional("Availability", C.Availability.Mode,

270 APIAvailability::Available);

271 IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));

272 IO.mapOptional("SwiftPrivate", C.SwiftPrivate);

273 IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));

274 IO.mapOptional("SwiftBridge", C.SwiftBridge);

275 IO.mapOptional("NSErrorDomain", C.NSErrorDomain);

276 IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);

277 IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);

278 IO.mapOptional("Methods", C.Methods);

279 IO.mapOptional("Properties", C.Properties);

280 }

281};

282}

283}

284

285namespace {

287 StringRef Name;

288 ParamsSeq Params;

290 std::optional NullabilityOfRet;

291 std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;

292 AvailabilityItem Availability;

293 std::optional SwiftPrivate;

294 StringRef SwiftName;

295 StringRef Type;

296 StringRef ResultType;

297 StringRef SwiftReturnOwnership;

298};

299

300typedef std::vector FunctionsSeq;

301}

302

303LLVM_YAML_IS_SEQUENCE_VECTOR(Function)

304

305namespace llvm {

306namespace yaml {

307template <> struct MappingTraits<Function> {

308 static void mapping(IO &IO, Function &F) {

309 IO.mapRequired("Name", F.Name);

310 IO.mapOptional("Parameters", F.Params);

311 IO.mapOptional("Nullability", F.Nullability);

312 IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, std::nullopt);

313 IO.mapOptional("RetainCountConvention", F.RetainCountConvention);

314 IO.mapOptional("Availability", F.Availability.Mode,

315 APIAvailability::Available);

316 IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));

317 IO.mapOptional("SwiftPrivate", F.SwiftPrivate);

318 IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));

319 IO.mapOptional("ResultType", F.ResultType, StringRef(""));

320 IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership,

321 StringRef(""));

322 }

323};

324}

325}

326

327namespace {

328struct GlobalVariable {

329 StringRef Name;

330 std::optional Nullability;

331 AvailabilityItem Availability;

332 std::optional SwiftPrivate;

333 StringRef SwiftName;

334 StringRef Type;

335};

336

337typedef std::vector GlobalVariablesSeq;

338}

339

340LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)

341

342namespace llvm {

343namespace yaml {

344template <> struct MappingTraits {

345 static void mapping(IO &IO, GlobalVariable &GV) {

346 IO.mapRequired("Name", GV.Name);

347 IO.mapOptional("Nullability", GV.Nullability, std::nullopt);

348 IO.mapOptional("Availability", GV.Availability.Mode,

349 APIAvailability::Available);

350 IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));

351 IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);

352 IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));

353 IO.mapOptional("Type", GV.Type, StringRef(""));

354 }

355};

356}

357}

358

359namespace {

361 StringRef Name;

362 AvailabilityItem Availability;

363 std::optional SwiftPrivate;

364 StringRef SwiftName;

365};

366

367typedef std::vector EnumConstantsSeq;

368}

369

370LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)

371

372namespace llvm {

373namespace yaml {

374template <> struct MappingTraits {

375 static void mapping(IO &IO, EnumConstant &EC) {

376 IO.mapRequired("Name", EC.Name);

377 IO.mapOptional("Availability", EC.Availability.Mode,

378 APIAvailability::Available);

379 IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));

380 IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);

381 IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));

382 }

383};

384}

385}

386

387namespace {

388

389enum class EnumConvenienceAliasKind {

390

392

393 CFEnum,

394

395 CFOptions,

396

397 CFClosedEnum

398};

399}

400

401namespace llvm {

402namespace yaml {

403template <> struct ScalarEnumerationTraits {

404 static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {

405 IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);

406 IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);

407 IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);

408 IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);

409 IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);

410 IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);

411 IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);

412 }

413};

414}

415}

416

417namespace {

419 StringRef Name;

420 std::optional Nullability;

421 AvailabilityItem Availability;

422 std::optional SwiftPrivate;

423 StringRef SwiftName;

424 StringRef Type;

425};

426

427typedef std::vector FieldsSeq;

428}

429

430LLVM_YAML_IS_SEQUENCE_VECTOR(Field)

431

432namespace llvm {

433namespace yaml {

434template <> struct MappingTraits {

435 static void mapping(IO &IO, Field &F) {

436 IO.mapRequired("Name", F.Name);

437 IO.mapOptional("Nullability", F.Nullability, std::nullopt);

438 IO.mapOptional("Availability", F.Availability.Mode,

439 APIAvailability::Available);

440 IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));

441 IO.mapOptional("SwiftPrivate", F.SwiftPrivate);

442 IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));

443 IO.mapOptional("Type", F.Type, StringRef(""));

444 }

445};

446}

447}

448

449namespace {

450struct Tag;

451typedef std::vector TagsSeq;

452

453struct Tag {

454 StringRef Name;

455 AvailabilityItem Availability;

456 StringRef SwiftName;

457 std::optional SwiftPrivate;

458 std::optional SwiftBridge;

459 std::optional NSErrorDomain;

460 std::optionalstd::string SwiftImportAs;

461 std::optionalstd::string SwiftRetainOp;

462 std::optionalstd::string SwiftReleaseOp;

463 std::optionalstd::string SwiftConformance;

464 std::optional EnumExtensibility;

465 std::optional FlagEnum;

466 std::optional EnumConvenienceKind;

467 std::optional SwiftCopyable;

468 std::optional SwiftEscapable;

469 FunctionsSeq Methods;

470 FieldsSeq Fields;

471

472

473

474 TagsSeq Tags;

475};

476}

477

478LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)

479

480namespace llvm {

481namespace yaml {

484 IO.enumCase(EEK, "none", EnumExtensibilityKind::None);

485 IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);

486 IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);

487 }

488};

489

490template <> struct MappingTraits<Tag> {

492 IO.mapRequired("Name", T.Name);

493 IO.mapOptional("Availability", T.Availability.Mode,

494 APIAvailability::Available);

495 IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));

496 IO.mapOptional("SwiftPrivate", T.SwiftPrivate);

497 IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));

498 IO.mapOptional("SwiftBridge", T.SwiftBridge);

499 IO.mapOptional("NSErrorDomain", T.NSErrorDomain);

500 IO.mapOptional("SwiftImportAs", T.SwiftImportAs);

501 IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);

502 IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);

503 IO.mapOptional("SwiftConformsTo", T.SwiftConformance);

504 IO.mapOptional("EnumExtensibility", T.EnumExtensibility);

505 IO.mapOptional("FlagEnum", T.FlagEnum);

506 IO.mapOptional("EnumKind", T.EnumConvenienceKind);

507 IO.mapOptional("SwiftCopyable", T.SwiftCopyable);

508 IO.mapOptional("SwiftEscapable", T.SwiftEscapable);

509 IO.mapOptional("Methods", T.Methods);

510 IO.mapOptional("Fields", T.Fields);

511 IO.mapOptional("Tags", T.Tags);

512 }

513};

514}

515}

516

517namespace {

518struct Typedef {

519 StringRef Name;

520 AvailabilityItem Availability;

521 StringRef SwiftName;

522 std::optional SwiftPrivate;

523 std::optional SwiftBridge;

524 std::optional NSErrorDomain;

525 std::optional SwiftType;

526};

527

528typedef std::vector TypedefsSeq;

529}

530

531LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)

532

533namespace llvm {

534namespace yaml {

537 IO.enumCase(SWK, "none", SwiftNewTypeKind::None);

538 IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);

539 IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);

540 }

541};

542

543template <> struct MappingTraits {

544 static void mapping(IO &IO, Typedef &T) {

545 IO.mapRequired("Name", T.Name);

546 IO.mapOptional("Availability", T.Availability.Mode,

547 APIAvailability::Available);

548 IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));

549 IO.mapOptional("SwiftPrivate", T.SwiftPrivate);

550 IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));

551 IO.mapOptional("SwiftBridge", T.SwiftBridge);

552 IO.mapOptional("NSErrorDomain", T.NSErrorDomain);

553 IO.mapOptional("SwiftWrapper", T.SwiftType);

554 }

555};

556}

557}

558

559namespace {

561typedef std::vector NamespacesSeq;

562

563struct TopLevelItems {

564 ClassesSeq Classes;

565 ClassesSeq Protocols;

566 FunctionsSeq Functions;

567 GlobalVariablesSeq Globals;

568 EnumConstantsSeq EnumConstants;

569 TagsSeq Tags;

570 TypedefsSeq Typedefs;

571 NamespacesSeq Namespaces;

572};

573}

574

575namespace llvm {

576namespace yaml {

578 IO.mapOptional("Classes", TLI.Classes);

579 IO.mapOptional("Protocols", TLI.Protocols);

580 IO.mapOptional("Functions", TLI.Functions);

581 IO.mapOptional("Globals", TLI.Globals);

582 IO.mapOptional("Enumerators", TLI.EnumConstants);

583 IO.mapOptional("Tags", TLI.Tags);

584 IO.mapOptional("Typedefs", TLI.Typedefs);

585 IO.mapOptional("Namespaces", TLI.Namespaces);

586}

587}

588}

589

590namespace {

592 StringRef Name;

593 AvailabilityItem Availability;

594 StringRef SwiftName;

595 std::optional SwiftPrivate;

596 TopLevelItems Items;

597};

598}

599

600LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)

601

602namespace llvm {

603namespace yaml {

605 static void mapping(IO &IO, Namespace &T) {

606 IO.mapRequired("Name", T.Name);

607 IO.mapOptional("Availability", T.Availability.Mode,

608 APIAvailability::Available);

609 IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));

610 IO.mapOptional("SwiftPrivate", T.SwiftPrivate);

611 IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));

613 }

614};

615}

616}

617

618namespace {

619struct Versioned {

620 VersionTuple Version;

621 TopLevelItems Items;

622};

623

624typedef std::vector VersionedSeq;

625}

626

627LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)

628

629namespace llvm {

630namespace yaml {

631template <> struct MappingTraits {

632 static void mapping(IO &IO, Versioned &V) {

633 IO.mapRequired("Version", V.Version);

635 }

636};

637}

638}

639

640namespace {

642 StringRef Name;

643 AvailabilityItem Availability;

644 TopLevelItems TopLevel;

645 VersionedSeq SwiftVersions;

646

647 std::optional SwiftInferImportAsMember;

648

649#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

650 LLVM_DUMP_METHOD void dump() ;

651#endif

652};

653}

654

655namespace llvm {

656namespace yaml {

657template <> struct MappingTraits<Module> {

659 IO.mapRequired("Name", M.Name);

660 IO.mapOptional("Availability", M.Availability.Mode,

661 APIAvailability::Available);

662 IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));

663 IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);

665 IO.mapOptional("SwiftVersions", M.SwiftVersions);

666 }

667};

668}

669}

670

671#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

672LLVM_DUMP_METHOD void Module::dump() {

673 llvm::yaml::Output OS(llvm::errs());

674 OS << *this;

675}

676#endif

677

678namespace {

679bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,

680 void *DiagContext) {

681 llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);

682 IS >> M;

683 return static_cast<bool>(IS.error());

684}

685}

686

688 llvm::raw_ostream &OS) {

690 if (parseAPINotes(YI, M, nullptr, nullptr))

691 return true;

692

693 llvm::yaml::Output YOS(OS);

694 YOS << M;

695

696 return false;

697}

698

699namespace {

700using namespace api_notes;

701

702class YAMLConverter {

705 llvm::raw_ostream &OS;

706 llvm::SourceMgr::DiagHandlerTy DiagHandler;

707 void *DiagHandlerCtxt;

708 bool ErrorOccured;

709

710

711 bool emitError(llvm::Twine Message) {

712 DiagHandler(

713 llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()),

714 DiagHandlerCtxt);

715 ErrorOccured = true;

716 return true;

717 }

718

719public:

720 YAMLConverter(const Module &TheModule, const FileEntry *SourceFile,

721 llvm::raw_ostream &OS,

722 llvm::SourceMgr::DiagHandlerTy DiagHandler,

723 void *DiagHandlerCtxt)

724 : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),

725 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),

726 ErrorOccured(false) {}

727

728 void convertAvailability(const AvailabilityItem &Availability,

730

731 CEI.Unavailable = (Availability.Mode == APIAvailability::None);

732 CEI.UnavailableInSwift = (Availability.Mode == APIAvailability::NonSwift);

735 } else {

736 if (!Availability.Msg.empty())

737 emitError(llvm::Twine("availability message for available API '") +

738 APIName + "' will not be used");

739 }

740 }

741

742 void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo,

743 std::optional &thisOrSelf) {

744 for (const auto &P : Params) {

746 if (P.Nullability)

750 PI.setType(std::string(P.Type));

752 if (static_cast<int>(OutInfo.Params.size()) <= P.Position)

753 OutInfo.Params.resize(P.Position + 1);

754 if (P.Position == -1)

755 thisOrSelf = PI;

756 else if (P.Position >= 0)

757 OutInfo.Params[P.Position] |= PI;

758 else

759 emitError("invalid parameter position " + llvm::itostr(P.Position));

760 }

761 }

762

763 void convertNullability(const NullabilitySeq &Nullability,

764 std::optional ReturnNullability,

765 FunctionInfo &OutInfo, llvm::StringRef APIName) {

767 emitError(llvm::Twine("nullability info for '") + APIName +

768 "' does not fit");

769 return;

770 }

771

772 bool audited = false;

773 unsigned int idx = 1;

774 for (const auto &N : Nullability)

776 audited = Nullability.size() > 0 || ReturnNullability;

777 if (audited)

779 ReturnNullability.value_or(NullabilityKind::NonNull));

780 if (!audited)

781 return;

784 }

785

786

787 template

788 void convertCommonEntity(const T &Common, CommonEntityInfo &Info,

789 StringRef APIName) {

790 convertAvailability(Common.Availability, Info, APIName);

792 Info.SwiftName = std::string(Common.SwiftName);

793 }

794

795

796 template

797 void convertCommonType(const T &Common, CommonTypeInfo &Info,

798 StringRef APIName) {

799 convertCommonEntity(Common, Info, APIName);

800 if (Common.SwiftBridge)

801 Info.setSwiftBridge(std::string(*Common.SwiftBridge));

803 }

804

805

806 void convertMethod(const Method &M, ContextID ClassID, StringRef ClassName,

807 VersionTuple SwiftVersion) {

809 convertCommonEntity(M, MI, M.Selector);

810

811

812 bool takesArguments = M.Selector.ends_with(":");

813

814

816 M.Selector.split(Args, ":", -1, false);

817 if (!takesArguments && Args.size() > 1) {

818 emitError("selector '" + M.Selector + "' is missing a ':' at the end");

819 return;

820 }

821

822

824 Selector.NumArgs = !takesArguments ? 0 : Args.size();

826

827

830 if (M.FactoryAsInit != FactoryAsInitKind::Infer)

831 emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");

832

833 MI.ResultType = std::string(M.ResultType);

835

836

837 convertParams(M.Params, MI, MI.Self);

838

839

840 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);

841

843

844

846 SwiftVersion);

847 }

848

849 template

850 void convertVariable(const T &Entity, VariableInfo &VI) {

851 convertAvailability(Entity.Availability, VI, Entity.Name);

853 VI.SwiftName = std::string(Entity.SwiftName);

854 if (Entity.Nullability)

856 VI.setType(std::string(Entity.Type));

857 }

858

859 void convertContext(std::optional ParentContextID, const Class &C,

861

863 convertCommonType(C, CI, C.Name);

864

865 if (C.AuditedForNullability)

867 if (C.SwiftImportAsNonGeneric)

869 if (C.SwiftObjCMembers)

871

873 Writer.addContext(ParentContextID, C.Name, Kind, CI, SwiftVersion);

874

875

876 llvm::StringMap<std::pair<bool, bool>> KnownMethods;

877 for (const auto &method : C.Methods) {

878

880 bool &Known = IsInstanceMethod ? KnownMethods[method.Selector].first

881 : KnownMethods[method.Selector].second;

882 if (Known) {

883 emitError(llvm::Twine("duplicate definition of method '") +

884 (IsInstanceMethod ? "-" : "+") + "[" + C.Name + " " +

885 method.Selector + "]'");

886 continue;

887 }

888 Known = true;

889

890 convertMethod(method, CtxID, C.Name, SwiftVersion);

891 }

892

893

894 llvm::StringSet<> KnownInstanceProperties;

895 llvm::StringSet<> KnownClassProperties;

896 for (const auto &Property : C.Properties) {

897

898 if ((Property.Kind || *Property.Kind == MethodKind::Instance) &&

899 !KnownInstanceProperties.insert(Property.Name).second) {

900 emitError(llvm::Twine("duplicate definition of instance property '") +

901 C.Name + "." + Property.Name + "'");

902 continue;

903 }

904

905 if ((Property.Kind || *Property.Kind == MethodKind::Class) &&

906 !KnownClassProperties.insert(Property.Name).second) {

907 emitError(llvm::Twine("duplicate definition of class property '") +

908 C.Name + "." + Property.Name + "'");

909 continue;

910 }

911

912

914 convertVariable(Property, PI);

915 if (Property.SwiftImportAsAccessors)

917

918

921 *Property.Kind == MethodKind::Instance, PI,

922 SwiftVersion);

923 } else {

926 }

927 }

928 }

929

930 void convertNamespaceContext(std::optional ParentContextID,

931 const Namespace &TheNamespace,

932 VersionTuple SwiftVersion) {

933

935 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);

936

938 Writer.addContext(ParentContextID, TheNamespace.Name,

939 ContextKind::Namespace, CI, SwiftVersion);

940

941 convertTopLevelItems(Context(CtxID, ContextKind::Namespace),

942 TheNamespace.Items, SwiftVersion);

943 }

944

945 template

946 void convertFunction(const Function &Function, FuncOrMethodInfo &FI) {

947 convertAvailability(Function.Availability, FI, Function.Name);

948 FI.setSwiftPrivate(Function.SwiftPrivate);

949 FI.SwiftName = std::string(Function.SwiftName);

950 std::optional This;

951 convertParams(Function.Params, FI, This);

952 if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)

953 FI.This = This;

954 else if (This)

955 emitError("implicit instance parameter is only permitted on C++ and "

956 "Objective-C methods");

957 convertNullability(Function.Nullability, Function.NullabilityOfRet, FI,

959 FI.ResultType = std::string(Function.ResultType);

960 FI.SwiftReturnOwnership = std::string(Function.SwiftReturnOwnership);

961 FI.setRetainCountConvention(Function.RetainCountConvention);

962 }

963

964 void convertTagContext(std::optional ParentContext, const Tag &T,

965 VersionTuple SwiftVersion) {

967 std::optional ParentContextID =

968 ParentContext ? std::optional(ParentContext->id)

969 : std::nullopt;

970 convertCommonType(T, TI, T.Name);

971

972 if ((T.SwiftRetainOp || T.SwiftReleaseOp) && T.SwiftImportAs) {

973 emitError(llvm::Twine("should declare SwiftImportAs to use "

974 "SwiftRetainOp and SwiftReleaseOp (for ") +

975 T.Name + ")");

976 return;

977 }

978 if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) {

979 emitError(llvm::Twine("should declare both SwiftReleaseOp and "

980 "SwiftRetainOp (for ") +

981 T.Name + ")");

982 return;

983 }

984

985 if (T.SwiftImportAs)

987 if (T.SwiftRetainOp)

989 if (T.SwiftReleaseOp)

991 if (T.SwiftConformance)

993

994 if (T.SwiftCopyable)

996 if (T.SwiftEscapable)

998

999 if (T.EnumConvenienceKind) {

1000 if (T.EnumExtensibility) {

1001 emitError(

1002 llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +

1003 T.Name + ")");

1004 return;

1005 }

1006 if (T.FlagEnum) {

1007 emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +

1008 T.Name + ")");

1009 return;

1010 }

1011 switch (*T.EnumConvenienceKind) {

1012 case EnumConvenienceAliasKind::None:

1015 break;

1016 case EnumConvenienceAliasKind::CFEnum:

1019 break;

1020 case EnumConvenienceAliasKind::CFOptions:

1023 break;

1024 case EnumConvenienceAliasKind::CFClosedEnum:

1027 break;

1028 }

1029 } else {

1032 }

1033

1034 Writer.addTag(ParentContext, T.Name, TI, SwiftVersion);

1035

1037 auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag,

1038 CI, SwiftVersion);

1039 Context TagCtx(TagCtxID, ContextKind::Tag);

1040

1041 for (const auto &Field : T.Fields) {

1043 convertVariable(Field, FI);

1044 Writer.addField(TagCtxID, Field.Name, FI, SwiftVersion);

1045 }

1046

1047 for (const auto &CXXMethod : T.Methods) {

1049 convertFunction(CXXMethod, MI);

1050 Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);

1051 }

1052

1053

1054 for (const auto &Tag : T.Tags)

1055 convertTagContext(TagCtx, Tag, SwiftVersion);

1056 }

1057

1058 void convertTopLevelItems(std::optional Ctx,

1059 const TopLevelItems &TLItems,

1060 VersionTuple SwiftVersion) {

1061 std::optional CtxID =

1062 Ctx ? std::optional(Ctx->id) : std::nullopt;

1063

1064

1065 llvm::StringSet<> KnownClasses;

1066 for (const auto &Class : TLItems.Classes) {

1067

1068 if (!KnownClasses.insert(Class.Name).second) {

1069 emitError(llvm::Twine("multiple definitions of class '") + Class.Name +

1070 "'");

1071 continue;

1072 }

1073

1074 convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);

1075 }

1076

1077

1078 llvm::StringSet<> KnownProtocols;

1079 for (const auto &Protocol : TLItems.Protocols) {

1080

1081 if (!KnownProtocols.insert(Protocol.Name).second) {

1082 emitError(llvm::Twine("multiple definitions of protocol '") +

1084 continue;

1085 }

1086

1087 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);

1088 }

1089

1090

1091 llvm::StringSet<> KnownNamespaces;

1092 for (const auto &Namespace : TLItems.Namespaces) {

1093

1094 if (!KnownNamespaces.insert(Namespace.Name).second) {

1095 emitError(llvm::Twine("multiple definitions of namespace '") +

1097 continue;

1098 }

1099

1100 convertNamespaceContext(CtxID, Namespace, SwiftVersion);

1101 }

1102

1103

1104 llvm::StringSet<> KnownGlobals;

1105 for (const auto &Global : TLItems.Globals) {

1106

1107 if (!KnownGlobals.insert(Global.Name).second) {

1108 emitError(llvm::Twine("multiple definitions of global variable '") +

1110 continue;

1111 }

1112

1114 convertVariable(Global, GVI);

1116 }

1117

1118

1119 llvm::StringSet<> KnownFunctions;

1120 for (const auto &Function : TLItems.Functions) {

1121

1122 if (!KnownFunctions.insert(Function.Name).second) {

1123 emitError(llvm::Twine("multiple definitions of global function '") +

1125 continue;

1126 }

1127

1129 convertFunction(Function, GFI);

1131 }

1132

1133

1134 llvm::StringSet<> KnownEnumConstants;

1135 for (const auto &EnumConstant : TLItems.EnumConstants) {

1136

1137 if (!KnownEnumConstants.insert(EnumConstant.Name).second) {

1138 emitError(llvm::Twine("multiple definitions of enumerator '") +

1140 continue;

1141 }

1142

1148 }

1149

1150

1151 llvm::StringSet<> KnownTags;

1152 for (const auto &Tag : TLItems.Tags) {

1153

1154 if (!KnownTags.insert(Tag.Name).second) {

1155 emitError(llvm::Twine("multiple definitions of tag '") + Tag.Name +

1156 "'");

1157 continue;

1158 }

1159

1160 convertTagContext(Ctx, Tag, SwiftVersion);

1161 }

1162

1163

1164 llvm::StringSet<> KnownTypedefs;

1165 for (const auto &Typedef : TLItems.Typedefs) {

1166

1167 if (!KnownTypedefs.insert(Typedef.Name).second) {

1168 emitError(llvm::Twine("multiple definitions of typedef '") +

1169 Typedef.Name + "'");

1170 continue;

1171 }

1172

1174 convertCommonType(Typedef, TInfo, Typedef.Name);

1176

1177 Writer.addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);

1178 }

1179 }

1180

1181 bool convertModule() {

1182

1183 convertTopLevelItems( std::nullopt, M.TopLevel,

1184 VersionTuple());

1185

1186

1187 for (const auto &Versioned : M.SwiftVersions)

1188 convertTopLevelItems( std::nullopt, Versioned.Items,

1189 Versioned.Version);

1190

1191 if (!ErrorOccured)

1193

1194 return ErrorOccured;

1195 }

1196};

1197}

1198

1200 llvm::raw_ostream &OS,

1201 llvm::SourceMgr::DiagHandlerTy DiagHandler,

1202 void *DiagHandlerCtxt) {

1203 YAMLConverter C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);

1204 return C.convertModule();

1205}

1206

1207

1209 Diag.print(nullptr, llvm::errs());

1210}

1211

1214 llvm::raw_ostream &OS,

1215 llvm::SourceMgr::DiagHandlerTy DiagHandler,

1216 void *DiagHandlerCtxt) {

1218

1219 if (!DiagHandler)

1221

1222 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))

1223 return true;

1224

1225 return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);

1226}

static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context)

Simple diagnostic handler that prints diagnostics to standard error.

static bool compile(const Module &M, const FileEntry *SourceFile, llvm::raw_ostream &OS, llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)

enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Defines various enumerations that describe declaration and type specifiers.

Cached information about one file (either on disk or in the virtual file system).

Describes a module or submodule.

std::string Name

The name of this module.

void dump() const

Dump the contents of this module to the given output stream.

Smart pointer class that efficiently represents Objective-C method names.

The base class of the type hierarchy.

A class that writes API notes data to a binary representation that can be read by the APINotesReader.

void addObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, bool IsInstanceMethod, const ObjCMethodInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a specific Objective-C method.

void addEnumConstant(llvm::StringRef Name, const EnumConstantInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about an enumerator.

ContextID addContext(std::optional< ContextID > ParentCtxID, llvm::StringRef Name, ContextKind Kind, const ContextInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a specific Objective-C class or protocol or a C++ namespace.

void addGlobalFunction(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalFunctionInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a global function.

void addObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstanceProperty, const ObjCPropertyInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a specific Objective-C property.

void addField(ContextID CtxID, llvm::StringRef Name, const FieldInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a specific C record field.

void addGlobalVariable(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalVariableInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a global variable.

void addTypedef(std::optional< Context > Ctx, llvm::StringRef Name, const TypedefInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a typedef.

void writeToStream(llvm::raw_ostream &OS)

void addCXXMethod(ContextID CtxID, llvm::StringRef Name, const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a specific C++ method.

void addTag(std::optional< Context > Ctx, llvm::StringRef Name, const TagInfo &Info, llvm::VersionTuple SwiftVersion)

Add information about a tag (struct/union/enum/C++ class).

Describes API notes data for a C++ method.

Describes API notes data for any entity.

unsigned UnavailableInSwift

Whether this entity is marked unavailable in Swift.

unsigned Unavailable

Whether this entity is marked unavailable.

std::string SwiftName

Swift name of this entity.

void setSwiftPrivate(std::optional< bool > Private)

std::string UnavailableMsg

Message to use when this entity is unavailable.

Describes API notes for types.

void setNSErrorDomain(const std::optional< std::string > &Domain)

void setSwiftBridge(std::optional< std::string > SwiftType)

Opaque context ID used to refer to an Objective-C class or protocol or a C++ namespace.

Describes API notes data for an Objective-C class or protocol or a C++ namespace.

void setDefaultNullability(NullabilityKind Kind)

Set the default nullability for properties and methods of this class.

void setSwiftObjCMembers(std::optional< bool > Value)

void setSwiftImportAsNonGeneric(std::optional< bool > Value)

Describes API notes data for an enumerator.

Describes API notes data for a C/C++ record field.

API notes for a function or method.

std::string SwiftReturnOwnership

Ownership convention for return value.

void addTypeInfo(unsigned index, NullabilityKind kind)

void setRetainCountConvention(std::optional< RetainCountConventionKind > Value)

std::vector< ParamInfo > Params

The function parameters.

unsigned NumAdjustedNullable

Number of types whose nullability is encoded with the NullabilityPayload.

std::string ResultType

The result type of this function, as a C type.

static unsigned getMaxNullabilityIndex()

unsigned NullabilityAudited

Whether the signature has been audited with respect to nullability.

Describes API notes data for a global function.

Describes API notes data for a global variable.

Describes API notes data for an Objective-C method.

unsigned DesignatedInit

Whether this is a designated initializer of its class.

std::optional< ParamInfo > Self

unsigned RequiredInit

Whether this is a required initializer.

Describes API notes data for an Objective-C property.

void setSwiftImportAsAccessors(std::optional< bool > Value)

Describes a function or method parameter.

void setNoEscape(std::optional< bool > Value)

void setLifetimebound(std::optional< bool > Value)

void setRetainCountConvention(std::optional< RetainCountConventionKind > Value)

Describes API notes data for a tag.

std::optional< std::string > SwiftReleaseOp

std::optional< std::string > SwiftRetainOp

std::optional< std::string > SwiftImportAs

std::optional< EnumExtensibilityKind > EnumExtensibility

void setSwiftCopyable(std::optional< bool > Value)

void setSwiftEscapable(std::optional< bool > Value)

void setFlagEnum(std::optional< bool > Value)

std::optional< std::string > SwiftConformance

The Swift protocol that this type should be automatically conformed to.

Describes API notes data for a typedef.

std::optional< SwiftNewTypeKind > SwiftWrapper

API notes for a variable/property.

void setNullabilityAudited(NullabilityKind kind)

void setType(const std::string &type)

RetainCountConventionKind

bool compileAPINotes(llvm::StringRef YAMLInput, const FileEntry *SourceFile, llvm::raw_ostream &OS, llvm::SourceMgr::DiagHandlerTy DiagHandler=nullptr, void *DiagHandlerCtxt=nullptr)

Converts API notes from YAML format to binary format.

SwiftNewTypeKind

The kind of a swift_wrapper/swift_newtype.

EnumExtensibilityKind

The payload for an enum_extensibility attribute.

bool parseAndDumpAPINotes(llvm::StringRef YI, llvm::raw_ostream &OS)

Parses the APINotes YAML content and writes the representation back to the specified stream.

bool This(InterpState &S, CodePtr OpPC)

The JSON file list parser is used to communicate input to InstallAPI.

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

NullabilityKind

Describes the nullability of a particular type.

@ Property

The type of a property.

const FunctionProtoType * T

@ Class

The "class" keyword introduces the elaborated-type-specifier.

static void mapTopLevelItems(IO &IO, TopLevelItems &TLI)

Diagnostic wrappers for TextAPI types for error reporting.

A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...

static void mapping(IO &IO, Class &C)

static void mapping(IO &IO, EnumConstant &EC)

static void mapping(IO &IO, Field &F)

static void mapping(IO &IO, Function &F)

static void mapping(IO &IO, GlobalVariable &GV)

static void mapping(IO &IO, Method &M)

static void mapping(IO &IO, Module &M)

static void mapping(IO &IO, Namespace &T)

static void mapping(IO &IO, Param &P)

static void mapping(IO &IO, Property &P)

static void mapping(IO &IO, Tag &T)

static void mapping(IO &IO, Typedef &T)

static void mapping(IO &IO, Versioned &V)

static void enumeration(IO &IO, APIAvailability &AA)

static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK)

static void enumeration(IO &IO, EnumExtensibilityKind &EEK)

static void enumeration(IO &IO, FactoryAsInitKind &FIK)

static void enumeration(IO &IO, MethodKind &MK)

static void enumeration(IO &IO, NullabilityKind &NK)

static void enumeration(IO &IO, RetainCountConventionKind &RCCK)

static void enumeration(IO &IO, SwiftNewTypeKind &SWK)