xref: /freebsd/contrib/llvm-project/clang/lib/APINotes/APINotesReader.cpp (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
1 //===--- APINotesReader.cpp - API Notes Reader ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/APINotes/APINotesReader.h"
10 #include "APINotesFormat.h"
11 #include "llvm/ADT/Hashing.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/Bitstream/BitstreamReader.h"
14 #include "llvm/Support/DJB.h"
15 #include "llvm/Support/EndianStream.h"
16 #include "llvm/Support/OnDiskHashTable.h"
17 
18 namespace clang {
19 namespace api_notes {
20 using namespace llvm::support;
21 
22 namespace {
23 /// Deserialize a version tuple.
24 llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) {
25   uint8_t NumVersions = (*Data++) & 0x03;
26 
27   unsigned Major =
28       endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
29   if (NumVersions == 0)
30     return llvm::VersionTuple(Major);
31 
32   unsigned Minor =
33       endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
34   if (NumVersions == 1)
35     return llvm::VersionTuple(Major, Minor);
36 
37   unsigned Subminor =
38       endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
39   if (NumVersions == 2)
40     return llvm::VersionTuple(Major, Minor, Subminor);
41 
42   unsigned Build =
43       endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
44   return llvm::VersionTuple(Major, Minor, Subminor, Build);
45 }
46 
47 /// An on-disk hash table whose data is versioned based on the Swift version.
48 template <typename Derived, typename KeyType, typename UnversionedDataType>
49 class VersionedTableInfo {
50 public:
51   using internal_key_type = KeyType;
52   using external_key_type = KeyType;
53   using data_type =
54       llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
55   using hash_value_type = size_t;
56   using offset_type = unsigned;
57 
58   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
59 
60   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
61 
62   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
63     return LHS == RHS;
64   }
65 
66   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
67     unsigned KeyLength =
68         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
69     unsigned DataLength =
70         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
71     return {KeyLength, DataLength};
72   }
73 
74   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
75                             unsigned Length) {
76     unsigned NumElements =
77         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
78     data_type Result;
79     Result.reserve(NumElements);
80     for (unsigned i = 0; i != NumElements; ++i) {
81       auto version = ReadVersionTuple(Data);
82       const auto *DataBefore = Data;
83       (void)DataBefore;
84       assert(Data != DataBefore &&
85              "Unversioned data reader didn't move pointer");
86       auto UnversionedData = Derived::readUnversioned(Key, Data);
87       Result.push_back({version, UnversionedData});
88     }
89     return Result;
90   }
91 };
92 
93 /// Read serialized CommonEntityInfo.
94 void ReadCommonEntityInfo(const uint8_t *&Data, CommonEntityInfo &Info) {
95   uint8_t UnavailableBits = *Data++;
96   Info.Unavailable = (UnavailableBits >> 1) & 0x01;
97   Info.UnavailableInSwift = UnavailableBits & 0x01;
98   if ((UnavailableBits >> 2) & 0x01)
99     Info.setSwiftPrivate(static_cast<bool>((UnavailableBits >> 3) & 0x01));
100 
101   unsigned MsgLength =
102       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
103   Info.UnavailableMsg =
104       std::string(reinterpret_cast<const char *>(Data),
105                   reinterpret_cast<const char *>(Data) + MsgLength);
106   Data += MsgLength;
107 
108   unsigned SwiftNameLength =
109       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
110   Info.SwiftName =
111       std::string(reinterpret_cast<const char *>(Data),
112                   reinterpret_cast<const char *>(Data) + SwiftNameLength);
113   Data += SwiftNameLength;
114 }
115 
116 /// Read serialized CommonTypeInfo.
117 void ReadCommonTypeInfo(const uint8_t *&Data, CommonTypeInfo &Info) {
118   ReadCommonEntityInfo(Data, Info);
119 
120   unsigned SwiftBridgeLength =
121       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
122   if (SwiftBridgeLength > 0) {
123     Info.setSwiftBridge(std::string(reinterpret_cast<const char *>(Data),
124                                     SwiftBridgeLength - 1));
125     Data += SwiftBridgeLength - 1;
126   }
127 
128   unsigned ErrorDomainLength =
129       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
130   if (ErrorDomainLength > 0) {
131     Info.setNSErrorDomain(std::optional<std::string>(std::string(
132         reinterpret_cast<const char *>(Data), ErrorDomainLength - 1)));
133     Data += ErrorDomainLength - 1;
134   }
135 }
136 
137 /// Used to deserialize the on-disk identifier table.
138 class IdentifierTableInfo {
139 public:
140   using internal_key_type = llvm::StringRef;
141   using external_key_type = llvm::StringRef;
142   using data_type = IdentifierID;
143   using hash_value_type = uint32_t;
144   using offset_type = unsigned;
145 
146   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
147 
148   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
149 
150   hash_value_type ComputeHash(internal_key_type Key) {
151     return llvm::hash_value(Key);
152   }
153 
154   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
155     return LHS == RHS;
156   }
157 
158   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
159     unsigned KeyLength =
160         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
161     unsigned DataLength =
162         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
163     return {KeyLength, DataLength};
164   }
165 
166   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
167     return llvm::StringRef(reinterpret_cast<const char *>(Data), Length);
168   }
169 
170   static data_type ReadData(internal_key_type key, const uint8_t *Data,
171                             unsigned Length) {
172     return endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
173         Data);
174   }
175 };
176 
177 /// Used to deserialize the on-disk Objective-C class table.
178 class ObjCContextIDTableInfo {
179 public:
180   using internal_key_type = ContextTableKey;
181   using external_key_type = internal_key_type;
182   using data_type = unsigned;
183   using hash_value_type = size_t;
184   using offset_type = unsigned;
185 
186   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
187 
188   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
189 
190   hash_value_type ComputeHash(internal_key_type Key) {
191     return static_cast<size_t>(Key.hashValue());
192   }
193 
194   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
195     return LHS == RHS;
196   }
197 
198   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
199     unsigned KeyLength =
200         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
201     unsigned DataLength =
202         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
203     return {KeyLength, DataLength};
204   }
205 
206   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
207     auto ParentCtxID =
208         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
209     auto ContextKind =
210         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
211     auto NameID =
212         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
213     return {ParentCtxID, ContextKind, NameID};
214   }
215 
216   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
217                             unsigned Length) {
218     return endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
219         Data);
220   }
221 };
222 
223 /// Used to deserialize the on-disk Objective-C property table.
224 class ObjCContextInfoTableInfo
225     : public VersionedTableInfo<ObjCContextInfoTableInfo, unsigned,
226                                 ObjCContextInfo> {
227 public:
228   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
229     return endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
230         Data);
231   }
232 
233   hash_value_type ComputeHash(internal_key_type Key) {
234     return static_cast<size_t>(llvm::hash_value(Key));
235   }
236 
237   static ObjCContextInfo readUnversioned(internal_key_type Key,
238                                          const uint8_t *&Data) {
239     ObjCContextInfo Info;
240     ReadCommonTypeInfo(Data, Info);
241     uint8_t Payload = *Data++;
242 
243     if (Payload & 0x01)
244       Info.setHasDesignatedInits(true);
245     Payload = Payload >> 1;
246 
247     if (Payload & 0x4)
248       Info.setDefaultNullability(static_cast<NullabilityKind>(Payload & 0x03));
249     Payload >>= 3;
250 
251     if (Payload & (1 << 1))
252       Info.setSwiftObjCMembers(Payload & 1);
253     Payload >>= 2;
254 
255     if (Payload & (1 << 1))
256       Info.setSwiftImportAsNonGeneric(Payload & 1);
257 
258     return Info;
259   }
260 };
261 
262 /// Read serialized VariableInfo.
263 void ReadVariableInfo(const uint8_t *&Data, VariableInfo &Info) {
264   ReadCommonEntityInfo(Data, Info);
265   if (*Data++) {
266     Info.setNullabilityAudited(static_cast<NullabilityKind>(*Data));
267   }
268   ++Data;
269 
270   auto TypeLen =
271       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
272   Info.setType(std::string(Data, Data + TypeLen));
273   Data += TypeLen;
274 }
275 
276 /// Used to deserialize the on-disk Objective-C property table.
277 class ObjCPropertyTableInfo
278     : public VersionedTableInfo<ObjCPropertyTableInfo,
279                                 std::tuple<uint32_t, uint32_t, uint8_t>,
280                                 ObjCPropertyInfo> {
281 public:
282   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
283     auto ClassID =
284         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
285     auto NameID =
286         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
287     char IsInstance =
288         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
289     return {ClassID, NameID, IsInstance};
290   }
291 
292   hash_value_type ComputeHash(internal_key_type Key) {
293     return static_cast<size_t>(llvm::hash_value(Key));
294   }
295 
296   static ObjCPropertyInfo readUnversioned(internal_key_type Key,
297                                           const uint8_t *&Data) {
298     ObjCPropertyInfo Info;
299     ReadVariableInfo(Data, Info);
300     uint8_t Flags = *Data++;
301     if (Flags & (1 << 0))
302       Info.setSwiftImportAsAccessors(Flags & (1 << 1));
303     return Info;
304   }
305 };
306 
307 /// Read serialized ParamInfo.
308 void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
309   ReadVariableInfo(Data, Info);
310 
311   uint8_t Payload =
312       endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
313   if (auto RawConvention = Payload & 0x7) {
314     auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1);
315     Info.setRetainCountConvention(Convention);
316   }
317   Payload >>= 3;
318   if (Payload & 0x01)
319     Info.setNoEscape(Payload & 0x02);
320   Payload >>= 2;
321   assert(Payload == 0 && "Bad API notes");
322 }
323 
324 /// Read serialized FunctionInfo.
325 void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) {
326   ReadCommonEntityInfo(Data, Info);
327 
328   uint8_t Payload =
329       endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
330   if (auto RawConvention = Payload & 0x7) {
331     auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1);
332     Info.setRetainCountConvention(Convention);
333   }
334   Payload >>= 3;
335   Info.NullabilityAudited = Payload & 0x1;
336   Payload >>= 1;
337   assert(Payload == 0 && "Bad API notes");
338 
339   Info.NumAdjustedNullable =
340       endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
341   Info.NullabilityPayload =
342       endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Data);
343 
344   unsigned NumParams =
345       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
346   while (NumParams > 0) {
347     ParamInfo pi;
348     ReadParamInfo(Data, pi);
349     Info.Params.push_back(pi);
350     --NumParams;
351   }
352 
353   unsigned ResultTypeLen =
354       endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
355   Info.ResultType = std::string(Data, Data + ResultTypeLen);
356   Data += ResultTypeLen;
357 }
358 
359 /// Used to deserialize the on-disk Objective-C method table.
360 class ObjCMethodTableInfo
361     : public VersionedTableInfo<ObjCMethodTableInfo,
362                                 std::tuple<uint32_t, uint32_t, uint8_t>,
363                                 ObjCMethodInfo> {
364 public:
365   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
366     auto ClassID =
367         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
368     auto SelectorID =
369         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
370     auto IsInstance =
371         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
372     return {ClassID, SelectorID, IsInstance};
373   }
374 
375   hash_value_type ComputeHash(internal_key_type Key) {
376     return static_cast<size_t>(llvm::hash_value(Key));
377   }
378 
379   static ObjCMethodInfo readUnversioned(internal_key_type Key,
380                                         const uint8_t *&Data) {
381     ObjCMethodInfo Info;
382     uint8_t Payload = *Data++;
383     Info.RequiredInit = Payload & 0x01;
384     Payload >>= 1;
385     Info.DesignatedInit = Payload & 0x01;
386     Payload >>= 1;
387 
388     ReadFunctionInfo(Data, Info);
389     return Info;
390   }
391 };
392 
393 /// Used to deserialize the on-disk Objective-C selector table.
394 class ObjCSelectorTableInfo {
395 public:
396   using internal_key_type = StoredObjCSelector;
397   using external_key_type = internal_key_type;
398   using data_type = SelectorID;
399   using hash_value_type = unsigned;
400   using offset_type = unsigned;
401 
402   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
403 
404   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
405 
406   hash_value_type ComputeHash(internal_key_type Key) {
407     return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
408   }
409 
410   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
411     return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS);
412   }
413 
414   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
415     unsigned KeyLength =
416         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
417     unsigned DataLength =
418         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
419     return {KeyLength, DataLength};
420   }
421 
422   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
423     internal_key_type Key;
424     Key.NumArgs =
425         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
426     unsigned NumIdents = (Length - sizeof(uint16_t)) / sizeof(uint32_t);
427     for (unsigned i = 0; i != NumIdents; ++i) {
428       Key.Identifiers.push_back(
429           endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
430               Data));
431     }
432     return Key;
433   }
434 
435   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
436                             unsigned Length) {
437     return endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
438         Data);
439   }
440 };
441 
442 /// Used to deserialize the on-disk global variable table.
443 class GlobalVariableTableInfo
444     : public VersionedTableInfo<GlobalVariableTableInfo, ContextTableKey,
445                                 GlobalVariableInfo> {
446 public:
447   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
448     auto CtxID =
449         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
450     auto ContextKind =
451         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
452     auto NameID =
453         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
454     return {CtxID, ContextKind, NameID};
455   }
456 
457   hash_value_type ComputeHash(internal_key_type Key) {
458     return static_cast<size_t>(Key.hashValue());
459   }
460 
461   static GlobalVariableInfo readUnversioned(internal_key_type Key,
462                                             const uint8_t *&Data) {
463     GlobalVariableInfo Info;
464     ReadVariableInfo(Data, Info);
465     return Info;
466   }
467 };
468 
469 /// Used to deserialize the on-disk global function table.
470 class GlobalFunctionTableInfo
471     : public VersionedTableInfo<GlobalFunctionTableInfo, ContextTableKey,
472                                 GlobalFunctionInfo> {
473 public:
474   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
475     auto CtxID =
476         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
477     auto ContextKind =
478         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
479     auto NameID =
480         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
481     return {CtxID, ContextKind, NameID};
482   }
483 
484   hash_value_type ComputeHash(internal_key_type Key) {
485     return static_cast<size_t>(Key.hashValue());
486   }
487 
488   static GlobalFunctionInfo readUnversioned(internal_key_type Key,
489                                             const uint8_t *&Data) {
490     GlobalFunctionInfo Info;
491     ReadFunctionInfo(Data, Info);
492     return Info;
493   }
494 };
495 
496 /// Used to deserialize the on-disk enumerator table.
497 class EnumConstantTableInfo
498     : public VersionedTableInfo<EnumConstantTableInfo, uint32_t,
499                                 EnumConstantInfo> {
500 public:
501   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
502     auto NameID =
503         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
504     return NameID;
505   }
506 
507   hash_value_type ComputeHash(internal_key_type Key) {
508     return static_cast<size_t>(llvm::hash_value(Key));
509   }
510 
511   static EnumConstantInfo readUnversioned(internal_key_type Key,
512                                           const uint8_t *&Data) {
513     EnumConstantInfo Info;
514     ReadCommonEntityInfo(Data, Info);
515     return Info;
516   }
517 };
518 
519 /// Used to deserialize the on-disk tag table.
520 class TagTableInfo
521     : public VersionedTableInfo<TagTableInfo, ContextTableKey, TagInfo> {
522 public:
523   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
524     auto CtxID =
525         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
526     auto ContextKind =
527         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
528     auto NameID =
529         endian::readNext<IdentifierID, llvm::endianness::little, unaligned>(
530             Data);
531     return {CtxID, ContextKind, NameID};
532   }
533 
534   hash_value_type ComputeHash(internal_key_type Key) {
535     return static_cast<size_t>(Key.hashValue());
536   }
537 
538   static TagInfo readUnversioned(internal_key_type Key, const uint8_t *&Data) {
539     TagInfo Info;
540 
541     uint8_t Payload = *Data++;
542     if (Payload & 1)
543       Info.setFlagEnum(Payload & 2);
544     Payload >>= 2;
545     if (Payload > 0)
546       Info.EnumExtensibility =
547           static_cast<EnumExtensibilityKind>((Payload & 0x3) - 1);
548 
549     unsigned ImportAsLength =
550         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
551     if (ImportAsLength > 0) {
552       Info.SwiftImportAs =
553           std::string(reinterpret_cast<const char *>(Data), ImportAsLength - 1);
554       Data += ImportAsLength - 1;
555     }
556     unsigned RetainOpLength =
557         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
558     if (RetainOpLength > 0) {
559       Info.SwiftRetainOp =
560           std::string(reinterpret_cast<const char *>(Data), RetainOpLength - 1);
561       Data += RetainOpLength - 1;
562     }
563     unsigned ReleaseOpLength =
564         endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
565     if (ReleaseOpLength > 0) {
566       Info.SwiftReleaseOp = std::string(reinterpret_cast<const char *>(Data),
567                                         ReleaseOpLength - 1);
568       Data += ReleaseOpLength - 1;
569     }
570 
571     ReadCommonTypeInfo(Data, Info);
572     return Info;
573   }
574 };
575 
576 /// Used to deserialize the on-disk typedef table.
577 class TypedefTableInfo
578     : public VersionedTableInfo<TypedefTableInfo, ContextTableKey,
579                                 TypedefInfo> {
580 public:
581   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
582     auto CtxID =
583         endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
584     auto ContextKind =
585         endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data);
586     auto nameID =
587         endian::readNext<IdentifierID, llvm::endianness::little, unaligned>(
588             Data);
589     return {CtxID, ContextKind, nameID};
590   }
591 
592   hash_value_type ComputeHash(internal_key_type Key) {
593     return static_cast<size_t>(Key.hashValue());
594   }
595 
596   static TypedefInfo readUnversioned(internal_key_type Key,
597                                      const uint8_t *&Data) {
598     TypedefInfo Info;
599 
600     uint8_t Payload = *Data++;
601     if (Payload > 0)
602       Info.SwiftWrapper = static_cast<SwiftNewTypeKind>((Payload & 0x3) - 1);
603 
604     ReadCommonTypeInfo(Data, Info);
605     return Info;
606   }
607 };
608 } // end anonymous namespace
609 
610 class APINotesReader::Implementation {
611 public:
612   /// The input buffer for the API notes data.
613   llvm::MemoryBuffer *InputBuffer;
614 
615   /// The Swift version to use for filtering.
616   llvm::VersionTuple SwiftVersion;
617 
618   /// The name of the module that we read from the control block.
619   std::string ModuleName;
620 
621   // The size and modification time of the source file from
622   // which this API notes file was created, if known.
623   std::optional<std::pair<off_t, time_t>> SourceFileSizeAndModTime;
624 
625   using SerializedIdentifierTable =
626       llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
627 
628   /// The identifier table.
629   std::unique_ptr<SerializedIdentifierTable> IdentifierTable;
630 
631   using SerializedObjCContextIDTable =
632       llvm::OnDiskIterableChainedHashTable<ObjCContextIDTableInfo>;
633 
634   /// The Objective-C context ID table.
635   std::unique_ptr<SerializedObjCContextIDTable> ObjCContextIDTable;
636 
637   using SerializedObjCContextInfoTable =
638       llvm::OnDiskIterableChainedHashTable<ObjCContextInfoTableInfo>;
639 
640   /// The Objective-C context info table.
641   std::unique_ptr<SerializedObjCContextInfoTable> ObjCContextInfoTable;
642 
643   using SerializedObjCPropertyTable =
644       llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
645 
646   /// The Objective-C property table.
647   std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;
648 
649   using SerializedObjCMethodTable =
650       llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
651 
652   /// The Objective-C method table.
653   std::unique_ptr<SerializedObjCMethodTable> ObjCMethodTable;
654 
655   using SerializedObjCSelectorTable =
656       llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
657 
658   /// The Objective-C selector table.
659   std::unique_ptr<SerializedObjCSelectorTable> ObjCSelectorTable;
660 
661   using SerializedGlobalVariableTable =
662       llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
663 
664   /// The global variable table.
665   std::unique_ptr<SerializedGlobalVariableTable> GlobalVariableTable;
666 
667   using SerializedGlobalFunctionTable =
668       llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
669 
670   /// The global function table.
671   std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable;
672 
673   using SerializedEnumConstantTable =
674       llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
675 
676   /// The enumerator table.
677   std::unique_ptr<SerializedEnumConstantTable> EnumConstantTable;
678 
679   using SerializedTagTable = llvm::OnDiskIterableChainedHashTable<TagTableInfo>;
680 
681   /// The tag table.
682   std::unique_ptr<SerializedTagTable> TagTable;
683 
684   using SerializedTypedefTable =
685       llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
686 
687   /// The typedef table.
688   std::unique_ptr<SerializedTypedefTable> TypedefTable;
689 
690   /// Retrieve the identifier ID for the given string, or an empty
691   /// optional if the string is unknown.
692   std::optional<IdentifierID> getIdentifier(llvm::StringRef Str);
693 
694   /// Retrieve the selector ID for the given selector, or an empty
695   /// optional if the string is unknown.
696   std::optional<SelectorID> getSelector(ObjCSelectorRef Selector);
697 
698   bool readControlBlock(llvm::BitstreamCursor &Cursor,
699                         llvm::SmallVectorImpl<uint64_t> &Scratch);
700   bool readIdentifierBlock(llvm::BitstreamCursor &Cursor,
701                            llvm::SmallVectorImpl<uint64_t> &Scratch);
702   bool readObjCContextBlock(llvm::BitstreamCursor &Cursor,
703                             llvm::SmallVectorImpl<uint64_t> &Scratch);
704   bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor,
705                              llvm::SmallVectorImpl<uint64_t> &Scratch);
706   bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor,
707                            llvm::SmallVectorImpl<uint64_t> &Scratch);
708   bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor,
709                              llvm::SmallVectorImpl<uint64_t> &Scratch);
710   bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
711                                llvm::SmallVectorImpl<uint64_t> &Scratch);
712   bool readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor,
713                                llvm::SmallVectorImpl<uint64_t> &Scratch);
714   bool readEnumConstantBlock(llvm::BitstreamCursor &Cursor,
715                              llvm::SmallVectorImpl<uint64_t> &Scratch);
716   bool readTagBlock(llvm::BitstreamCursor &Cursor,
717                     llvm::SmallVectorImpl<uint64_t> &Scratch);
718   bool readTypedefBlock(llvm::BitstreamCursor &Cursor,
719                         llvm::SmallVectorImpl<uint64_t> &Scratch);
720 };
721 
722 std::optional<IdentifierID>
723 APINotesReader::Implementation::getIdentifier(llvm::StringRef Str) {
724   if (!IdentifierTable)
725     return std::nullopt;
726 
727   if (Str.empty())
728     return IdentifierID(0);
729 
730   auto Known = IdentifierTable->find(Str);
731   if (Known == IdentifierTable->end())
732     return std::nullopt;
733 
734   return *Known;
735 }
736 
737 std::optional<SelectorID>
738 APINotesReader::Implementation::getSelector(ObjCSelectorRef Selector) {
739   if (!ObjCSelectorTable || !IdentifierTable)
740     return std::nullopt;
741 
742   // Translate the identifiers.
743   StoredObjCSelector Key;
744   Key.NumArgs = Selector.NumArgs;
745   for (auto Ident : Selector.Identifiers) {
746     if (auto IdentID = getIdentifier(Ident)) {
747       Key.Identifiers.push_back(*IdentID);
748     } else {
749       return std::nullopt;
750     }
751   }
752 
753   auto Known = ObjCSelectorTable->find(Key);
754   if (Known == ObjCSelectorTable->end())
755     return std::nullopt;
756 
757   return *Known;
758 }
759 
760 bool APINotesReader::Implementation::readControlBlock(
761     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
762   if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID))
763     return true;
764 
765   bool SawMetadata = false;
766 
767   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
768   if (!MaybeNext) {
769     // FIXME this drops the error on the floor.
770     consumeError(MaybeNext.takeError());
771     return false;
772   }
773   llvm::BitstreamEntry Next = MaybeNext.get();
774 
775   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
776     if (Next.Kind == llvm::BitstreamEntry::Error)
777       return true;
778 
779     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
780       // Unknown metadata sub-block, possibly for use by a future version of the
781       // API notes format.
782       if (Cursor.SkipBlock())
783         return true;
784 
785       MaybeNext = Cursor.advance();
786       if (!MaybeNext) {
787         // FIXME this drops the error on the floor.
788         consumeError(MaybeNext.takeError());
789         return false;
790       }
791       Next = MaybeNext.get();
792       continue;
793     }
794 
795     Scratch.clear();
796     llvm::StringRef BlobData;
797     llvm::Expected<unsigned> MaybeKind =
798         Cursor.readRecord(Next.ID, Scratch, &BlobData);
799     if (!MaybeKind) {
800       // FIXME this drops the error on the floor.
801       consumeError(MaybeKind.takeError());
802       return false;
803     }
804     unsigned Kind = MaybeKind.get();
805 
806     switch (Kind) {
807     case control_block::METADATA:
808       // Already saw metadata.
809       if (SawMetadata)
810         return true;
811 
812       if (Scratch[0] != VERSION_MAJOR || Scratch[1] != VERSION_MINOR)
813         return true;
814 
815       SawMetadata = true;
816       break;
817 
818     case control_block::MODULE_NAME:
819       ModuleName = BlobData.str();
820       break;
821 
822     case control_block::MODULE_OPTIONS:
823       break;
824 
825     case control_block::SOURCE_FILE:
826       SourceFileSizeAndModTime = {Scratch[0], Scratch[1]};
827       break;
828 
829     default:
830       // Unknown metadata record, possibly for use by a future version of the
831       // module format.
832       break;
833     }
834 
835     MaybeNext = Cursor.advance();
836     if (!MaybeNext) {
837       // FIXME this drops the error on the floor.
838       consumeError(MaybeNext.takeError());
839       return false;
840     }
841     Next = MaybeNext.get();
842   }
843 
844   return !SawMetadata;
845 }
846 
847 bool APINotesReader::Implementation::readIdentifierBlock(
848     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
849   if (Cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID))
850     return true;
851 
852   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
853   if (!MaybeNext) {
854     // FIXME this drops the error on the floor.
855     consumeError(MaybeNext.takeError());
856     return false;
857   }
858   llvm::BitstreamEntry Next = MaybeNext.get();
859 
860   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
861     if (Next.Kind == llvm::BitstreamEntry::Error)
862       return true;
863 
864     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
865       // Unknown sub-block, possibly for use by a future version of the
866       // API notes format.
867       if (Cursor.SkipBlock())
868         return true;
869 
870       MaybeNext = Cursor.advance();
871       if (!MaybeNext) {
872         // FIXME this drops the error on the floor.
873         consumeError(MaybeNext.takeError());
874         return false;
875       }
876       Next = MaybeNext.get();
877       continue;
878     }
879 
880     Scratch.clear();
881     llvm::StringRef BlobData;
882     llvm::Expected<unsigned> MaybeKind =
883         Cursor.readRecord(Next.ID, Scratch, &BlobData);
884     if (!MaybeKind) {
885       // FIXME this drops the error on the floor.
886       consumeError(MaybeKind.takeError());
887       return false;
888     }
889     unsigned Kind = MaybeKind.get();
890     switch (Kind) {
891     case identifier_block::IDENTIFIER_DATA: {
892       // Already saw identifier table.
893       if (IdentifierTable)
894         return true;
895 
896       uint32_t tableOffset;
897       identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);
898       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
899 
900       IdentifierTable.reset(SerializedIdentifierTable::Create(
901           base + tableOffset, base + sizeof(uint32_t), base));
902       break;
903     }
904 
905     default:
906       // Unknown record, possibly for use by a future version of the
907       // module format.
908       break;
909     }
910 
911     MaybeNext = Cursor.advance();
912     if (!MaybeNext) {
913       // FIXME this drops the error on the floor.
914       consumeError(MaybeNext.takeError());
915       return false;
916     }
917     Next = MaybeNext.get();
918   }
919 
920   return false;
921 }
922 
923 bool APINotesReader::Implementation::readObjCContextBlock(
924     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
925   if (Cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID))
926     return true;
927 
928   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
929   if (!MaybeNext) {
930     // FIXME this drops the error on the floor.
931     consumeError(MaybeNext.takeError());
932     return false;
933   }
934   llvm::BitstreamEntry Next = MaybeNext.get();
935 
936   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
937     if (Next.Kind == llvm::BitstreamEntry::Error)
938       return true;
939 
940     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
941       // Unknown sub-block, possibly for use by a future version of the
942       // API notes format.
943       if (Cursor.SkipBlock())
944         return true;
945 
946       MaybeNext = Cursor.advance();
947       if (!MaybeNext) {
948         // FIXME this drops the error on the floor.
949         consumeError(MaybeNext.takeError());
950         return false;
951       }
952       Next = MaybeNext.get();
953       continue;
954     }
955 
956     Scratch.clear();
957     llvm::StringRef BlobData;
958     llvm::Expected<unsigned> MaybeKind =
959         Cursor.readRecord(Next.ID, Scratch, &BlobData);
960     if (!MaybeKind) {
961       // FIXME this drops the error on the floor.
962       consumeError(MaybeKind.takeError());
963       return false;
964     }
965     unsigned Kind = MaybeKind.get();
966     switch (Kind) {
967     case objc_context_block::OBJC_CONTEXT_ID_DATA: {
968       // Already saw Objective-C context ID table.
969       if (ObjCContextIDTable)
970         return true;
971 
972       uint32_t tableOffset;
973       objc_context_block::ObjCContextIDLayout::readRecord(Scratch, tableOffset);
974       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
975 
976       ObjCContextIDTable.reset(SerializedObjCContextIDTable::Create(
977           base + tableOffset, base + sizeof(uint32_t), base));
978       break;
979     }
980 
981     case objc_context_block::OBJC_CONTEXT_INFO_DATA: {
982       // Already saw Objective-C context info table.
983       if (ObjCContextInfoTable)
984         return true;
985 
986       uint32_t tableOffset;
987       objc_context_block::ObjCContextInfoLayout::readRecord(Scratch,
988                                                             tableOffset);
989       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
990 
991       ObjCContextInfoTable.reset(SerializedObjCContextInfoTable::Create(
992           base + tableOffset, base + sizeof(uint32_t), base));
993       break;
994     }
995 
996     default:
997       // Unknown record, possibly for use by a future version of the
998       // module format.
999       break;
1000     }
1001 
1002     MaybeNext = Cursor.advance();
1003     if (!MaybeNext) {
1004       // FIXME this drops the error on the floor.
1005       consumeError(MaybeNext.takeError());
1006       return false;
1007     }
1008     Next = MaybeNext.get();
1009   }
1010 
1011   return false;
1012 }
1013 
1014 bool APINotesReader::Implementation::readObjCPropertyBlock(
1015     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1016   if (Cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID))
1017     return true;
1018 
1019   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1020   if (!MaybeNext) {
1021     // FIXME this drops the error on the floor.
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       // Unknown sub-block, possibly for use by a future version of the
1033       // API notes format.
1034       if (Cursor.SkipBlock())
1035         return true;
1036 
1037       MaybeNext = Cursor.advance();
1038       if (!MaybeNext) {
1039         // FIXME this drops the error on the floor.
1040         consumeError(MaybeNext.takeError());
1041         return false;
1042       }
1043       Next = MaybeNext.get();
1044       continue;
1045     }
1046 
1047     Scratch.clear();
1048     llvm::StringRef BlobData;
1049     llvm::Expected<unsigned> MaybeKind =
1050         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1051     if (!MaybeKind) {
1052       // FIXME this drops the error on the floor.
1053       consumeError(MaybeKind.takeError());
1054       return false;
1055     }
1056     unsigned Kind = MaybeKind.get();
1057     switch (Kind) {
1058     case objc_property_block::OBJC_PROPERTY_DATA: {
1059       // Already saw Objective-C property table.
1060       if (ObjCPropertyTable)
1061         return true;
1062 
1063       uint32_t tableOffset;
1064       objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,
1065                                                               tableOffset);
1066       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1067 
1068       ObjCPropertyTable.reset(SerializedObjCPropertyTable::Create(
1069           base + tableOffset, base + sizeof(uint32_t), base));
1070       break;
1071     }
1072 
1073     default:
1074       // Unknown record, possibly for use by a future version of the
1075       // module format.
1076       break;
1077     }
1078 
1079     MaybeNext = Cursor.advance();
1080     if (!MaybeNext) {
1081       // FIXME this drops the error on the floor.
1082       consumeError(MaybeNext.takeError());
1083       return false;
1084     }
1085     Next = MaybeNext.get();
1086   }
1087 
1088   return false;
1089 }
1090 
1091 bool APINotesReader::Implementation::readObjCMethodBlock(
1092     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1093   if (Cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID))
1094     return true;
1095 
1096   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1097   if (!MaybeNext) {
1098     // FIXME this drops the error on the floor.
1099     consumeError(MaybeNext.takeError());
1100     return false;
1101   }
1102   llvm::BitstreamEntry Next = MaybeNext.get();
1103   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1104     if (Next.Kind == llvm::BitstreamEntry::Error)
1105       return true;
1106 
1107     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1108       // Unknown sub-block, possibly for use by a future version of the
1109       // API notes format.
1110       if (Cursor.SkipBlock())
1111         return true;
1112 
1113       MaybeNext = Cursor.advance();
1114       if (!MaybeNext) {
1115         // FIXME this drops the error on the floor.
1116         consumeError(MaybeNext.takeError());
1117         return false;
1118       }
1119       Next = MaybeNext.get();
1120       continue;
1121     }
1122 
1123     Scratch.clear();
1124     llvm::StringRef BlobData;
1125     llvm::Expected<unsigned> MaybeKind =
1126         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1127     if (!MaybeKind) {
1128       // FIXME this drops the error on the floor.
1129       consumeError(MaybeKind.takeError());
1130       return false;
1131     }
1132     unsigned Kind = MaybeKind.get();
1133     switch (Kind) {
1134     case objc_method_block::OBJC_METHOD_DATA: {
1135       // Already saw Objective-C method table.
1136       if (ObjCMethodTable)
1137         return true;
1138 
1139       uint32_t tableOffset;
1140       objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);
1141       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1142 
1143       ObjCMethodTable.reset(SerializedObjCMethodTable::Create(
1144           base + tableOffset, base + sizeof(uint32_t), base));
1145       break;
1146     }
1147 
1148     default:
1149       // Unknown record, possibly for use by a future version of the
1150       // module format.
1151       break;
1152     }
1153 
1154     MaybeNext = Cursor.advance();
1155     if (!MaybeNext) {
1156       // FIXME this drops the error on the floor.
1157       consumeError(MaybeNext.takeError());
1158       return false;
1159     }
1160     Next = MaybeNext.get();
1161   }
1162 
1163   return false;
1164 }
1165 
1166 bool APINotesReader::Implementation::readObjCSelectorBlock(
1167     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1168   if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
1169     return true;
1170 
1171   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1172   if (!MaybeNext) {
1173     // FIXME this drops the error on the floor.
1174     consumeError(MaybeNext.takeError());
1175     return false;
1176   }
1177   llvm::BitstreamEntry Next = MaybeNext.get();
1178   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1179     if (Next.Kind == llvm::BitstreamEntry::Error)
1180       return true;
1181 
1182     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1183       // Unknown sub-block, possibly for use by a future version of the
1184       // API notes format.
1185       if (Cursor.SkipBlock())
1186         return true;
1187 
1188       MaybeNext = Cursor.advance();
1189       if (!MaybeNext) {
1190         // FIXME this drops the error on the floor.
1191         consumeError(MaybeNext.takeError());
1192         return false;
1193       }
1194       Next = MaybeNext.get();
1195       continue;
1196     }
1197 
1198     Scratch.clear();
1199     llvm::StringRef BlobData;
1200     llvm::Expected<unsigned> MaybeKind =
1201         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1202     if (!MaybeKind) {
1203       // FIXME this drops the error on the floor.
1204       consumeError(MaybeKind.takeError());
1205       return false;
1206     }
1207     unsigned Kind = MaybeKind.get();
1208     switch (Kind) {
1209     case objc_selector_block::OBJC_SELECTOR_DATA: {
1210       // Already saw Objective-C selector table.
1211       if (ObjCSelectorTable)
1212         return true;
1213 
1214       uint32_t tableOffset;
1215       objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,
1216                                                               tableOffset);
1217       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1218 
1219       ObjCSelectorTable.reset(SerializedObjCSelectorTable::Create(
1220           base + tableOffset, base + sizeof(uint32_t), base));
1221       break;
1222     }
1223 
1224     default:
1225       // Unknown record, possibly for use by a future version of the
1226       // module format.
1227       break;
1228     }
1229 
1230     MaybeNext = Cursor.advance();
1231     if (!MaybeNext) {
1232       // FIXME this drops the error on the floor.
1233       consumeError(MaybeNext.takeError());
1234       return false;
1235     }
1236     Next = MaybeNext.get();
1237   }
1238 
1239   return false;
1240 }
1241 
1242 bool APINotesReader::Implementation::readGlobalVariableBlock(
1243     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1244   if (Cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID))
1245     return true;
1246 
1247   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1248   if (!MaybeNext) {
1249     // FIXME this drops the error on the floor.
1250     consumeError(MaybeNext.takeError());
1251     return false;
1252   }
1253   llvm::BitstreamEntry Next = MaybeNext.get();
1254   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1255     if (Next.Kind == llvm::BitstreamEntry::Error)
1256       return true;
1257 
1258     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1259       // Unknown sub-block, possibly for use by a future version of the
1260       // API notes format.
1261       if (Cursor.SkipBlock())
1262         return true;
1263 
1264       MaybeNext = Cursor.advance();
1265       if (!MaybeNext) {
1266         // FIXME this drops the error on the floor.
1267         consumeError(MaybeNext.takeError());
1268         return false;
1269       }
1270       Next = MaybeNext.get();
1271       continue;
1272     }
1273 
1274     Scratch.clear();
1275     llvm::StringRef BlobData;
1276     llvm::Expected<unsigned> MaybeKind =
1277         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1278     if (!MaybeKind) {
1279       // FIXME this drops the error on the floor.
1280       consumeError(MaybeKind.takeError());
1281       return false;
1282     }
1283     unsigned Kind = MaybeKind.get();
1284     switch (Kind) {
1285     case global_variable_block::GLOBAL_VARIABLE_DATA: {
1286       // Already saw global variable table.
1287       if (GlobalVariableTable)
1288         return true;
1289 
1290       uint32_t tableOffset;
1291       global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,
1292                                                                   tableOffset);
1293       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1294 
1295       GlobalVariableTable.reset(SerializedGlobalVariableTable::Create(
1296           base + tableOffset, base + sizeof(uint32_t), base));
1297       break;
1298     }
1299 
1300     default:
1301       // Unknown record, possibly for use by a future version of the
1302       // module format.
1303       break;
1304     }
1305 
1306     MaybeNext = Cursor.advance();
1307     if (!MaybeNext) {
1308       // FIXME this drops the error on the floor.
1309       consumeError(MaybeNext.takeError());
1310       return false;
1311     }
1312     Next = MaybeNext.get();
1313   }
1314 
1315   return false;
1316 }
1317 
1318 bool APINotesReader::Implementation::readGlobalFunctionBlock(
1319     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1320   if (Cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID))
1321     return true;
1322 
1323   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1324   if (!MaybeNext) {
1325     // FIXME this drops the error on the floor.
1326     consumeError(MaybeNext.takeError());
1327     return false;
1328   }
1329   llvm::BitstreamEntry Next = MaybeNext.get();
1330   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1331     if (Next.Kind == llvm::BitstreamEntry::Error)
1332       return true;
1333 
1334     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1335       // Unknown sub-block, possibly for use by a future version of the
1336       // API notes format.
1337       if (Cursor.SkipBlock())
1338         return true;
1339 
1340       MaybeNext = Cursor.advance();
1341       if (!MaybeNext) {
1342         // FIXME this drops the error on the floor.
1343         consumeError(MaybeNext.takeError());
1344         return false;
1345       }
1346       Next = MaybeNext.get();
1347       continue;
1348     }
1349 
1350     Scratch.clear();
1351     llvm::StringRef BlobData;
1352     llvm::Expected<unsigned> MaybeKind =
1353         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1354     if (!MaybeKind) {
1355       // FIXME this drops the error on the floor.
1356       consumeError(MaybeKind.takeError());
1357       return false;
1358     }
1359     unsigned Kind = MaybeKind.get();
1360     switch (Kind) {
1361     case global_function_block::GLOBAL_FUNCTION_DATA: {
1362       // Already saw global function table.
1363       if (GlobalFunctionTable)
1364         return true;
1365 
1366       uint32_t tableOffset;
1367       global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,
1368                                                                   tableOffset);
1369       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1370 
1371       GlobalFunctionTable.reset(SerializedGlobalFunctionTable::Create(
1372           base + tableOffset, base + sizeof(uint32_t), base));
1373       break;
1374     }
1375 
1376     default:
1377       // Unknown record, possibly for use by a future version of the
1378       // module format.
1379       break;
1380     }
1381 
1382     MaybeNext = Cursor.advance();
1383     if (!MaybeNext) {
1384       // FIXME this drops the error on the floor.
1385       consumeError(MaybeNext.takeError());
1386       return false;
1387     }
1388     Next = MaybeNext.get();
1389   }
1390 
1391   return false;
1392 }
1393 
1394 bool APINotesReader::Implementation::readEnumConstantBlock(
1395     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1396   if (Cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID))
1397     return true;
1398 
1399   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1400   if (!MaybeNext) {
1401     // FIXME this drops the error on the floor.
1402     consumeError(MaybeNext.takeError());
1403     return false;
1404   }
1405   llvm::BitstreamEntry Next = MaybeNext.get();
1406   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1407     if (Next.Kind == llvm::BitstreamEntry::Error)
1408       return true;
1409 
1410     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1411       // Unknown sub-block, possibly for use by a future version of the
1412       // API notes format.
1413       if (Cursor.SkipBlock())
1414         return true;
1415 
1416       MaybeNext = Cursor.advance();
1417       if (!MaybeNext) {
1418         // FIXME this drops the error on the floor.
1419         consumeError(MaybeNext.takeError());
1420         return false;
1421       }
1422       Next = MaybeNext.get();
1423       continue;
1424     }
1425 
1426     Scratch.clear();
1427     llvm::StringRef BlobData;
1428     llvm::Expected<unsigned> MaybeKind =
1429         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1430     if (!MaybeKind) {
1431       // FIXME this drops the error on the floor.
1432       consumeError(MaybeKind.takeError());
1433       return false;
1434     }
1435     unsigned Kind = MaybeKind.get();
1436     switch (Kind) {
1437     case enum_constant_block::ENUM_CONSTANT_DATA: {
1438       // Already saw enumerator table.
1439       if (EnumConstantTable)
1440         return true;
1441 
1442       uint32_t tableOffset;
1443       enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,
1444                                                               tableOffset);
1445       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1446 
1447       EnumConstantTable.reset(SerializedEnumConstantTable::Create(
1448           base + tableOffset, base + sizeof(uint32_t), base));
1449       break;
1450     }
1451 
1452     default:
1453       // Unknown record, possibly for use by a future version of the
1454       // module format.
1455       break;
1456     }
1457 
1458     MaybeNext = Cursor.advance();
1459     if (!MaybeNext) {
1460       // FIXME this drops the error on the floor.
1461       consumeError(MaybeNext.takeError());
1462       return false;
1463     }
1464     Next = MaybeNext.get();
1465   }
1466 
1467   return false;
1468 }
1469 
1470 bool APINotesReader::Implementation::readTagBlock(
1471     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1472   if (Cursor.EnterSubBlock(TAG_BLOCK_ID))
1473     return true;
1474 
1475   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1476   if (!MaybeNext) {
1477     // FIXME this drops the error on the floor.
1478     consumeError(MaybeNext.takeError());
1479     return false;
1480   }
1481   llvm::BitstreamEntry Next = MaybeNext.get();
1482   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1483     if (Next.Kind == llvm::BitstreamEntry::Error)
1484       return true;
1485 
1486     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1487       // Unknown sub-block, possibly for use by a future version of the
1488       // API notes format.
1489       if (Cursor.SkipBlock())
1490         return true;
1491 
1492       MaybeNext = Cursor.advance();
1493       if (!MaybeNext) {
1494         // FIXME this drops the error on the floor.
1495         consumeError(MaybeNext.takeError());
1496         return false;
1497       }
1498       Next = MaybeNext.get();
1499       continue;
1500     }
1501 
1502     Scratch.clear();
1503     llvm::StringRef BlobData;
1504     llvm::Expected<unsigned> MaybeKind =
1505         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1506     if (!MaybeKind) {
1507       // FIXME this drops the error on the floor.
1508       consumeError(MaybeKind.takeError());
1509       return false;
1510     }
1511     unsigned Kind = MaybeKind.get();
1512     switch (Kind) {
1513     case tag_block::TAG_DATA: {
1514       // Already saw tag table.
1515       if (TagTable)
1516         return true;
1517 
1518       uint32_t tableOffset;
1519       tag_block::TagDataLayout::readRecord(Scratch, tableOffset);
1520       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1521 
1522       TagTable.reset(SerializedTagTable::Create(base + tableOffset,
1523                                                 base + sizeof(uint32_t), base));
1524       break;
1525     }
1526 
1527     default:
1528       // Unknown record, possibly for use by a future version of the
1529       // module format.
1530       break;
1531     }
1532 
1533     MaybeNext = Cursor.advance();
1534     if (!MaybeNext) {
1535       // FIXME this drops the error on the floor.
1536       consumeError(MaybeNext.takeError());
1537       return false;
1538     }
1539     Next = MaybeNext.get();
1540   }
1541 
1542   return false;
1543 }
1544 
1545 bool APINotesReader::Implementation::readTypedefBlock(
1546     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1547   if (Cursor.EnterSubBlock(TYPEDEF_BLOCK_ID))
1548     return true;
1549 
1550   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1551   if (!MaybeNext) {
1552     // FIXME this drops the error on the floor.
1553     consumeError(MaybeNext.takeError());
1554     return false;
1555   }
1556   llvm::BitstreamEntry Next = MaybeNext.get();
1557   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1558     if (Next.Kind == llvm::BitstreamEntry::Error)
1559       return true;
1560 
1561     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1562       // Unknown sub-block, possibly for use by a future version of the
1563       // API notes format.
1564       if (Cursor.SkipBlock())
1565         return true;
1566 
1567       MaybeNext = Cursor.advance();
1568       if (!MaybeNext) {
1569         // FIXME this drops the error on the floor.
1570         consumeError(MaybeNext.takeError());
1571         return false;
1572       }
1573       Next = MaybeNext.get();
1574       continue;
1575     }
1576 
1577     Scratch.clear();
1578     llvm::StringRef BlobData;
1579     llvm::Expected<unsigned> MaybeKind =
1580         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1581     if (!MaybeKind) {
1582       // FIXME this drops the error on the floor.
1583       consumeError(MaybeKind.takeError());
1584       return false;
1585     }
1586     unsigned Kind = MaybeKind.get();
1587     switch (Kind) {
1588     case typedef_block::TYPEDEF_DATA: {
1589       // Already saw typedef table.
1590       if (TypedefTable)
1591         return true;
1592 
1593       uint32_t tableOffset;
1594       typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);
1595       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1596 
1597       TypedefTable.reset(SerializedTypedefTable::Create(
1598           base + tableOffset, base + sizeof(uint32_t), base));
1599       break;
1600     }
1601 
1602     default:
1603       // Unknown record, possibly for use by a future version of the
1604       // module format.
1605       break;
1606     }
1607 
1608     MaybeNext = Cursor.advance();
1609     if (!MaybeNext) {
1610       // FIXME this drops the error on the floor.
1611       consumeError(MaybeNext.takeError());
1612       return false;
1613     }
1614     Next = MaybeNext.get();
1615   }
1616 
1617   return false;
1618 }
1619 
1620 APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1621                                llvm::VersionTuple SwiftVersion, bool &Failed)
1622     : Implementation(new class Implementation) {
1623   Failed = false;
1624 
1625   // Initialize the input buffer.
1626   Implementation->InputBuffer = InputBuffer;
1627   Implementation->SwiftVersion = SwiftVersion;
1628   llvm::BitstreamCursor Cursor(*Implementation->InputBuffer);
1629 
1630   // Validate signature.
1631   for (auto byte : API_NOTES_SIGNATURE) {
1632     if (Cursor.AtEndOfStream()) {
1633       Failed = true;
1634       return;
1635     }
1636     if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead =
1637             Cursor.Read(8)) {
1638       if (maybeRead.get() != byte) {
1639         Failed = true;
1640         return;
1641       }
1642     } else {
1643       // FIXME this drops the error on the floor.
1644       consumeError(maybeRead.takeError());
1645       Failed = true;
1646       return;
1647     }
1648   }
1649 
1650   // Look at all of the blocks.
1651   bool HasValidControlBlock = false;
1652   llvm::SmallVector<uint64_t, 64> Scratch;
1653   while (!Cursor.AtEndOfStream()) {
1654     llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry = Cursor.advance();
1655     if (!MaybeTopLevelEntry) {
1656       // FIXME this drops the error on the floor.
1657       consumeError(MaybeTopLevelEntry.takeError());
1658       Failed = true;
1659       return;
1660     }
1661     llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
1662 
1663     if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
1664       break;
1665 
1666     switch (TopLevelEntry.ID) {
1667     case llvm::bitc::BLOCKINFO_BLOCK_ID:
1668       if (!Cursor.ReadBlockInfoBlock()) {
1669         Failed = true;
1670         break;
1671       }
1672       break;
1673 
1674     case CONTROL_BLOCK_ID:
1675       // Only allow a single control block.
1676       if (HasValidControlBlock ||
1677           Implementation->readControlBlock(Cursor, Scratch)) {
1678         Failed = true;
1679         return;
1680       }
1681 
1682       HasValidControlBlock = true;
1683       break;
1684 
1685     case IDENTIFIER_BLOCK_ID:
1686       if (!HasValidControlBlock ||
1687           Implementation->readIdentifierBlock(Cursor, Scratch)) {
1688         Failed = true;
1689         return;
1690       }
1691       break;
1692 
1693     case OBJC_CONTEXT_BLOCK_ID:
1694       if (!HasValidControlBlock ||
1695           Implementation->readObjCContextBlock(Cursor, Scratch)) {
1696         Failed = true;
1697         return;
1698       }
1699 
1700       break;
1701 
1702     case OBJC_PROPERTY_BLOCK_ID:
1703       if (!HasValidControlBlock ||
1704           Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
1705         Failed = true;
1706         return;
1707       }
1708       break;
1709 
1710     case OBJC_METHOD_BLOCK_ID:
1711       if (!HasValidControlBlock ||
1712           Implementation->readObjCMethodBlock(Cursor, Scratch)) {
1713         Failed = true;
1714         return;
1715       }
1716       break;
1717 
1718     case OBJC_SELECTOR_BLOCK_ID:
1719       if (!HasValidControlBlock ||
1720           Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
1721         Failed = true;
1722         return;
1723       }
1724       break;
1725 
1726     case GLOBAL_VARIABLE_BLOCK_ID:
1727       if (!HasValidControlBlock ||
1728           Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
1729         Failed = true;
1730         return;
1731       }
1732       break;
1733 
1734     case GLOBAL_FUNCTION_BLOCK_ID:
1735       if (!HasValidControlBlock ||
1736           Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
1737         Failed = true;
1738         return;
1739       }
1740       break;
1741 
1742     case ENUM_CONSTANT_BLOCK_ID:
1743       if (!HasValidControlBlock ||
1744           Implementation->readEnumConstantBlock(Cursor, Scratch)) {
1745         Failed = true;
1746         return;
1747       }
1748       break;
1749 
1750     case TAG_BLOCK_ID:
1751       if (!HasValidControlBlock ||
1752           Implementation->readTagBlock(Cursor, Scratch)) {
1753         Failed = true;
1754         return;
1755       }
1756       break;
1757 
1758     case TYPEDEF_BLOCK_ID:
1759       if (!HasValidControlBlock ||
1760           Implementation->readTypedefBlock(Cursor, Scratch)) {
1761         Failed = true;
1762         return;
1763       }
1764       break;
1765 
1766     default:
1767       // Unknown top-level block, possibly for use by a future version of the
1768       // module format.
1769       if (Cursor.SkipBlock()) {
1770         Failed = true;
1771         return;
1772       }
1773       break;
1774     }
1775   }
1776 
1777   if (!Cursor.AtEndOfStream()) {
1778     Failed = true;
1779     return;
1780   }
1781 }
1782 
1783 APINotesReader::~APINotesReader() { delete Implementation->InputBuffer; }
1784 
1785 std::unique_ptr<APINotesReader>
1786 APINotesReader::Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
1787                        llvm::VersionTuple SwiftVersion) {
1788   bool Failed = false;
1789   std::unique_ptr<APINotesReader> Reader(
1790       new APINotesReader(InputBuffer.release(), SwiftVersion, Failed));
1791   if (Failed)
1792     return nullptr;
1793 
1794   return Reader;
1795 }
1796 
1797 template <typename T>
1798 APINotesReader::VersionedInfo<T>::VersionedInfo(
1799     llvm::VersionTuple Version,
1800     llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results)
1801     : Results(std::move(Results)) {
1802 
1803   assert(!Results.empty());
1804   assert(std::is_sorted(
1805       Results.begin(), Results.end(),
1806       [](const std::pair<llvm::VersionTuple, T> &left,
1807          const std::pair<llvm::VersionTuple, T> &right) -> bool {
1808         assert(left.first != right.first && "two entries for the same version");
1809         return left.first < right.first;
1810       }));
1811 
1812   Selected = std::nullopt;
1813   for (unsigned i = 0, n = Results.size(); i != n; ++i) {
1814     if (!Version.empty() && Results[i].first >= Version) {
1815       // If the current version is "4", then entries for 4 are better than
1816       // entries for 5, but both are valid. Because entries are sorted, we get
1817       // that behavior by picking the first match.
1818       Selected = i;
1819       break;
1820     }
1821   }
1822 
1823   // If we didn't find a match but we have an unversioned result, use the
1824   // unversioned result. This will always be the first entry because we encode
1825   // it as version 0.
1826   if (!Selected && Results[0].first.empty())
1827     Selected = 0;
1828 }
1829 
1830 auto APINotesReader::lookupObjCClassID(llvm::StringRef Name)
1831     -> std::optional<ContextID> {
1832   if (!Implementation->ObjCContextIDTable)
1833     return std::nullopt;
1834 
1835   std::optional<IdentifierID> ClassID = Implementation->getIdentifier(Name);
1836   if (!ClassID)
1837     return std::nullopt;
1838 
1839   // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
1840   // context.
1841   auto KnownID = Implementation->ObjCContextIDTable->find(
1842       ContextTableKey(-1, (uint8_t)ContextKind::ObjCClass, *ClassID));
1843   if (KnownID == Implementation->ObjCContextIDTable->end())
1844     return std::nullopt;
1845 
1846   return ContextID(*KnownID);
1847 }
1848 
1849 auto APINotesReader::lookupObjCClassInfo(llvm::StringRef Name)
1850     -> VersionedInfo<ObjCContextInfo> {
1851   if (!Implementation->ObjCContextInfoTable)
1852     return std::nullopt;
1853 
1854   std::optional<ContextID> CtxID = lookupObjCClassID(Name);
1855   if (!CtxID)
1856     return std::nullopt;
1857 
1858   auto KnownInfo = Implementation->ObjCContextInfoTable->find(CtxID->Value);
1859   if (KnownInfo == Implementation->ObjCContextInfoTable->end())
1860     return std::nullopt;
1861 
1862   return {Implementation->SwiftVersion, *KnownInfo};
1863 }
1864 
1865 auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name)
1866     -> std::optional<ContextID> {
1867   if (!Implementation->ObjCContextIDTable)
1868     return std::nullopt;
1869 
1870   std::optional<IdentifierID> classID = Implementation->getIdentifier(Name);
1871   if (!classID)
1872     return std::nullopt;
1873 
1874   // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
1875   // context.
1876   auto KnownID = Implementation->ObjCContextIDTable->find(
1877       ContextTableKey(-1, (uint8_t)ContextKind::ObjCProtocol, *classID));
1878   if (KnownID == Implementation->ObjCContextIDTable->end())
1879     return std::nullopt;
1880 
1881   return ContextID(*KnownID);
1882 }
1883 
1884 auto APINotesReader::lookupObjCProtocolInfo(llvm::StringRef Name)
1885     -> VersionedInfo<ObjCContextInfo> {
1886   if (!Implementation->ObjCContextInfoTable)
1887     return std::nullopt;
1888 
1889   std::optional<ContextID> CtxID = lookupObjCProtocolID(Name);
1890   if (!CtxID)
1891     return std::nullopt;
1892 
1893   auto KnownInfo = Implementation->ObjCContextInfoTable->find(CtxID->Value);
1894   if (KnownInfo == Implementation->ObjCContextInfoTable->end())
1895     return std::nullopt;
1896 
1897   return {Implementation->SwiftVersion, *KnownInfo};
1898 }
1899 
1900 auto APINotesReader::lookupObjCProperty(ContextID CtxID, llvm::StringRef Name,
1901                                         bool IsInstance)
1902     -> VersionedInfo<ObjCPropertyInfo> {
1903   if (!Implementation->ObjCPropertyTable)
1904     return std::nullopt;
1905 
1906   std::optional<IdentifierID> PropertyID = Implementation->getIdentifier(Name);
1907   if (!PropertyID)
1908     return std::nullopt;
1909 
1910   auto Known = Implementation->ObjCPropertyTable->find(
1911       std::make_tuple(CtxID.Value, *PropertyID, (char)IsInstance));
1912   if (Known == Implementation->ObjCPropertyTable->end())
1913     return std::nullopt;
1914 
1915   return {Implementation->SwiftVersion, *Known};
1916 }
1917 
1918 auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
1919                                       bool IsInstanceMethod)
1920     -> VersionedInfo<ObjCMethodInfo> {
1921   if (!Implementation->ObjCMethodTable)
1922     return std::nullopt;
1923 
1924   std::optional<SelectorID> SelID = Implementation->getSelector(Selector);
1925   if (!SelID)
1926     return std::nullopt;
1927 
1928   auto Known = Implementation->ObjCMethodTable->find(
1929       ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
1930                                              IsInstanceMethod});
1931   if (Known == Implementation->ObjCMethodTable->end())
1932     return std::nullopt;
1933 
1934   return {Implementation->SwiftVersion, *Known};
1935 }
1936 
1937 auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name,
1938                                           std::optional<Context> Ctx)
1939     -> VersionedInfo<GlobalVariableInfo> {
1940   if (!Implementation->GlobalVariableTable)
1941     return std::nullopt;
1942 
1943   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
1944   if (!NameID)
1945     return std::nullopt;
1946 
1947   ContextTableKey Key(Ctx, *NameID);
1948 
1949   auto Known = Implementation->GlobalVariableTable->find(Key);
1950   if (Known == Implementation->GlobalVariableTable->end())
1951     return std::nullopt;
1952 
1953   return {Implementation->SwiftVersion, *Known};
1954 }
1955 
1956 auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name,
1957                                           std::optional<Context> Ctx)
1958     -> VersionedInfo<GlobalFunctionInfo> {
1959   if (!Implementation->GlobalFunctionTable)
1960     return std::nullopt;
1961 
1962   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
1963   if (!NameID)
1964     return std::nullopt;
1965 
1966   ContextTableKey Key(Ctx, *NameID);
1967 
1968   auto Known = Implementation->GlobalFunctionTable->find(Key);
1969   if (Known == Implementation->GlobalFunctionTable->end())
1970     return std::nullopt;
1971 
1972   return {Implementation->SwiftVersion, *Known};
1973 }
1974 
1975 auto APINotesReader::lookupEnumConstant(llvm::StringRef Name)
1976     -> VersionedInfo<EnumConstantInfo> {
1977   if (!Implementation->EnumConstantTable)
1978     return std::nullopt;
1979 
1980   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
1981   if (!NameID)
1982     return std::nullopt;
1983 
1984   auto Known = Implementation->EnumConstantTable->find(*NameID);
1985   if (Known == Implementation->EnumConstantTable->end())
1986     return std::nullopt;
1987 
1988   return {Implementation->SwiftVersion, *Known};
1989 }
1990 
1991 auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional<Context> Ctx)
1992     -> VersionedInfo<TagInfo> {
1993   if (!Implementation->TagTable)
1994     return std::nullopt;
1995 
1996   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
1997   if (!NameID)
1998     return std::nullopt;
1999 
2000   ContextTableKey Key(Ctx, *NameID);
2001 
2002   auto Known = Implementation->TagTable->find(Key);
2003   if (Known == Implementation->TagTable->end())
2004     return std::nullopt;
2005 
2006   return {Implementation->SwiftVersion, *Known};
2007 }
2008 
2009 auto APINotesReader::lookupTypedef(llvm::StringRef Name,
2010                                    std::optional<Context> Ctx)
2011     -> VersionedInfo<TypedefInfo> {
2012   if (!Implementation->TypedefTable)
2013     return std::nullopt;
2014 
2015   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2016   if (!NameID)
2017     return std::nullopt;
2018 
2019   ContextTableKey Key(Ctx, *NameID);
2020 
2021   auto Known = Implementation->TypedefTable->find(Key);
2022   if (Known == Implementation->TypedefTable->end())
2023     return std::nullopt;
2024 
2025   return {Implementation->SwiftVersion, *Known};
2026 }
2027 
2028 auto APINotesReader::lookupNamespaceID(
2029     llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2030     -> std::optional<ContextID> {
2031   if (!Implementation->ObjCContextIDTable)
2032     return std::nullopt;
2033 
2034   std::optional<IdentifierID> NamespaceID = Implementation->getIdentifier(Name);
2035   if (!NamespaceID)
2036     return std::nullopt;
2037 
2038   uint32_t RawParentNamespaceID =
2039       ParentNamespaceID ? ParentNamespaceID->Value : -1;
2040   auto KnownID = Implementation->ObjCContextIDTable->find(
2041       {RawParentNamespaceID, (uint8_t)ContextKind::Namespace, *NamespaceID});
2042   if (KnownID == Implementation->ObjCContextIDTable->end())
2043     return std::nullopt;
2044 
2045   return ContextID(*KnownID);
2046 }
2047 
2048 } // namespace api_notes
2049 } // namespace clang
2050