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
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 (.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 (.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 (.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