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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

18#include "llvm/ADT/Hashing.h"

19#include "llvm/Bitstream/BitstreamReader.h"

20#include "llvm/Support/DJB.h"

21#include "llvm/Support/OnDiskHashTable.h"

22

25using namespace llvm::support;

26

27namespace {

28

29llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) {

30 uint8_t NumVersions = (*Data++) & 0x03;

31

32 unsigned Major = endian::readNext<uint32_t, llvm::endianness::little>(Data);

33 if (NumVersions == 0)

34 return llvm::VersionTuple(Major);

35

36 unsigned Minor = endian::readNext<uint32_t, llvm::endianness::little>(Data);

37 if (NumVersions == 1)

38 return llvm::VersionTuple(Major, Minor);

39

40 unsigned Subminor =

41 endian::readNext<uint32_t, llvm::endianness::little>(Data);

42 if (NumVersions == 2)

43 return llvm::VersionTuple(Major, Minor, Subminor);

44

45 unsigned Build = endian::readNext<uint32_t, llvm::endianness::little>(Data);

46 return llvm::VersionTuple(Major, Minor, Subminor, Build);

47}

48

49

50template <typename Derived, typename KeyType, typename UnversionedDataType>

51class VersionedTableInfo {

52public:

53 using internal_key_type = KeyType;

54 using external_key_type = KeyType;

55 using data_type =

56 llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;

57 using hash_value_type = size_t;

58 using offset_type = unsigned;

59

60 internal_key_type GetInternalKey(external_key_type Key) { return Key; }

61

62 external_key_type GetExternalKey(internal_key_type Key) { return Key; }

63

64 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {

65 return LHS == RHS;

66 }

67

68 static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {

69 unsigned KeyLength =

70 endian::readNext<uint16_t, llvm::endianness::little>(Data);

71 unsigned DataLength =

72 endian::readNext<uint16_t, llvm::endianness::little>(Data);

73 return {KeyLength, DataLength};

74 }

75

76 static data_type ReadData(internal_key_type Key, const uint8_t *Data,

77 unsigned Length) {

78 unsigned NumElements =

79 endian::readNext<uint16_t, llvm::endianness::little>(Data);

81 Result.reserve(NumElements);

82 for (unsigned i = 0; i != NumElements; ++i) {

83 auto version = ReadVersionTuple(Data);

84 const auto *DataBefore = Data;

85 (void)DataBefore;

86 auto UnversionedData = Derived::readUnversioned(Key, Data);

87 assert(Data != DataBefore &&

88 "Unversioned data reader didn't move pointer");

89 Result.push_back({version, UnversionedData});

90 }

92 }

93};

94

95

97 uint8_t EncodedBits = *Data++;

98 Info.Unavailable = (EncodedBits >> 1) & 0x01;

99 Info.UnavailableInSwift = EncodedBits & 0x01;

100 if ((EncodedBits >> 2) & 0x01)

101 Info.setSwiftPrivate(static_cast<bool>((EncodedBits >> 3) & 0x01));

102 if ((EncodedBits >> 4) & 0x01)

103 Info.setSwiftSafety(

104 static_cast<SwiftSafetyKind>((EncodedBits >> 5) & 0x03));

105

106 unsigned MsgLength =

107 endian::readNext<uint16_t, llvm::endianness::little>(Data);

108 Info.UnavailableMsg =

109 std::string(reinterpret_cast<const char *>(Data),

110 reinterpret_cast<const char *>(Data) + MsgLength);

111 Data += MsgLength;

112

113 unsigned SwiftNameLength =

114 endian::readNext<uint16_t, llvm::endianness::little>(Data);

115 Info.SwiftName =

116 std::string(reinterpret_cast<const char *>(Data),

117 reinterpret_cast<const char *>(Data) + SwiftNameLength);

118 Data += SwiftNameLength;

119}

120

121

123 ReadCommonEntityInfo(Data, Info);

124

125 unsigned SwiftBridgeLength =

126 endian::readNext<uint16_t, llvm::endianness::little>(Data);

127 if (SwiftBridgeLength > 0) {

128 Info.setSwiftBridge(std::string(reinterpret_cast<const char *>(Data),

129 SwiftBridgeLength - 1));

130 Data += SwiftBridgeLength - 1;

131 }

132

133 unsigned ErrorDomainLength =

134 endian::readNext<uint16_t, llvm::endianness::little>(Data);

135 if (ErrorDomainLength > 0) {

136 Info.setNSErrorDomain(std::optionalstd::string(std::string(

137 reinterpret_cast<const char *>(Data), ErrorDomainLength - 1)));

138 Data += ErrorDomainLength - 1;

139 }

140

141 if (unsigned ConformanceLength =

142 endian::readNext<uint16_t, llvm::endianness::little>(Data)) {

143 Info.setSwiftConformance(std::string(reinterpret_cast<const char *>(Data),

144 ConformanceLength - 1));

145 Data += ConformanceLength - 1;

146 }

147}

148

149

150class IdentifierTableInfo {

151public:

152 using internal_key_type = llvm::StringRef;

153 using external_key_type = llvm::StringRef;

155 using hash_value_type = uint32_t;

156 using offset_type = unsigned;

157

158 internal_key_type GetInternalKey(external_key_type Key) { return Key; }

159

160 external_key_type GetExternalKey(internal_key_type Key) { return Key; }

161

162 hash_value_type ComputeHash(internal_key_type Key) {

163 return llvm::djbHash(Key);

164 }

165

166 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {

167 return LHS == RHS;

168 }

169

170 static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {

171 unsigned KeyLength =

172 endian::readNext<uint16_t, llvm::endianness::little>(Data);

173 unsigned DataLength =

174 endian::readNext<uint16_t, llvm::endianness::little>(Data);

175 return {KeyLength, DataLength};

176 }

177

178 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

179 return llvm::StringRef(reinterpret_cast<const char *>(Data), Length);

180 }

181

182 static data_type ReadData(internal_key_type key, const uint8_t *Data,

183 unsigned Length) {

184 return endian::readNext<uint32_t, llvm::endianness::little>(Data);

185 }

186};

187

188

189

190class ContextIDTableInfo {

191public:

192 using internal_key_type = ContextTableKey;

193 using external_key_type = internal_key_type;

194 using data_type = unsigned;

195 using hash_value_type = size_t;

196 using offset_type = unsigned;

197

198 internal_key_type GetInternalKey(external_key_type Key) { return Key; }

199

200 external_key_type GetExternalKey(internal_key_type Key) { return Key; }

201

202 hash_value_type ComputeHash(internal_key_type Key) {

203 return static_cast<size_t>(Key.hashValue());

204 }

205

206 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {

207 return LHS == RHS;

208 }

209

210 static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {

211 unsigned KeyLength =

212 endian::readNext<uint16_t, llvm::endianness::little>(Data);

213 unsigned DataLength =

214 endian::readNext<uint16_t, llvm::endianness::little>(Data);

215 return {KeyLength, DataLength};

216 }

217

218 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

219 auto ParentCtxID =

220 endian::readNext<uint32_t, llvm::endianness::little>(Data);

222 endian::readNext<uint8_t, llvm::endianness::little>(Data);

223 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

224 return {ParentCtxID, ContextKind, NameID};

225 }

226

227 static data_type ReadData(internal_key_type Key, const uint8_t *Data,

228 unsigned Length) {

229 return endian::readNext<uint32_t, llvm::endianness::little>(Data);

230 }

231};

232

233

234class ContextInfoTableInfo

235 : public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {

236public:

237 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

238 return endian::readNext<uint32_t, llvm::endianness::little>(Data);

239 }

240

241 hash_value_type ComputeHash(internal_key_type Key) {

243 }

244

245 static ContextInfo readUnversioned(internal_key_type Key,

246 const uint8_t *&Data) {

247 ContextInfo Info;

248 ReadCommonTypeInfo(Data, Info);

249 uint8_t Payload = *Data++;

250

251 if (Payload & 0x01)

252 Info.setHasDesignatedInits(true);

253 Payload = Payload >> 1;

254

255 if (Payload & 0x4)

256 Info.setDefaultNullability(static_cast<NullabilityKind>(Payload & 0x03));

257 Payload >>= 3;

258

259 if (Payload & (1 << 1))

260 Info.setSwiftObjCMembers(Payload & 1);

261 Payload >>= 2;

262

263 if (Payload & (1 << 1))

264 Info.setSwiftImportAsNonGeneric(Payload & 1);

265

266 return Info;

267 }

268};

269

270

271void ReadVariableInfo(const uint8_t *&Data, VariableInfo &Info) {

272 ReadCommonEntityInfo(Data, Info);

273 if (*Data++) {

275 }

277

278 auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(Data);

279 Info.setType(std::string(Data, Data + TypeLen));

280 Data += TypeLen;

281}

282

283

284class ObjCPropertyTableInfo

285 : public VersionedTableInfo<ObjCPropertyTableInfo,

286 std::tuple<uint32_t, uint32_t, uint8_t>,

287 ObjCPropertyInfo> {

288public:

289 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

290 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

291 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

292 char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data);

293 return {ClassID, NameID, IsInstance};

294 }

295

296 hash_value_type ComputeHash(internal_key_type Key) {

298 }

299

300 static ObjCPropertyInfo readUnversioned(internal_key_type Key,

301 const uint8_t *&Data) {

302 ObjCPropertyInfo Info;

303 ReadVariableInfo(Data, Info);

304 uint8_t Flags = *Data++;

305 if (Flags & (1 << 0))

306 Info.setSwiftImportAsAccessors(Flags & (1 << 1));

307 return Info;

308 }

309};

310

311

312class FieldTableInfo

313 : public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {

314public:

315 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

316 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

317 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

318 return {CtxID, NameID};

319 }

320

321 hash_value_type ComputeHash(internal_key_type Key) {

322 return static_cast<size_t>(Key.hashValue());

323 }

324

325 static FieldInfo readUnversioned(internal_key_type Key,

326 const uint8_t *&Data) {

327 FieldInfo Info;

328 ReadVariableInfo(Data, Info);

329 return Info;

330 }

331};

332

333

334void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {

335 ReadVariableInfo(Data, Info);

336

337 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data);

338 if (auto RawConvention = Payload & 0x7) {

340 Info.setRetainCountConvention(Convention);

341 }

342 Payload >>= 3;

343 if (Payload & 0x01)

344 Info.setLifetimebound(Payload & 0x02);

345 Payload >>= 2;

346 if (Payload & 0x01)

347 Info.setNoEscape(Payload & 0x02);

348 Payload >>= 2;

349 assert(Payload == 0 && "Bad API notes");

350}

351

352

353void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) {

354 ReadCommonEntityInfo(Data, Info);

355

356 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data);

357 if (auto RawConvention = Payload & 0x7) {

359 Info.setRetainCountConvention(Convention);

360 }

361 Payload >>= 3;

362 Info.NullabilityAudited = Payload & 0x1;

363 Payload >>= 1;

364 assert(Payload == 0 && "Bad API notes");

365

366 Info.NumAdjustedNullable =

367 endian::readNext<uint8_t, llvm::endianness::little>(Data);

368 Info.NullabilityPayload =

369 endian::readNext<uint64_t, llvm::endianness::little>(Data);

370

371 unsigned NumParams =

372 endian::readNext<uint16_t, llvm::endianness::little>(Data);

373 while (NumParams > 0) {

375 ReadParamInfo(Data, pi);

376 Info.Params.push_back(pi);

377 --NumParams;

378 }

379

380 unsigned ResultTypeLen =

381 endian::readNext<uint16_t, llvm::endianness::little>(Data);

382 Info.ResultType = std::string(Data, Data + ResultTypeLen);

383 Data += ResultTypeLen;

384

385 unsigned SwiftReturnOwnershipLength =

386 endian::readNext<uint16_t, llvm::endianness::little>(Data);

387 Info.SwiftReturnOwnership = std::string(reinterpret_cast<const char *>(Data),

388 reinterpret_cast<const char *>(Data) +

389 SwiftReturnOwnershipLength);

390 Data += SwiftReturnOwnershipLength;

391}

392

393

394class ObjCMethodTableInfo

395 : public VersionedTableInfo<ObjCMethodTableInfo,

396 std::tuple<uint32_t, uint32_t, uint8_t>,

397 ObjCMethodInfo> {

398public:

399 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

400 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

402 endian::readNext<uint32_t, llvm::endianness::little>(Data);

403 auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data);

404 return {ClassID, SelectorID, IsInstance};

405 }

406

407 hash_value_type ComputeHash(internal_key_type Key) {

409 }

410

411 static ObjCMethodInfo readUnversioned(internal_key_type Key,

412 const uint8_t *&Data) {

413 ObjCMethodInfo Info;

414 uint8_t Payload = *Data++;

415 bool HasSelf = Payload & 0x01;

416 Payload >>= 1;

417 Info.RequiredInit = Payload & 0x01;

418 Payload >>= 1;

419 Info.DesignatedInit = Payload & 0x01;

420 Payload >>= 1;

421 assert(Payload == 0 && "Unable to fully decode 'Payload'.");

422

423 ReadFunctionInfo(Data, Info);

424 if (HasSelf) {

425 Info.Self = ParamInfo{};

426 ReadParamInfo(Data, *Info.Self);

427 }

428 return Info;

429 }

430};

431

432

433class ObjCSelectorTableInfo {

434public:

435 using internal_key_type = StoredObjCSelector;

436 using external_key_type = internal_key_type;

438 using hash_value_type = unsigned;

439 using offset_type = unsigned;

440

441 internal_key_type GetInternalKey(external_key_type Key) { return Key; }

442

443 external_key_type GetExternalKey(internal_key_type Key) { return Key; }

444

445 hash_value_type ComputeHash(internal_key_type Key) {

446 return llvm::DenseMapInfo::getHashValue(Key);

447 }

448

449 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {

450 return llvm::DenseMapInfo::isEqual(LHS, RHS);

451 }

452

453 static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {

454 unsigned KeyLength =

455 endian::readNext<uint16_t, llvm::endianness::little>(Data);

456 unsigned DataLength =

457 endian::readNext<uint16_t, llvm::endianness::little>(Data);

458 return {KeyLength, DataLength};

459 }

460

461 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

462 internal_key_type Key;

463 Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(Data);

464 unsigned NumIdents = (Length - sizeof(uint16_t)) / sizeof(uint32_t);

465 for (unsigned i = 0; i != NumIdents; ++i) {

466 Key.Identifiers.push_back(

467 endian::readNext<uint32_t, llvm::endianness::little>(Data));

468 }

469 return Key;

470 }

471

472 static data_type ReadData(internal_key_type Key, const uint8_t *Data,

473 unsigned Length) {

474 return endian::readNext<uint32_t, llvm::endianness::little>(Data);

475 }

476};

477

478

479class GlobalVariableTableInfo

480 : public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,

481 GlobalVariableInfo> {

482public:

483 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

484 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

485 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

486 return {CtxID, NameID};

487 }

488

489 hash_value_type ComputeHash(internal_key_type Key) {

490 return static_cast<size_t>(Key.hashValue());

491 }

492

493 static GlobalVariableInfo readUnversioned(internal_key_type Key,

494 const uint8_t *&Data) {

495 GlobalVariableInfo Info;

496 ReadVariableInfo(Data, Info);

497 return Info;

498 }

499};

500

501

502class GlobalFunctionTableInfo

503 : public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,

504 GlobalFunctionInfo> {

505public:

506 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

507 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

508 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

509 return {CtxID, NameID};

510 }

511

512 hash_value_type ComputeHash(internal_key_type Key) {

513 return static_cast<size_t>(Key.hashValue());

514 }

515

516 static GlobalFunctionInfo readUnversioned(internal_key_type Key,

517 const uint8_t *&Data) {

518 GlobalFunctionInfo Info;

519 ReadFunctionInfo(Data, Info);

520 return Info;

521 }

522};

523

524

525class CXXMethodTableInfo

526 : public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey,

527 CXXMethodInfo> {

528public:

529 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

530 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

531 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

532 return {CtxID, NameID};

533 }

534

535 hash_value_type ComputeHash(internal_key_type Key) {

536 return static_cast<size_t>(Key.hashValue());

537 }

538

539 static CXXMethodInfo readUnversioned(internal_key_type Key,

540 const uint8_t *&Data) {

541 CXXMethodInfo Info;

542

543 uint8_t Payload = *Data++;

544 bool HasThis = Payload & 0x01;

545 Payload >>= 1;

546 assert(Payload == 0 && "Unable to fully decode 'Payload'.");

547

548 ReadFunctionInfo(Data, Info);

549 if (HasThis) {

550 Info.This = ParamInfo{};

551 ReadParamInfo(Data, *Info.This);

552 }

553 return Info;

554 }

555};

556

557

558class EnumConstantTableInfo

559 : public VersionedTableInfo<EnumConstantTableInfo, uint32_t,

560 EnumConstantInfo> {

561public:

562 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

563 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

564 return NameID;

565 }

566

567 hash_value_type ComputeHash(internal_key_type Key) {

569 }

570

571 static EnumConstantInfo readUnversioned(internal_key_type Key,

572 const uint8_t *&Data) {

573 EnumConstantInfo Info;

574 ReadCommonEntityInfo(Data, Info);

575 return Info;

576 }

577};

578

579

580class TagTableInfo

581 : public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {

582public:

583 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

584 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

585 auto NameID =

586 endian::readNext<IdentifierID, llvm::endianness::little>(Data);

587 return {CtxID, NameID};

588 }

589

590 hash_value_type ComputeHash(internal_key_type Key) {

591 return static_cast<size_t>(Key.hashValue());

592 }

593

594 static TagInfo readUnversioned(internal_key_type Key, const uint8_t *&Data) {

595 TagInfo Info;

596

597 uint8_t Payload = *Data++;

598 if (Payload & 1)

599 Info.setFlagEnum(Payload & 2);

600 Payload >>= 2;

601 if (Payload > 0)

602 Info.EnumExtensibility =

604

605 uint8_t Copyable =

606 endian::readNext<uint8_t, llvm::endianness::little>(Data);

608 Info.setSwiftCopyable(std::optional(Copyable == kSwiftConforms));

609 uint8_t Escapable =

610 endian::readNext<uint8_t, llvm::endianness::little>(Data);

612 Info.setSwiftEscapable(std::optional(Escapable == kSwiftConforms));

613

614 unsigned ImportAsLength =

615 endian::readNext<uint16_t, llvm::endianness::little>(Data);

616 if (ImportAsLength > 0) {

617 Info.SwiftImportAs =

618 std::string(reinterpret_cast<const char *>(Data), ImportAsLength - 1);

619 Data += ImportAsLength - 1;

620 }

621 unsigned RetainOpLength =

622 endian::readNext<uint16_t, llvm::endianness::little>(Data);

623 if (RetainOpLength > 0) {

624 Info.SwiftRetainOp =

625 std::string(reinterpret_cast<const char *>(Data), RetainOpLength - 1);

626 Data += RetainOpLength - 1;

627 }

628 unsigned ReleaseOpLength =

629 endian::readNext<uint16_t, llvm::endianness::little>(Data);

630 if (ReleaseOpLength > 0) {

631 Info.SwiftReleaseOp = std::string(reinterpret_cast<const char *>(Data),

632 ReleaseOpLength - 1);

633 Data += ReleaseOpLength - 1;

634 }

635 unsigned DefaultOwnershipLength =

636 endian::readNext<uint16_t, llvm::endianness::little>(Data);

637 if (DefaultOwnershipLength > 0) {

638 Info.SwiftDefaultOwnership = std::string(

639 reinterpret_cast<const char *>(Data), DefaultOwnershipLength - 1);

640 Data += DefaultOwnershipLength - 1;

641 }

642 unsigned DestroyOpLength =

643 endian::readNext<uint16_t, llvm::endianness::little>(Data);

644 if (DestroyOpLength > 0) {

645 Info.SwiftDestroyOp = std::string(reinterpret_cast<const char *>(Data),

646 DestroyOpLength - 1);

647 Data += DestroyOpLength - 1;

648 }

649

650 ReadCommonTypeInfo(Data, Info);

651 return Info;

652 }

653};

654

655

656class TypedefTableInfo

657 : public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,

658 TypedefInfo> {

659public:

660 static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {

661 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);

662 auto nameID =

663 endian::readNext<IdentifierID, llvm::endianness::little>(Data);

664 return {CtxID, nameID};

665 }

666

667 hash_value_type ComputeHash(internal_key_type Key) {

668 return static_cast<size_t>(Key.hashValue());

669 }

670

671 static TypedefInfo readUnversioned(internal_key_type Key,

672 const uint8_t *&Data) {

673 TypedefInfo Info;

674

675 uint8_t Payload = *Data++;

676 if (Payload > 0)

677 Info.SwiftWrapper = static_cast<SwiftNewTypeKind>((Payload & 0x3) - 1);

678

679 ReadCommonTypeInfo(Data, Info);

680 return Info;

681 }

682};

683}

684

686public:

687

689

690

692

693

695

696

697

699

701 llvm::OnDiskIterableChainedHashTable;

702

703

705

707 llvm::OnDiskIterableChainedHashTable;

708

709

711

713 llvm::OnDiskIterableChainedHashTable;

714

715

717

719 llvm::OnDiskIterableChainedHashTable;

720

721

723

725 llvm::OnDiskIterableChainedHashTable;

726

727

728 std::unique_ptr FieldTable;

729

731 llvm::OnDiskIterableChainedHashTable;

732

733

735

737 llvm::OnDiskIterableChainedHashTable;

738

739

741

743 llvm::OnDiskIterableChainedHashTable;

744

745

747

749 llvm::OnDiskIterableChainedHashTable;

750

751

753

755 llvm::OnDiskIterableChainedHashTable;

756

757

759

761 llvm::OnDiskIterableChainedHashTable;

762

763

765

767

768

769 std::unique_ptr TagTable;

770

772 llvm::OnDiskIterableChainedHashTable;

773

774

776

777

778

779 std::optional getIdentifier(llvm::StringRef Str);

780

781

782

784

807 bool readTagBlock(llvm::BitstreamCursor &Cursor,

811};

812

813std::optional

816 return std::nullopt;

817

818 if (Str.empty())

820

823 return std::nullopt;

824

825 return *Known;

826}

827

828std::optional

831 return std::nullopt;

832

833

836 for (auto Ident : Selector.Identifiers) {

839 } else {

840 return std::nullopt;

841 }

842 }

843

846 return std::nullopt;

847

848 return *Known;

849}

850

854 return true;

855

856 bool SawMetadata = false;

857

859 if (!MaybeNext) {

860

861 consumeError(MaybeNext.takeError());

862 return false;

863 }

864 llvm::BitstreamEntry Next = MaybeNext.get();

865

866 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

867 if (Next.Kind == llvm::BitstreamEntry::Error)

868 return true;

869

870 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

871

872

873 if (Cursor.SkipBlock())

874 return true;

875

876 MaybeNext = Cursor.advance();

877 if (!MaybeNext) {

878

879 consumeError(MaybeNext.takeError());

880 return false;

881 }

882 Next = MaybeNext.get();

883 continue;

884 }

885

886 Scratch.clear();

887 llvm::StringRef BlobData;

889 Cursor.readRecord(Next.ID, Scratch, &BlobData);

890 if (!MaybeKind) {

891

892 consumeError(MaybeKind.takeError());

893 return false;

894 }

895 unsigned Kind = MaybeKind.get();

896

897 switch (Kind) {

899

900 if (SawMetadata)

901 return true;

902

904 return true;

905

906 SawMetadata = true;

907 break;

908

911 break;

912

914 break;

915

918 break;

919

920 default:

921

922

923 break;

924 }

925

926 MaybeNext = Cursor.advance();

927 if (!MaybeNext) {

928

929 consumeError(MaybeNext.takeError());

930 return false;

931 }

932 Next = MaybeNext.get();

933 }

934

935 return !SawMetadata;

936}

937

941 return true;

942

944 if (!MaybeNext) {

945

946 consumeError(MaybeNext.takeError());

947 return false;

948 }

949 llvm::BitstreamEntry Next = MaybeNext.get();

950

951 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

952 if (Next.Kind == llvm::BitstreamEntry::Error)

953 return true;

954

955 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

956

957

958 if (Cursor.SkipBlock())

959 return true;

960

961 MaybeNext = Cursor.advance();

962 if (!MaybeNext) {

963

964 consumeError(MaybeNext.takeError());

965 return false;

966 }

967 Next = MaybeNext.get();

968 continue;

969 }

970

971 Scratch.clear();

972 llvm::StringRef BlobData;

974 Cursor.readRecord(Next.ID, Scratch, &BlobData);

975 if (!MaybeKind) {

976

977 consumeError(MaybeKind.takeError());

978 return false;

979 }

980 unsigned Kind = MaybeKind.get();

981 switch (Kind) {

983

985 return true;

986

987 uint32_t tableOffset;

988 identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);

989 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

990

992 base + tableOffset, base + sizeof(uint32_t), base));

993 break;

994 }

995

996 default:

997

998

999 break;

1000 }

1001

1002 MaybeNext = Cursor.advance();

1003 if (!MaybeNext) {

1004

1005 consumeError(MaybeNext.takeError());

1006 return false;

1007 }

1008 Next = MaybeNext.get();

1009 }

1010

1011 return false;

1012}

1013

1017 return true;

1018

1020 if (!MaybeNext) {

1021

1022 consumeError(MaybeNext.takeError());

1023 return false;

1024 }

1025 llvm::BitstreamEntry Next = MaybeNext.get();

1026

1027 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1028 if (Next.Kind == llvm::BitstreamEntry::Error)

1029 return true;

1030

1031 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1032

1033

1034 if (Cursor.SkipBlock())

1035 return true;

1036

1037 MaybeNext = Cursor.advance();

1038 if (!MaybeNext) {

1039

1040 consumeError(MaybeNext.takeError());

1041 return false;

1042 }

1043 Next = MaybeNext.get();

1044 continue;

1045 }

1046

1047 Scratch.clear();

1048 llvm::StringRef BlobData;

1050 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1051 if (!MaybeKind) {

1052

1053 consumeError(MaybeKind.takeError());

1054 return false;

1055 }

1056 unsigned Kind = MaybeKind.get();

1057 switch (Kind) {

1059

1061 return true;

1062

1063 uint32_t tableOffset;

1064 context_block::ContextIDLayout::readRecord(Scratch, tableOffset);

1065 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1066

1067 ContextIDTable.reset(SerializedContextIDTable::Create(

1068 base + tableOffset, base + sizeof(uint32_t), base));

1069 break;

1070 }

1071

1073

1075 return true;

1076

1077 uint32_t tableOffset;

1078 context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);

1079 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1080

1082 base + tableOffset, base + sizeof(uint32_t), base));

1083 break;

1084 }

1085

1086 default:

1087

1088

1089 break;

1090 }

1091

1092 MaybeNext = Cursor.advance();

1093 if (!MaybeNext) {

1094

1095 consumeError(MaybeNext.takeError());

1096 return false;

1097 }

1098 Next = MaybeNext.get();

1099 }

1100

1101 return false;

1102}

1103

1107 return true;

1108

1110 if (!MaybeNext) {

1111

1112 consumeError(MaybeNext.takeError());

1113 return false;

1114 }

1115 llvm::BitstreamEntry Next = MaybeNext.get();

1116

1117 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1118 if (Next.Kind == llvm::BitstreamEntry::Error)

1119 return true;

1120

1121 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1122

1123

1124 if (Cursor.SkipBlock())

1125 return true;

1126

1127 MaybeNext = Cursor.advance();

1128 if (!MaybeNext) {

1129

1130 consumeError(MaybeNext.takeError());

1131 return false;

1132 }

1133 Next = MaybeNext.get();

1134 continue;

1135 }

1136

1137 Scratch.clear();

1138 llvm::StringRef BlobData;

1140 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1141 if (!MaybeKind) {

1142

1143 consumeError(MaybeKind.takeError());

1144 return false;

1145 }

1146 unsigned Kind = MaybeKind.get();

1147 switch (Kind) {

1149

1151 return true;

1152

1153 uint32_t tableOffset;

1154 objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,

1155 tableOffset);

1156 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1157

1159 base + tableOffset, base + sizeof(uint32_t), base));

1160 break;

1161 }

1162

1163 default:

1164

1165

1166 break;

1167 }

1168

1169 MaybeNext = Cursor.advance();

1170 if (!MaybeNext) {

1171

1172 consumeError(MaybeNext.takeError());

1173 return false;

1174 }

1175 Next = MaybeNext.get();

1176 }

1177

1178 return false;

1179}

1180

1184 return true;

1185

1187 if (!MaybeNext) {

1188

1189 consumeError(MaybeNext.takeError());

1190 return false;

1191 }

1192 llvm::BitstreamEntry Next = MaybeNext.get();

1193 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1194 if (Next.Kind == llvm::BitstreamEntry::Error)

1195 return true;

1196

1197 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1198

1199

1200 if (Cursor.SkipBlock())

1201 return true;

1202

1203 MaybeNext = Cursor.advance();

1204 if (!MaybeNext) {

1205

1206 consumeError(MaybeNext.takeError());

1207 return false;

1208 }

1209 Next = MaybeNext.get();

1210 continue;

1211 }

1212

1213 Scratch.clear();

1214 llvm::StringRef BlobData;

1216 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1217 if (!MaybeKind) {

1218

1219 consumeError(MaybeKind.takeError());

1220 return false;

1221 }

1222 unsigned Kind = MaybeKind.get();

1223 switch (Kind) {

1225

1227 return true;

1228

1229 uint32_t tableOffset;

1230 objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);

1231 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1232

1233 ObjCMethodTable.reset(SerializedObjCMethodTable::Create(

1234 base + tableOffset, base + sizeof(uint32_t), base));

1235 break;

1236 }

1237

1238 default:

1239

1240

1241 break;

1242 }

1243

1244 MaybeNext = Cursor.advance();

1245 if (!MaybeNext) {

1246

1247 consumeError(MaybeNext.takeError());

1248 return false;

1249 }

1250 Next = MaybeNext.get();

1251 }

1252

1253 return false;

1254}

1255

1259 return true;

1260

1262 if (!MaybeNext) {

1263

1264 consumeError(MaybeNext.takeError());

1265 return false;

1266 }

1267 llvm::BitstreamEntry Next = MaybeNext.get();

1268 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1269 if (Next.Kind == llvm::BitstreamEntry::Error)

1270 return true;

1271

1272 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1273

1274

1275 if (Cursor.SkipBlock())

1276 return true;

1277

1278 MaybeNext = Cursor.advance();

1279 if (!MaybeNext) {

1280

1281 consumeError(MaybeNext.takeError());

1282 return false;

1283 }

1284 Next = MaybeNext.get();

1285 continue;

1286 }

1287

1288 Scratch.clear();

1289 llvm::StringRef BlobData;

1291 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1292 if (!MaybeKind) {

1293

1294 consumeError(MaybeKind.takeError());

1295 return false;

1296 }

1297 unsigned Kind = MaybeKind.get();

1298 switch (Kind) {

1300

1302 return true;

1303

1304 uint32_t tableOffset;

1305 cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset);

1306 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1307

1308 CXXMethodTable.reset(SerializedCXXMethodTable::Create(

1309 base + tableOffset, base + sizeof(uint32_t), base));

1310 break;

1311 }

1312

1313 default:

1314

1315

1316 break;

1317 }

1318

1319 MaybeNext = Cursor.advance();

1320 if (!MaybeNext) {

1321

1322 consumeError(MaybeNext.takeError());

1323 return false;

1324 }

1325 Next = MaybeNext.get();

1326 }

1327

1328 return false;

1329}

1330

1334 return true;

1335

1337 if (!MaybeNext) {

1338

1339 consumeError(MaybeNext.takeError());

1340 return false;

1341 }

1342 llvm::BitstreamEntry Next = MaybeNext.get();

1343 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1344 if (Next.Kind == llvm::BitstreamEntry::Error)

1345 return true;

1346

1347 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1348

1349

1350 if (Cursor.SkipBlock())

1351 return true;

1352

1353 MaybeNext = Cursor.advance();

1354 if (!MaybeNext) {

1355

1356 consumeError(MaybeNext.takeError());

1357 return false;

1358 }

1359 Next = MaybeNext.get();

1360 continue;

1361 }

1362

1363 Scratch.clear();

1364 llvm::StringRef BlobData;

1366 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1367 if (!MaybeKind) {

1368

1369 consumeError(MaybeKind.takeError());

1370 return false;

1371 }

1372 unsigned Kind = MaybeKind.get();

1373 switch (Kind) {

1375

1377 return true;

1378

1379 uint32_t tableOffset;

1380 field_block::FieldDataLayout::readRecord(Scratch, tableOffset);

1381 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1382

1383 FieldTable.reset(SerializedFieldTable::Create(

1384 base + tableOffset, base + sizeof(uint32_t), base));

1385 break;

1386 }

1387

1388 default:

1389

1390

1391 break;

1392 }

1393

1394 MaybeNext = Cursor.advance();

1395 if (!MaybeNext) {

1396

1397 consumeError(MaybeNext.takeError());

1398 return false;

1399 }

1400 Next = MaybeNext.get();

1401 }

1402

1403 return false;

1404}

1405

1409 return true;

1410

1412 if (!MaybeNext) {

1413

1414 consumeError(MaybeNext.takeError());

1415 return false;

1416 }

1417 llvm::BitstreamEntry Next = MaybeNext.get();

1418 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1419 if (Next.Kind == llvm::BitstreamEntry::Error)

1420 return true;

1421

1422 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1423

1424

1425 if (Cursor.SkipBlock())

1426 return true;

1427

1428 MaybeNext = Cursor.advance();

1429 if (!MaybeNext) {

1430

1431 consumeError(MaybeNext.takeError());

1432 return false;

1433 }

1434 Next = MaybeNext.get();

1435 continue;

1436 }

1437

1438 Scratch.clear();

1439 llvm::StringRef BlobData;

1441 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1442 if (!MaybeKind) {

1443

1444 consumeError(MaybeKind.takeError());

1445 return false;

1446 }

1447 unsigned Kind = MaybeKind.get();

1448 switch (Kind) {

1450

1452 return true;

1453

1454 uint32_t tableOffset;

1455 objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,

1456 tableOffset);

1457 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1458

1460 base + tableOffset, base + sizeof(uint32_t), base));

1461 break;

1462 }

1463

1464 default:

1465

1466

1467 break;

1468 }

1469

1470 MaybeNext = Cursor.advance();

1471 if (!MaybeNext) {

1472

1473 consumeError(MaybeNext.takeError());

1474 return false;

1475 }

1476 Next = MaybeNext.get();

1477 }

1478

1479 return false;

1480}

1481

1485 return true;

1486

1488 if (!MaybeNext) {

1489

1490 consumeError(MaybeNext.takeError());

1491 return false;

1492 }

1493 llvm::BitstreamEntry Next = MaybeNext.get();

1494 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1495 if (Next.Kind == llvm::BitstreamEntry::Error)

1496 return true;

1497

1498 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1499

1500

1501 if (Cursor.SkipBlock())

1502 return true;

1503

1504 MaybeNext = Cursor.advance();

1505 if (!MaybeNext) {

1506

1507 consumeError(MaybeNext.takeError());

1508 return false;

1509 }

1510 Next = MaybeNext.get();

1511 continue;

1512 }

1513

1514 Scratch.clear();

1515 llvm::StringRef BlobData;

1517 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1518 if (!MaybeKind) {

1519

1520 consumeError(MaybeKind.takeError());

1521 return false;

1522 }

1523 unsigned Kind = MaybeKind.get();

1524 switch (Kind) {

1526

1528 return true;

1529

1530 uint32_t tableOffset;

1531 global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,

1532 tableOffset);

1533 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1534

1536 base + tableOffset, base + sizeof(uint32_t), base));

1537 break;

1538 }

1539

1540 default:

1541

1542

1543 break;

1544 }

1545

1546 MaybeNext = Cursor.advance();

1547 if (!MaybeNext) {

1548

1549 consumeError(MaybeNext.takeError());

1550 return false;

1551 }

1552 Next = MaybeNext.get();

1553 }

1554

1555 return false;

1556}

1557

1561 return true;

1562

1564 if (!MaybeNext) {

1565

1566 consumeError(MaybeNext.takeError());

1567 return false;

1568 }

1569 llvm::BitstreamEntry Next = MaybeNext.get();

1570 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1571 if (Next.Kind == llvm::BitstreamEntry::Error)

1572 return true;

1573

1574 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1575

1576

1577 if (Cursor.SkipBlock())

1578 return true;

1579

1580 MaybeNext = Cursor.advance();

1581 if (!MaybeNext) {

1582

1583 consumeError(MaybeNext.takeError());

1584 return false;

1585 }

1586 Next = MaybeNext.get();

1587 continue;

1588 }

1589

1590 Scratch.clear();

1591 llvm::StringRef BlobData;

1593 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1594 if (!MaybeKind) {

1595

1596 consumeError(MaybeKind.takeError());

1597 return false;

1598 }

1599 unsigned Kind = MaybeKind.get();

1600 switch (Kind) {

1602

1604 return true;

1605

1606 uint32_t tableOffset;

1607 global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,

1608 tableOffset);

1609 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1610

1612 base + tableOffset, base + sizeof(uint32_t), base));

1613 break;

1614 }

1615

1616 default:

1617

1618

1619 break;

1620 }

1621

1622 MaybeNext = Cursor.advance();

1623 if (!MaybeNext) {

1624

1625 consumeError(MaybeNext.takeError());

1626 return false;

1627 }

1628 Next = MaybeNext.get();

1629 }

1630

1631 return false;

1632}

1633

1637 return true;

1638

1640 if (!MaybeNext) {

1641

1642 consumeError(MaybeNext.takeError());

1643 return false;

1644 }

1645 llvm::BitstreamEntry Next = MaybeNext.get();

1646 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1647 if (Next.Kind == llvm::BitstreamEntry::Error)

1648 return true;

1649

1650 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1651

1652

1653 if (Cursor.SkipBlock())

1654 return true;

1655

1656 MaybeNext = Cursor.advance();

1657 if (!MaybeNext) {

1658

1659 consumeError(MaybeNext.takeError());

1660 return false;

1661 }

1662 Next = MaybeNext.get();

1663 continue;

1664 }

1665

1666 Scratch.clear();

1667 llvm::StringRef BlobData;

1669 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1670 if (!MaybeKind) {

1671

1672 consumeError(MaybeKind.takeError());

1673 return false;

1674 }

1675 unsigned Kind = MaybeKind.get();

1676 switch (Kind) {

1678

1680 return true;

1681

1682 uint32_t tableOffset;

1683 enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,

1684 tableOffset);

1685 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1686

1688 base + tableOffset, base + sizeof(uint32_t), base));

1689 break;

1690 }

1691

1692 default:

1693

1694

1695 break;

1696 }

1697

1698 MaybeNext = Cursor.advance();

1699 if (!MaybeNext) {

1700

1701 consumeError(MaybeNext.takeError());

1702 return false;

1703 }

1704 Next = MaybeNext.get();

1705 }

1706

1707 return false;

1708}

1709

1713 return true;

1714

1716 if (!MaybeNext) {

1717

1718 consumeError(MaybeNext.takeError());

1719 return false;

1720 }

1721 llvm::BitstreamEntry Next = MaybeNext.get();

1722 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1723 if (Next.Kind == llvm::BitstreamEntry::Error)

1724 return true;

1725

1726 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1727

1728

1729 if (Cursor.SkipBlock())

1730 return true;

1731

1732 MaybeNext = Cursor.advance();

1733 if (!MaybeNext) {

1734

1735 consumeError(MaybeNext.takeError());

1736 return false;

1737 }

1738 Next = MaybeNext.get();

1739 continue;

1740 }

1741

1742 Scratch.clear();

1743 llvm::StringRef BlobData;

1745 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1746 if (!MaybeKind) {

1747

1748 consumeError(MaybeKind.takeError());

1749 return false;

1750 }

1751 unsigned Kind = MaybeKind.get();

1752 switch (Kind) {

1754

1756 return true;

1757

1758 uint32_t tableOffset;

1759 tag_block::TagDataLayout::readRecord(Scratch, tableOffset);

1760 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1761

1762 TagTable.reset(SerializedTagTable::Create(base + tableOffset,

1763 base + sizeof(uint32_t), base));

1764 break;

1765 }

1766

1767 default:

1768

1769

1770 break;

1771 }

1772

1773 MaybeNext = Cursor.advance();

1774 if (!MaybeNext) {

1775

1776 consumeError(MaybeNext.takeError());

1777 return false;

1778 }

1779 Next = MaybeNext.get();

1780 }

1781

1782 return false;

1783}

1784

1788 return true;

1789

1791 if (!MaybeNext) {

1792

1793 consumeError(MaybeNext.takeError());

1794 return false;

1795 }

1796 llvm::BitstreamEntry Next = MaybeNext.get();

1797 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {

1798 if (Next.Kind == llvm::BitstreamEntry::Error)

1799 return true;

1800

1801 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {

1802

1803

1804 if (Cursor.SkipBlock())

1805 return true;

1806

1807 MaybeNext = Cursor.advance();

1808 if (!MaybeNext) {

1809

1810 consumeError(MaybeNext.takeError());

1811 return false;

1812 }

1813 Next = MaybeNext.get();

1814 continue;

1815 }

1816

1817 Scratch.clear();

1818 llvm::StringRef BlobData;

1820 Cursor.readRecord(Next.ID, Scratch, &BlobData);

1821 if (!MaybeKind) {

1822

1823 consumeError(MaybeKind.takeError());

1824 return false;

1825 }

1826 unsigned Kind = MaybeKind.get();

1827 switch (Kind) {

1829

1831 return true;

1832

1833 uint32_t tableOffset;

1834 typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);

1835 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

1836

1837 TypedefTable.reset(SerializedTypedefTable::Create(

1838 base + tableOffset, base + sizeof(uint32_t), base));

1839 break;

1840 }

1841

1842 default:

1843

1844

1845 break;

1846 }

1847

1848 MaybeNext = Cursor.advance();

1849 if (!MaybeNext) {

1850

1851 consumeError(MaybeNext.takeError());

1852 return false;

1853 }

1854 Next = MaybeNext.get();

1855 }

1856

1857 return false;

1858}

1859

1860APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,

1861 llvm::VersionTuple SwiftVersion, bool &Failed)

1863 Failed = false;

1864

1865

1869

1870

1872 if (Cursor.AtEndOfStream()) {

1873 Failed = true;

1874 return;

1875 }

1877 Cursor.Read(8)) {

1878 if (maybeRead.get() != byte) {

1879 Failed = true;

1880 return;

1881 }

1882 } else {

1883

1884 consumeError(maybeRead.takeError());

1885 Failed = true;

1886 return;

1887 }

1888 }

1889

1890

1891 bool HasValidControlBlock = false;

1892 llvm::SmallVector<uint64_t, 64> Scratch;

1893 while (Cursor.AtEndOfStream()) {

1894 llvm::Expectedllvm::BitstreamEntry MaybeTopLevelEntry = Cursor.advance();

1895 if (!MaybeTopLevelEntry) {

1896

1897 consumeError(MaybeTopLevelEntry.takeError());

1898 Failed = true;

1899 return;

1900 }

1901 llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();

1902

1903 if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)

1904 break;

1905

1906 switch (TopLevelEntry.ID) {

1907 case llvm::bitc::BLOCKINFO_BLOCK_ID:

1908 if (Cursor.ReadBlockInfoBlock()) {

1909 Failed = true;

1910 break;

1911 }

1912 break;

1913

1915

1916 if (HasValidControlBlock ||

1917 Implementation->readControlBlock(Cursor, Scratch)) {

1918 Failed = true;

1919 return;

1920 }

1921

1922 HasValidControlBlock = true;

1923 break;

1924

1926 if (!HasValidControlBlock ||

1927 Implementation->readIdentifierBlock(Cursor, Scratch)) {

1928 Failed = true;

1929 return;

1930 }

1931 break;

1932

1934 if (!HasValidControlBlock ||

1935 Implementation->readContextBlock(Cursor, Scratch)) {

1936 Failed = true;

1937 return;

1938 }

1939

1940 break;

1941

1943 if (!HasValidControlBlock ||

1944 Implementation->readObjCPropertyBlock(Cursor, Scratch)) {

1945 Failed = true;

1946 return;

1947 }

1948 break;

1949

1951 if (!HasValidControlBlock ||

1952 Implementation->readObjCMethodBlock(Cursor, Scratch)) {

1953 Failed = true;

1954 return;

1955 }

1956 break;

1957

1959 if (!HasValidControlBlock ||

1960 Implementation->readCXXMethodBlock(Cursor, Scratch)) {

1961 Failed = true;

1962 return;

1963 }

1964 break;

1965

1967 if (!HasValidControlBlock ||

1968 Implementation->readFieldBlock(Cursor, Scratch)) {

1969 Failed = true;

1970 return;

1971 }

1972 break;

1973

1975 if (!HasValidControlBlock ||

1976 Implementation->readObjCSelectorBlock(Cursor, Scratch)) {

1977 Failed = true;

1978 return;

1979 }

1980 break;

1981

1983 if (!HasValidControlBlock ||

1984 Implementation->readGlobalVariableBlock(Cursor, Scratch)) {

1985 Failed = true;

1986 return;

1987 }

1988 break;

1989

1991 if (!HasValidControlBlock ||

1992 Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {

1993 Failed = true;

1994 return;

1995 }

1996 break;

1997

1999 if (!HasValidControlBlock ||

2000 Implementation->readEnumConstantBlock(Cursor, Scratch)) {

2001 Failed = true;

2002 return;

2003 }

2004 break;

2005

2007 if (!HasValidControlBlock ||

2008 Implementation->readTagBlock(Cursor, Scratch)) {

2009 Failed = true;

2010 return;

2011 }

2012 break;

2013

2015 if (!HasValidControlBlock ||

2016 Implementation->readTypedefBlock(Cursor, Scratch)) {

2017 Failed = true;

2018 return;

2019 }

2020 break;

2021

2022 default:

2023

2024

2025 if (Cursor.SkipBlock()) {

2026 Failed = true;

2027 return;

2028 }

2029 break;

2030 }

2031 }

2032

2033 if (Cursor.AtEndOfStream()) {

2034 Failed = true;

2035 return;

2036 }

2037}

2038

2040

2041std::unique_ptr

2043 llvm::VersionTuple SwiftVersion) {

2044 bool Failed = false;

2045 std::unique_ptr Reader(

2046 new APINotesReader(InputBuffer.release(), SwiftVersion, Failed));

2047 if (Failed)

2048 return nullptr;

2049

2050 return Reader;

2051}

2052

2053template

2055 llvm::VersionTuple Version,

2057 : Results(std::move(R)) {

2058

2059 assert(!Results.empty());

2060 assert(llvm::is_sorted(

2061 Results,

2062 [](const std::pair<llvm::VersionTuple, T> &left,

2063 const std::pair<llvm::VersionTuple, T> &right) -> bool {

2064

2065

2066

2067

2068 assert((&left == &right || left.first != right.first) &&

2069 "two entries for the same version");

2070 return left.first < right.first;

2071 }));

2072

2073 Selected = std::nullopt;

2074 for (unsigned i = 0, n = Results.size(); i != n; ++i) {

2075 if (!Version.empty() && Results[i].first >= Version) {

2076

2077

2078

2079 Selected = i;

2080 break;

2081 }

2082 }

2083

2084

2085

2086

2087 if (!Selected && Results[0].first.empty())

2088 Selected = 0;

2089}

2090

2092 -> std::optional {

2094 return std::nullopt;

2095

2097 if (!ClassID)

2098 return std::nullopt;

2099

2100

2101

2105 return std::nullopt;

2106

2108}

2109

2113 return std::nullopt;

2114

2116 if (!CtxID)

2117 return std::nullopt;

2118

2121 return std::nullopt;

2122

2124}

2125

2127 -> std::optional {

2129 return std::nullopt;

2130

2132 if (!classID)

2133 return std::nullopt;

2134

2135

2136

2140 return std::nullopt;

2141

2143}

2144

2148 return std::nullopt;

2149

2151 if (!CtxID)

2152 return std::nullopt;

2153

2156 return std::nullopt;

2157

2159}

2160

2162 bool IsInstance)

2165 return std::nullopt;

2166

2168 if (!PropertyID)

2169 return std::nullopt;

2170

2172 std::make_tuple(CtxID.Value, *PropertyID, (char)IsInstance));

2174 return std::nullopt;

2175

2177}

2178

2180 bool IsInstanceMethod)

2183 return std::nullopt;

2184

2186 if (!SelID)

2187 return std::nullopt;

2188

2190 ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,

2191 IsInstanceMethod});

2193 return std::nullopt;

2194

2196}

2197

2201 return std::nullopt;

2202

2204 if (!NameID)

2205 return std::nullopt;

2206

2210 return std::nullopt;

2211

2213}

2214

2218 return std::nullopt;

2219

2221 if (!NameID)

2222 return std::nullopt;

2223

2227 return std::nullopt;

2228

2230}

2231

2233 std::optional Ctx)

2236 return std::nullopt;

2237

2239 if (!NameID)

2240 return std::nullopt;

2241

2243

2246 return std::nullopt;

2247

2249}

2250

2252 std::optional Ctx)

2255 return std::nullopt;

2256

2258 if (!NameID)

2259 return std::nullopt;

2260

2262

2265 return std::nullopt;

2266

2268}

2269

2273 return std::nullopt;

2274

2276 if (!NameID)

2277 return std::nullopt;

2278

2281 return std::nullopt;

2282

2284}

2285

2287 std::optional ParentCtx)

2288 -> std::optional {

2290 return std::nullopt;

2291

2293 if (!TagID)

2294 return std::nullopt;

2295

2299 return std::nullopt;

2300

2302}

2303

2307 return std::nullopt;

2308

2310 if (!NameID)

2311 return std::nullopt;

2312

2314

2317 return std::nullopt;

2318

2320}

2321

2323 std::optional Ctx)

2326 return std::nullopt;

2327

2329 if (!NameID)

2330 return std::nullopt;

2331

2333

2336 return std::nullopt;

2337

2339}

2340

2342 llvm::StringRef Name, std::optional ParentNamespaceID)

2343 -> std::optional {

2345 return std::nullopt;

2346

2348 if (!NamespaceID)

2349 return std::nullopt;

2350

2351 uint32_t RawParentNamespaceID =

2352 ParentNamespaceID ? ParentNamespaceID->Value : -1;

2356 return std::nullopt;

2357

2359}

2360

2361}

2362}

FormatToken * Next

The next token in the unwrapped line.

static StringRef getIdentifier(const Token &Tok)

__SIZE_TYPE__ size_t

The unsigned integer type of the result of the sizeof operator.

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

Definition APINotesReader.cpp:685

llvm::OnDiskIterableChainedHashTable< FieldTableInfo > SerializedFieldTable

Definition APINotesReader.cpp:724

std::unique_ptr< SerializedContextIDTable > ContextIDTable

The Objective-C / C++ context ID table.

Definition APINotesReader.cpp:710

bool readEnumConstantBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1634

std::string ModuleName

The name of the module that we read from the control block.

Definition APINotesReader.cpp:694

std::optional< std::pair< off_t, time_t > > SourceFileSizeAndModTime

Definition APINotesReader.cpp:698

std::unique_ptr< SerializedIdentifierTable > IdentifierTable

The identifier table.

Definition APINotesReader.cpp:704

llvm::OnDiskIterableChainedHashTable< TagTableInfo > SerializedTagTable

Definition APINotesReader.cpp:766

llvm::OnDiskIterableChainedHashTable< GlobalFunctionTableInfo > SerializedGlobalFunctionTable

Definition APINotesReader.cpp:754

std::unique_ptr< SerializedGlobalFunctionTable > GlobalFunctionTable

The global function table.

Definition APINotesReader.cpp:758

std::unique_ptr< SerializedObjCPropertyTable > ObjCPropertyTable

The Objective-C property table.

Definition APINotesReader.cpp:722

bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1181

llvm::OnDiskIterableChainedHashTable< EnumConstantTableInfo > SerializedEnumConstantTable

Definition APINotesReader.cpp:760

std::unique_ptr< SerializedGlobalVariableTable > GlobalVariableTable

The global variable table.

Definition APINotesReader.cpp:752

bool readTagBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1710

std::unique_ptr< SerializedTypedefTable > TypedefTable

The typedef table.

Definition APINotesReader.cpp:775

bool readFieldBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1331

bool readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1558

bool readTypedefBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1785

llvm::MemoryBuffer * InputBuffer

The input buffer for the API notes data.

Definition APINotesReader.cpp:688

std::unique_ptr< SerializedObjCSelectorTable > ObjCSelectorTable

The Objective-C selector table.

Definition APINotesReader.cpp:746

llvm::OnDiskIterableChainedHashTable< ObjCMethodTableInfo > SerializedObjCMethodTable

Definition APINotesReader.cpp:730

bool readControlBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:851

llvm::OnDiskIterableChainedHashTable< CXXMethodTableInfo > SerializedCXXMethodTable

Definition APINotesReader.cpp:736

llvm::OnDiskIterableChainedHashTable< ContextInfoTableInfo > SerializedContextInfoTable

Definition APINotesReader.cpp:712

std::unique_ptr< SerializedCXXMethodTable > CXXMethodTable

The C++ method table.

Definition APINotesReader.cpp:740

llvm::OnDiskIterableChainedHashTable< ObjCSelectorTableInfo > SerializedObjCSelectorTable

Definition APINotesReader.cpp:742

llvm::OnDiskIterableChainedHashTable< IdentifierTableInfo > SerializedIdentifierTable

Definition APINotesReader.cpp:700

bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1104

bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1406

std::unique_ptr< SerializedEnumConstantTable > EnumConstantTable

The enumerator table.

Definition APINotesReader.cpp:764

std::optional< IdentifierID > getIdentifier(llvm::StringRef Str)

Retrieve the identifier ID for the given string, or an empty optional if the string is unknown.

Definition APINotesReader.cpp:814

bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1482

std::unique_ptr< SerializedTagTable > TagTable

The tag table.

Definition APINotesReader.cpp:769

std::unique_ptr< SerializedFieldTable > FieldTable

The C record field table.

Definition APINotesReader.cpp:728

std::optional< SelectorID > getSelector(ObjCSelectorRef Selector)

Retrieve the selector ID for the given selector, or an empty optional if the string is unknown.

Definition APINotesReader.cpp:829

llvm::OnDiskIterableChainedHashTable< TypedefTableInfo > SerializedTypedefTable

Definition APINotesReader.cpp:771

bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1256

bool readIdentifierBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:938

llvm::OnDiskIterableChainedHashTable< GlobalVariableTableInfo > SerializedGlobalVariableTable

Definition APINotesReader.cpp:748

llvm::VersionTuple SwiftVersion

The Swift version to use for filtering.

Definition APINotesReader.cpp:691

llvm::OnDiskIterableChainedHashTable< ContextIDTableInfo > SerializedContextIDTable

Definition APINotesReader.cpp:706

bool readContextBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)

Definition APINotesReader.cpp:1014

std::unique_ptr< SerializedObjCMethodTable > ObjCMethodTable

The Objective-C method table.

Definition APINotesReader.cpp:734

std::unique_ptr< SerializedContextInfoTable > ContextInfoTable

The Objective-C context info table.

Definition APINotesReader.cpp:716

llvm::OnDiskIterableChainedHashTable< ObjCPropertyTableInfo > SerializedObjCPropertyTable

Definition APINotesReader.cpp:718

Captures the completed versioned information for a particular part of API notes, including both unver...

VersionedInfo(std::nullopt_t)

Form an empty set of versioned information.

VersionedInfo< ContextInfo > lookupObjCClassInfo(llvm::StringRef Name)

Look for information regarding the given Objective-C class.

Definition APINotesReader.cpp:2110

VersionedInfo< FieldInfo > lookupField(ContextID CtxID, llvm::StringRef Name)

Look for information regarding the given field of a C struct.

Definition APINotesReader.cpp:2198

VersionedInfo< CXXMethodInfo > lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)

Look for information regarding the given C++ method in the given C++ tag context.

Definition APINotesReader.cpp:2215

VersionedInfo< TagInfo > lookupTag(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)

Look for information regarding the given tag (struct/union/enum/C++ class).

Definition APINotesReader.cpp:2304

VersionedInfo< GlobalFunctionInfo > lookupGlobalFunction(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)

Look for information regarding the given global function.

Definition APINotesReader.cpp:2251

VersionedInfo< ObjCPropertyInfo > lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance)

Look for information regarding the given Objective-C property in the given context.

Definition APINotesReader.cpp:2161

VersionedInfo< ObjCMethodInfo > lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, bool IsInstanceMethod)

Look for information regarding the given Objective-C method in the given context.

Definition APINotesReader.cpp:2179

VersionedInfo< GlobalVariableInfo > lookupGlobalVariable(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)

Look for information regarding the given global variable.

Definition APINotesReader.cpp:2232

std::optional< ContextID > lookupNamespaceID(llvm::StringRef Name, std::optional< ContextID > ParentNamespaceID=std::nullopt)

Look for the context ID of the given C++ namespace.

Definition APINotesReader.cpp:2341

std::optional< ContextID > lookupTagID(llvm::StringRef Name, std::optional< Context > ParentCtx=std::nullopt)

Look for the context ID of the given C++ tag.

Definition APINotesReader.cpp:2286

VersionedInfo< TypedefInfo > lookupTypedef(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)

Look for information regarding the given typedef.

Definition APINotesReader.cpp:2322

std::optional< ContextID > lookupObjCClassID(llvm::StringRef Name)

Look for the context ID of the given Objective-C class.

Definition APINotesReader.cpp:2091

static std::unique_ptr< APINotesReader > Create(std::unique_ptr< llvm::MemoryBuffer > InputBuffer, llvm::VersionTuple SwiftVersion)

Create a new API notes reader from the given member buffer, which contains the contents of a binary A...

Definition APINotesReader.cpp:2042

~APINotesReader()

Definition APINotesReader.cpp:2039

VersionedInfo< ContextInfo > lookupObjCProtocolInfo(llvm::StringRef Name)

Look for information regarding the given Objective-C protocol.

Definition APINotesReader.cpp:2145

std::optional< ContextID > lookupObjCProtocolID(llvm::StringRef Name)

Look for the context ID of the given Objective-C protocol.

Definition APINotesReader.cpp:2126

VersionedInfo< EnumConstantInfo > lookupEnumConstant(llvm::StringRef Name)

Look for information regarding the given enumerator.

Definition APINotesReader.cpp:2270

Describes API notes data for any entity.

Describes API notes for types.

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

API notes for a function or method.

Describes a function or method parameter.

API notes for a variable/property.

RetainCountConventionKind

llvm::PointerEmbeddedInt< unsigned, 31 > IdentifierID

llvm::PointerEmbeddedInt< unsigned, 31 > SelectorID

const uint8_t kSwiftConforms

SwiftNewTypeKind

The kind of a swift_wrapper/swift_newtype.

EnumExtensibilityKind

The payload for an enum_extensibility attribute.

const uint8_t kSwiftDoesNotConform

const uint16_t VERSION_MAJOR

API notes file major version number.

const unsigned char API_NOTES_SIGNATURE[]

Magic number for API notes files.

const uint16_t VERSION_MINOR

API notes file minor version number.

@ OBJC_CONTEXT_BLOCK_ID

The Objective-C context data block, which contains information about Objective-C classes and protocol...

@ TYPEDEF_BLOCK_ID

The typedef data block, which maps typedef names to information about the typedefs.

@ OBJC_PROPERTY_BLOCK_ID

The Objective-C property data block, which maps Objective-C (class name, property name) pairs to info...

@ ENUM_CONSTANT_BLOCK_ID

The enum constant data block, which maps enumerator names to information about the enumerators.

@ TAG_BLOCK_ID

The tag data block, which maps tag names to information about the tags.

@ OBJC_METHOD_BLOCK_ID

The Objective-C property data block, which maps Objective-C (class name, selector,...

@ FIELD_BLOCK_ID

The fields data block, which maps names fields of C records to information about the field.

@ OBJC_SELECTOR_BLOCK_ID

The Objective-C selector data block, which maps Objective-C selector names (# of pieces,...

@ CXX_METHOD_BLOCK_ID

The C++ method data block, which maps C++ (context id, method name) pairs to information about the me...

@ GLOBAL_FUNCTION_BLOCK_ID

The (global) functions data block, which maps global function names to information about the global f...

@ CONTROL_BLOCK_ID

The control block, which contains all of the information that needs to be validated prior to committi...

@ IDENTIFIER_BLOCK_ID

The identifier data block, which maps identifier strings to IDs.

@ GLOBAL_VARIABLE_BLOCK_ID

The global variables data block, which maps global variable names to information about the global var...

unsigned ComputeHash(Selector Sel)

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

NullabilityKind

Describes the nullability of a particular type.

@ Result

The result type of a method or function.

hash_code hash_value(const clang::dependencies::ModuleID &ID)

A stored Objective-C or C++ context, represented by the ID of its parent context, the kind of this co...

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

A stored Objective-C or C++ declaration, represented by the ID of its parent context,...

A stored Objective-C selector.

llvm::SmallVector< IdentifierID, 2 > Identifiers