xref: /llvm-project/clang/lib/APINotes/APINotesReader.cpp (revision 26f5d1ee9c37e2a6d50898a5bf2d3b9171060ba0)
1bb352b6eSEgor Zhdan //===--- APINotesReader.cpp - API Notes Reader ------------------*- C++ -*-===//
2bb352b6eSEgor Zhdan //
3bb352b6eSEgor Zhdan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bb352b6eSEgor Zhdan // See https://llvm.org/LICENSE.txt for license information.
5bb352b6eSEgor Zhdan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bb352b6eSEgor Zhdan //
7bb352b6eSEgor Zhdan //===----------------------------------------------------------------------===//
8864593b9SJan Svoboda //
9864593b9SJan Svoboda // This file implements the \c APINotesReader class that reads source
10864593b9SJan Svoboda // API notes data providing additional information about source code as
11864593b9SJan Svoboda // a separate input, such as the non-nil/nilable annotations for
12864593b9SJan Svoboda // method parameters.
13864593b9SJan Svoboda //
14864593b9SJan Svoboda //===----------------------------------------------------------------------===//
15bb352b6eSEgor Zhdan #include "clang/APINotes/APINotesReader.h"
16bb352b6eSEgor Zhdan #include "APINotesFormat.h"
175f4e3a3cSGábor Horváth #include "clang/APINotes/Types.h"
18bb352b6eSEgor Zhdan #include "llvm/ADT/Hashing.h"
19bb352b6eSEgor Zhdan #include "llvm/ADT/StringExtras.h"
20bb352b6eSEgor Zhdan #include "llvm/Bitstream/BitstreamReader.h"
21bb352b6eSEgor Zhdan #include "llvm/Support/DJB.h"
22bb352b6eSEgor Zhdan #include "llvm/Support/EndianStream.h"
23bb352b6eSEgor Zhdan #include "llvm/Support/OnDiskHashTable.h"
24bb352b6eSEgor Zhdan 
25bb352b6eSEgor Zhdan namespace clang {
26bb352b6eSEgor Zhdan namespace api_notes {
27bb352b6eSEgor Zhdan using namespace llvm::support;
28bb352b6eSEgor Zhdan 
29bb352b6eSEgor Zhdan namespace {
30bb352b6eSEgor Zhdan /// Deserialize a version tuple.
31bb352b6eSEgor Zhdan llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) {
32bb352b6eSEgor Zhdan   uint8_t NumVersions = (*Data++) & 0x03;
33bb352b6eSEgor Zhdan 
3489071f35SKazu Hirata   unsigned Major = endian::readNext<uint32_t, llvm::endianness::little>(Data);
35bb352b6eSEgor Zhdan   if (NumVersions == 0)
36bb352b6eSEgor Zhdan     return llvm::VersionTuple(Major);
37bb352b6eSEgor Zhdan 
3889071f35SKazu Hirata   unsigned Minor = endian::readNext<uint32_t, llvm::endianness::little>(Data);
39bb352b6eSEgor Zhdan   if (NumVersions == 1)
40bb352b6eSEgor Zhdan     return llvm::VersionTuple(Major, Minor);
41bb352b6eSEgor Zhdan 
42bb352b6eSEgor Zhdan   unsigned Subminor =
4389071f35SKazu Hirata       endian::readNext<uint32_t, llvm::endianness::little>(Data);
44bb352b6eSEgor Zhdan   if (NumVersions == 2)
45bb352b6eSEgor Zhdan     return llvm::VersionTuple(Major, Minor, Subminor);
46bb352b6eSEgor Zhdan 
4789071f35SKazu Hirata   unsigned Build = endian::readNext<uint32_t, llvm::endianness::little>(Data);
48bb352b6eSEgor Zhdan   return llvm::VersionTuple(Major, Minor, Subminor, Build);
49bb352b6eSEgor Zhdan }
50bb352b6eSEgor Zhdan 
51bb352b6eSEgor Zhdan /// An on-disk hash table whose data is versioned based on the Swift version.
52bb352b6eSEgor Zhdan template <typename Derived, typename KeyType, typename UnversionedDataType>
53bb352b6eSEgor Zhdan class VersionedTableInfo {
54bb352b6eSEgor Zhdan public:
55bb352b6eSEgor Zhdan   using internal_key_type = KeyType;
56bb352b6eSEgor Zhdan   using external_key_type = KeyType;
57bb352b6eSEgor Zhdan   using data_type =
58bb352b6eSEgor Zhdan       llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
59bb352b6eSEgor Zhdan   using hash_value_type = size_t;
60bb352b6eSEgor Zhdan   using offset_type = unsigned;
61bb352b6eSEgor Zhdan 
62bb352b6eSEgor Zhdan   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
63bb352b6eSEgor Zhdan 
64bb352b6eSEgor Zhdan   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
65bb352b6eSEgor Zhdan 
66bb352b6eSEgor Zhdan   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
67bb352b6eSEgor Zhdan     return LHS == RHS;
68bb352b6eSEgor Zhdan   }
69bb352b6eSEgor Zhdan 
70bb352b6eSEgor Zhdan   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
71bb352b6eSEgor Zhdan     unsigned KeyLength =
7289071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
73bb352b6eSEgor Zhdan     unsigned DataLength =
7489071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
75bb352b6eSEgor Zhdan     return {KeyLength, DataLength};
76bb352b6eSEgor Zhdan   }
77bb352b6eSEgor Zhdan 
78bb352b6eSEgor Zhdan   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
79bb352b6eSEgor Zhdan                             unsigned Length) {
80bb352b6eSEgor Zhdan     unsigned NumElements =
8189071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
82bb352b6eSEgor Zhdan     data_type Result;
83bb352b6eSEgor Zhdan     Result.reserve(NumElements);
84bb352b6eSEgor Zhdan     for (unsigned i = 0; i != NumElements; ++i) {
85bb352b6eSEgor Zhdan       auto version = ReadVersionTuple(Data);
86bb352b6eSEgor Zhdan       const auto *DataBefore = Data;
87bb352b6eSEgor Zhdan       (void)DataBefore;
885e4c4365SEgor Zhdan       auto UnversionedData = Derived::readUnversioned(Key, Data);
89bb352b6eSEgor Zhdan       assert(Data != DataBefore &&
90bb352b6eSEgor Zhdan              "Unversioned data reader didn't move pointer");
91bb352b6eSEgor Zhdan       Result.push_back({version, UnversionedData});
92bb352b6eSEgor Zhdan     }
93bb352b6eSEgor Zhdan     return Result;
94bb352b6eSEgor Zhdan   }
95bb352b6eSEgor Zhdan };
96bb352b6eSEgor Zhdan 
97bb352b6eSEgor Zhdan /// Read serialized CommonEntityInfo.
98bb352b6eSEgor Zhdan void ReadCommonEntityInfo(const uint8_t *&Data, CommonEntityInfo &Info) {
99bb352b6eSEgor Zhdan   uint8_t UnavailableBits = *Data++;
100bb352b6eSEgor Zhdan   Info.Unavailable = (UnavailableBits >> 1) & 0x01;
101bb352b6eSEgor Zhdan   Info.UnavailableInSwift = UnavailableBits & 0x01;
102bb352b6eSEgor Zhdan   if ((UnavailableBits >> 2) & 0x01)
103bb352b6eSEgor Zhdan     Info.setSwiftPrivate(static_cast<bool>((UnavailableBits >> 3) & 0x01));
104bb352b6eSEgor Zhdan 
105bb352b6eSEgor Zhdan   unsigned MsgLength =
10689071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
107bb352b6eSEgor Zhdan   Info.UnavailableMsg =
108bb352b6eSEgor Zhdan       std::string(reinterpret_cast<const char *>(Data),
109bb352b6eSEgor Zhdan                   reinterpret_cast<const char *>(Data) + MsgLength);
110bb352b6eSEgor Zhdan   Data += MsgLength;
111bb352b6eSEgor Zhdan 
112bb352b6eSEgor Zhdan   unsigned SwiftNameLength =
11389071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
114bb352b6eSEgor Zhdan   Info.SwiftName =
115bb352b6eSEgor Zhdan       std::string(reinterpret_cast<const char *>(Data),
116bb352b6eSEgor Zhdan                   reinterpret_cast<const char *>(Data) + SwiftNameLength);
117bb352b6eSEgor Zhdan   Data += SwiftNameLength;
118bb352b6eSEgor Zhdan }
119bb352b6eSEgor Zhdan 
120bb352b6eSEgor Zhdan /// Read serialized CommonTypeInfo.
121bb352b6eSEgor Zhdan void ReadCommonTypeInfo(const uint8_t *&Data, CommonTypeInfo &Info) {
122bb352b6eSEgor Zhdan   ReadCommonEntityInfo(Data, Info);
123bb352b6eSEgor Zhdan 
124bb352b6eSEgor Zhdan   unsigned SwiftBridgeLength =
12589071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
126bb352b6eSEgor Zhdan   if (SwiftBridgeLength > 0) {
127bb352b6eSEgor Zhdan     Info.setSwiftBridge(std::string(reinterpret_cast<const char *>(Data),
128bb352b6eSEgor Zhdan                                     SwiftBridgeLength - 1));
129bb352b6eSEgor Zhdan     Data += SwiftBridgeLength - 1;
130bb352b6eSEgor Zhdan   }
131bb352b6eSEgor Zhdan 
132bb352b6eSEgor Zhdan   unsigned ErrorDomainLength =
13389071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
134bb352b6eSEgor Zhdan   if (ErrorDomainLength > 0) {
135bb352b6eSEgor Zhdan     Info.setNSErrorDomain(std::optional<std::string>(std::string(
136bb352b6eSEgor Zhdan         reinterpret_cast<const char *>(Data), ErrorDomainLength - 1)));
137bb352b6eSEgor Zhdan     Data += ErrorDomainLength - 1;
138bb352b6eSEgor Zhdan   }
139bb352b6eSEgor Zhdan }
140bb352b6eSEgor Zhdan 
141bb352b6eSEgor Zhdan /// Used to deserialize the on-disk identifier table.
142bb352b6eSEgor Zhdan class IdentifierTableInfo {
143bb352b6eSEgor Zhdan public:
144bb352b6eSEgor Zhdan   using internal_key_type = llvm::StringRef;
145bb352b6eSEgor Zhdan   using external_key_type = llvm::StringRef;
146bb352b6eSEgor Zhdan   using data_type = IdentifierID;
147bb352b6eSEgor Zhdan   using hash_value_type = uint32_t;
148bb352b6eSEgor Zhdan   using offset_type = unsigned;
149bb352b6eSEgor Zhdan 
150bb352b6eSEgor Zhdan   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
151bb352b6eSEgor Zhdan 
152bb352b6eSEgor Zhdan   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
153bb352b6eSEgor Zhdan 
154bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
1555e4c4365SEgor Zhdan     return llvm::djbHash(Key);
156bb352b6eSEgor Zhdan   }
157bb352b6eSEgor Zhdan 
158bb352b6eSEgor Zhdan   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
159bb352b6eSEgor Zhdan     return LHS == RHS;
160bb352b6eSEgor Zhdan   }
161bb352b6eSEgor Zhdan 
162bb352b6eSEgor Zhdan   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
163bb352b6eSEgor Zhdan     unsigned KeyLength =
16489071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
165bb352b6eSEgor Zhdan     unsigned DataLength =
16689071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
167bb352b6eSEgor Zhdan     return {KeyLength, DataLength};
168bb352b6eSEgor Zhdan   }
169bb352b6eSEgor Zhdan 
170bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
171bb352b6eSEgor Zhdan     return llvm::StringRef(reinterpret_cast<const char *>(Data), Length);
172bb352b6eSEgor Zhdan   }
173bb352b6eSEgor Zhdan 
174bb352b6eSEgor Zhdan   static data_type ReadData(internal_key_type key, const uint8_t *Data,
175bb352b6eSEgor Zhdan                             unsigned Length) {
17689071f35SKazu Hirata     return endian::readNext<uint32_t, llvm::endianness::little>(Data);
177bb352b6eSEgor Zhdan   }
178bb352b6eSEgor Zhdan };
179bb352b6eSEgor Zhdan 
18082ee7ae3SEgor Zhdan /// Used to deserialize the on-disk table of Objective-C classes and C++
18182ee7ae3SEgor Zhdan /// namespaces.
18282ee7ae3SEgor Zhdan class ContextIDTableInfo {
183bb352b6eSEgor Zhdan public:
184bb352b6eSEgor Zhdan   using internal_key_type = ContextTableKey;
185bb352b6eSEgor Zhdan   using external_key_type = internal_key_type;
186bb352b6eSEgor Zhdan   using data_type = unsigned;
187bb352b6eSEgor Zhdan   using hash_value_type = size_t;
188bb352b6eSEgor Zhdan   using offset_type = unsigned;
189bb352b6eSEgor Zhdan 
190bb352b6eSEgor Zhdan   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
191bb352b6eSEgor Zhdan 
192bb352b6eSEgor Zhdan   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
193bb352b6eSEgor Zhdan 
194bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
195bb352b6eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
196bb352b6eSEgor Zhdan   }
197bb352b6eSEgor Zhdan 
198bb352b6eSEgor Zhdan   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
199bb352b6eSEgor Zhdan     return LHS == RHS;
200bb352b6eSEgor Zhdan   }
201bb352b6eSEgor Zhdan 
202bb352b6eSEgor Zhdan   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
203bb352b6eSEgor Zhdan     unsigned KeyLength =
20489071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
205bb352b6eSEgor Zhdan     unsigned DataLength =
20689071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
207bb352b6eSEgor Zhdan     return {KeyLength, DataLength};
208bb352b6eSEgor Zhdan   }
209bb352b6eSEgor Zhdan 
210bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
211bb352b6eSEgor Zhdan     auto ParentCtxID =
21289071f35SKazu Hirata         endian::readNext<uint32_t, llvm::endianness::little>(Data);
213bb352b6eSEgor Zhdan     auto ContextKind =
21489071f35SKazu Hirata         endian::readNext<uint8_t, llvm::endianness::little>(Data);
21589071f35SKazu Hirata     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
216bb352b6eSEgor Zhdan     return {ParentCtxID, ContextKind, NameID};
217bb352b6eSEgor Zhdan   }
218bb352b6eSEgor Zhdan 
219bb352b6eSEgor Zhdan   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
220bb352b6eSEgor Zhdan                             unsigned Length) {
22189071f35SKazu Hirata     return endian::readNext<uint32_t, llvm::endianness::little>(Data);
222bb352b6eSEgor Zhdan   }
223bb352b6eSEgor Zhdan };
224bb352b6eSEgor Zhdan 
225bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C property table.
22682ee7ae3SEgor Zhdan class ContextInfoTableInfo
22782ee7ae3SEgor Zhdan     : public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
228bb352b6eSEgor Zhdan public:
229bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
23089071f35SKazu Hirata     return endian::readNext<uint32_t, llvm::endianness::little>(Data);
231bb352b6eSEgor Zhdan   }
232bb352b6eSEgor Zhdan 
233bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
234bb352b6eSEgor Zhdan     return static_cast<size_t>(llvm::hash_value(Key));
235bb352b6eSEgor Zhdan   }
236bb352b6eSEgor Zhdan 
23782ee7ae3SEgor Zhdan   static ContextInfo readUnversioned(internal_key_type Key,
238bb352b6eSEgor Zhdan                                      const uint8_t *&Data) {
23982ee7ae3SEgor Zhdan     ContextInfo Info;
240bb352b6eSEgor Zhdan     ReadCommonTypeInfo(Data, Info);
241bb352b6eSEgor Zhdan     uint8_t Payload = *Data++;
242bb352b6eSEgor Zhdan 
243bb352b6eSEgor Zhdan     if (Payload & 0x01)
244bb352b6eSEgor Zhdan       Info.setHasDesignatedInits(true);
245bb352b6eSEgor Zhdan     Payload = Payload >> 1;
246bb352b6eSEgor Zhdan 
247bb352b6eSEgor Zhdan     if (Payload & 0x4)
248bb352b6eSEgor Zhdan       Info.setDefaultNullability(static_cast<NullabilityKind>(Payload & 0x03));
249bb352b6eSEgor Zhdan     Payload >>= 3;
250bb352b6eSEgor Zhdan 
251bb352b6eSEgor Zhdan     if (Payload & (1 << 1))
252bb352b6eSEgor Zhdan       Info.setSwiftObjCMembers(Payload & 1);
253bb352b6eSEgor Zhdan     Payload >>= 2;
254bb352b6eSEgor Zhdan 
255bb352b6eSEgor Zhdan     if (Payload & (1 << 1))
256bb352b6eSEgor Zhdan       Info.setSwiftImportAsNonGeneric(Payload & 1);
257bb352b6eSEgor Zhdan 
258bb352b6eSEgor Zhdan     return Info;
259bb352b6eSEgor Zhdan   }
260bb352b6eSEgor Zhdan };
261bb352b6eSEgor Zhdan 
262bb352b6eSEgor Zhdan /// Read serialized VariableInfo.
263bb352b6eSEgor Zhdan void ReadVariableInfo(const uint8_t *&Data, VariableInfo &Info) {
264bb352b6eSEgor Zhdan   ReadCommonEntityInfo(Data, Info);
265bb352b6eSEgor Zhdan   if (*Data++) {
266bb352b6eSEgor Zhdan     Info.setNullabilityAudited(static_cast<NullabilityKind>(*Data));
267bb352b6eSEgor Zhdan   }
268bb352b6eSEgor Zhdan   ++Data;
269bb352b6eSEgor Zhdan 
27089071f35SKazu Hirata   auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(Data);
271bb352b6eSEgor Zhdan   Info.setType(std::string(Data, Data + TypeLen));
272bb352b6eSEgor Zhdan   Data += TypeLen;
273bb352b6eSEgor Zhdan }
274bb352b6eSEgor Zhdan 
275bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C property table.
276bb352b6eSEgor Zhdan class ObjCPropertyTableInfo
277bb352b6eSEgor Zhdan     : public VersionedTableInfo<ObjCPropertyTableInfo,
278bb352b6eSEgor Zhdan                                 std::tuple<uint32_t, uint32_t, uint8_t>,
279bb352b6eSEgor Zhdan                                 ObjCPropertyInfo> {
280bb352b6eSEgor Zhdan public:
281bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
28289071f35SKazu Hirata     auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
28389071f35SKazu Hirata     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
28489071f35SKazu Hirata     char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data);
285bb352b6eSEgor Zhdan     return {ClassID, NameID, IsInstance};
286bb352b6eSEgor Zhdan   }
287bb352b6eSEgor Zhdan 
288bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
289bb352b6eSEgor Zhdan     return static_cast<size_t>(llvm::hash_value(Key));
290bb352b6eSEgor Zhdan   }
291bb352b6eSEgor Zhdan 
292bb352b6eSEgor Zhdan   static ObjCPropertyInfo readUnversioned(internal_key_type Key,
293bb352b6eSEgor Zhdan                                           const uint8_t *&Data) {
294bb352b6eSEgor Zhdan     ObjCPropertyInfo Info;
295bb352b6eSEgor Zhdan     ReadVariableInfo(Data, Info);
296bb352b6eSEgor Zhdan     uint8_t Flags = *Data++;
297bb352b6eSEgor Zhdan     if (Flags & (1 << 0))
298bb352b6eSEgor Zhdan       Info.setSwiftImportAsAccessors(Flags & (1 << 1));
299bb352b6eSEgor Zhdan     return Info;
300bb352b6eSEgor Zhdan   }
301bb352b6eSEgor Zhdan };
302bb352b6eSEgor Zhdan 
303b8169771SEgor Zhdan /// Used to deserialize the on-disk C record field table.
304b8169771SEgor Zhdan class FieldTableInfo
305b8169771SEgor Zhdan     : public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
306b8169771SEgor Zhdan public:
307b8169771SEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
308b8169771SEgor Zhdan     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
309b8169771SEgor Zhdan     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
310b8169771SEgor Zhdan     return {CtxID, NameID};
311b8169771SEgor Zhdan   }
312b8169771SEgor Zhdan 
313b8169771SEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
314b8169771SEgor Zhdan     return static_cast<size_t>(Key.hashValue());
315b8169771SEgor Zhdan   }
316b8169771SEgor Zhdan 
317b8169771SEgor Zhdan   static FieldInfo readUnversioned(internal_key_type Key,
318b8169771SEgor Zhdan                                    const uint8_t *&Data) {
319b8169771SEgor Zhdan     FieldInfo Info;
320b8169771SEgor Zhdan     ReadVariableInfo(Data, Info);
321b8169771SEgor Zhdan     return Info;
322b8169771SEgor Zhdan   }
323b8169771SEgor Zhdan };
324b8169771SEgor Zhdan 
325bb352b6eSEgor Zhdan /// Read serialized ParamInfo.
326bb352b6eSEgor Zhdan void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
327bb352b6eSEgor Zhdan   ReadVariableInfo(Data, Info);
328bb352b6eSEgor Zhdan 
32989071f35SKazu Hirata   uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data);
330bb352b6eSEgor Zhdan   if (auto RawConvention = Payload & 0x7) {
331bb352b6eSEgor Zhdan     auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1);
332bb352b6eSEgor Zhdan     Info.setRetainCountConvention(Convention);
333bb352b6eSEgor Zhdan   }
334bb352b6eSEgor Zhdan   Payload >>= 3;
335bb352b6eSEgor Zhdan   if (Payload & 0x01)
3367ac78f13SGábor Horváth     Info.setLifetimebound(Payload & 0x02);
3377ac78f13SGábor Horváth   Payload >>= 2;
3387ac78f13SGábor Horváth   if (Payload & 0x01)
339bb352b6eSEgor Zhdan     Info.setNoEscape(Payload & 0x02);
340bb352b6eSEgor Zhdan   Payload >>= 2;
341bb352b6eSEgor Zhdan   assert(Payload == 0 && "Bad API notes");
342bb352b6eSEgor Zhdan }
343bb352b6eSEgor Zhdan 
344bb352b6eSEgor Zhdan /// Read serialized FunctionInfo.
345bb352b6eSEgor Zhdan void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) {
346bb352b6eSEgor Zhdan   ReadCommonEntityInfo(Data, Info);
347bb352b6eSEgor Zhdan 
34889071f35SKazu Hirata   uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data);
349bb352b6eSEgor Zhdan   if (auto RawConvention = Payload & 0x7) {
350bb352b6eSEgor Zhdan     auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1);
351bb352b6eSEgor Zhdan     Info.setRetainCountConvention(Convention);
352bb352b6eSEgor Zhdan   }
353bb352b6eSEgor Zhdan   Payload >>= 3;
354bb352b6eSEgor Zhdan   Info.NullabilityAudited = Payload & 0x1;
355bb352b6eSEgor Zhdan   Payload >>= 1;
356bb352b6eSEgor Zhdan   assert(Payload == 0 && "Bad API notes");
357bb352b6eSEgor Zhdan 
358bb352b6eSEgor Zhdan   Info.NumAdjustedNullable =
35989071f35SKazu Hirata       endian::readNext<uint8_t, llvm::endianness::little>(Data);
360bb352b6eSEgor Zhdan   Info.NullabilityPayload =
36189071f35SKazu Hirata       endian::readNext<uint64_t, llvm::endianness::little>(Data);
362bb352b6eSEgor Zhdan 
363bb352b6eSEgor Zhdan   unsigned NumParams =
36489071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
365bb352b6eSEgor Zhdan   while (NumParams > 0) {
366bb352b6eSEgor Zhdan     ParamInfo pi;
367bb352b6eSEgor Zhdan     ReadParamInfo(Data, pi);
368bb352b6eSEgor Zhdan     Info.Params.push_back(pi);
369bb352b6eSEgor Zhdan     --NumParams;
370bb352b6eSEgor Zhdan   }
371bb352b6eSEgor Zhdan 
372bb352b6eSEgor Zhdan   unsigned ResultTypeLen =
37389071f35SKazu Hirata       endian::readNext<uint16_t, llvm::endianness::little>(Data);
374bb352b6eSEgor Zhdan   Info.ResultType = std::string(Data, Data + ResultTypeLen);
375bb352b6eSEgor Zhdan   Data += ResultTypeLen;
37648f7f63aSfahadnayyar 
37748f7f63aSfahadnayyar   unsigned SwiftReturnOwnershipLength =
37848f7f63aSfahadnayyar       endian::readNext<uint16_t, llvm::endianness::little>(Data);
37948f7f63aSfahadnayyar   Info.SwiftReturnOwnership = std::string(reinterpret_cast<const char *>(Data),
38048f7f63aSfahadnayyar                                           reinterpret_cast<const char *>(Data) +
38148f7f63aSfahadnayyar                                               SwiftReturnOwnershipLength);
38248f7f63aSfahadnayyar   Data += SwiftReturnOwnershipLength;
383bb352b6eSEgor Zhdan }
384bb352b6eSEgor Zhdan 
385bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C method table.
386bb352b6eSEgor Zhdan class ObjCMethodTableInfo
387bb352b6eSEgor Zhdan     : public VersionedTableInfo<ObjCMethodTableInfo,
388bb352b6eSEgor Zhdan                                 std::tuple<uint32_t, uint32_t, uint8_t>,
389bb352b6eSEgor Zhdan                                 ObjCMethodInfo> {
390bb352b6eSEgor Zhdan public:
391bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
39289071f35SKazu Hirata     auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
393bb352b6eSEgor Zhdan     auto SelectorID =
39489071f35SKazu Hirata         endian::readNext<uint32_t, llvm::endianness::little>(Data);
39589071f35SKazu Hirata     auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data);
396bb352b6eSEgor Zhdan     return {ClassID, SelectorID, IsInstance};
397bb352b6eSEgor Zhdan   }
398bb352b6eSEgor Zhdan 
399bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
400bb352b6eSEgor Zhdan     return static_cast<size_t>(llvm::hash_value(Key));
401bb352b6eSEgor Zhdan   }
402bb352b6eSEgor Zhdan 
403bb352b6eSEgor Zhdan   static ObjCMethodInfo readUnversioned(internal_key_type Key,
404bb352b6eSEgor Zhdan                                         const uint8_t *&Data) {
405bb352b6eSEgor Zhdan     ObjCMethodInfo Info;
406bb352b6eSEgor Zhdan     uint8_t Payload = *Data++;
4075f4e3a3cSGábor Horváth     bool HasSelf = Payload & 0x01;
4085f4e3a3cSGábor Horváth     Payload >>= 1;
409bb352b6eSEgor Zhdan     Info.RequiredInit = Payload & 0x01;
410bb352b6eSEgor Zhdan     Payload >>= 1;
411bb352b6eSEgor Zhdan     Info.DesignatedInit = Payload & 0x01;
412bb352b6eSEgor Zhdan     Payload >>= 1;
4135f4e3a3cSGábor Horváth     assert(Payload == 0 && "Unable to fully decode 'Payload'.");
414bb352b6eSEgor Zhdan 
415bb352b6eSEgor Zhdan     ReadFunctionInfo(Data, Info);
4165f4e3a3cSGábor Horváth     if (HasSelf) {
4175f4e3a3cSGábor Horváth       Info.Self = ParamInfo{};
4185f4e3a3cSGábor Horváth       ReadParamInfo(Data, *Info.Self);
4195f4e3a3cSGábor Horváth     }
420bb352b6eSEgor Zhdan     return Info;
421bb352b6eSEgor Zhdan   }
422bb352b6eSEgor Zhdan };
423bb352b6eSEgor Zhdan 
424bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C selector table.
425bb352b6eSEgor Zhdan class ObjCSelectorTableInfo {
426bb352b6eSEgor Zhdan public:
427bb352b6eSEgor Zhdan   using internal_key_type = StoredObjCSelector;
428bb352b6eSEgor Zhdan   using external_key_type = internal_key_type;
429bb352b6eSEgor Zhdan   using data_type = SelectorID;
430bb352b6eSEgor Zhdan   using hash_value_type = unsigned;
431bb352b6eSEgor Zhdan   using offset_type = unsigned;
432bb352b6eSEgor Zhdan 
433bb352b6eSEgor Zhdan   internal_key_type GetInternalKey(external_key_type Key) { return Key; }
434bb352b6eSEgor Zhdan 
435bb352b6eSEgor Zhdan   external_key_type GetExternalKey(internal_key_type Key) { return Key; }
436bb352b6eSEgor Zhdan 
437bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
438bb352b6eSEgor Zhdan     return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
439bb352b6eSEgor Zhdan   }
440bb352b6eSEgor Zhdan 
441bb352b6eSEgor Zhdan   static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
442bb352b6eSEgor Zhdan     return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS);
443bb352b6eSEgor Zhdan   }
444bb352b6eSEgor Zhdan 
445bb352b6eSEgor Zhdan   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) {
446bb352b6eSEgor Zhdan     unsigned KeyLength =
44789071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
448bb352b6eSEgor Zhdan     unsigned DataLength =
44989071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
450bb352b6eSEgor Zhdan     return {KeyLength, DataLength};
451bb352b6eSEgor Zhdan   }
452bb352b6eSEgor Zhdan 
453bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
454bb352b6eSEgor Zhdan     internal_key_type Key;
45589071f35SKazu Hirata     Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(Data);
456bb352b6eSEgor Zhdan     unsigned NumIdents = (Length - sizeof(uint16_t)) / sizeof(uint32_t);
457bb352b6eSEgor Zhdan     for (unsigned i = 0; i != NumIdents; ++i) {
458bb352b6eSEgor Zhdan       Key.Identifiers.push_back(
45989071f35SKazu Hirata           endian::readNext<uint32_t, llvm::endianness::little>(Data));
460bb352b6eSEgor Zhdan     }
461bb352b6eSEgor Zhdan     return Key;
462bb352b6eSEgor Zhdan   }
463bb352b6eSEgor Zhdan 
464bb352b6eSEgor Zhdan   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
465bb352b6eSEgor Zhdan                             unsigned Length) {
46689071f35SKazu Hirata     return endian::readNext<uint32_t, llvm::endianness::little>(Data);
467bb352b6eSEgor Zhdan   }
468bb352b6eSEgor Zhdan };
469bb352b6eSEgor Zhdan 
470bb352b6eSEgor Zhdan /// Used to deserialize the on-disk global variable table.
471bb352b6eSEgor Zhdan class GlobalVariableTableInfo
472c5f402f9SEgor Zhdan     : public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
473bb352b6eSEgor Zhdan                                 GlobalVariableInfo> {
474bb352b6eSEgor Zhdan public:
475bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
47689071f35SKazu Hirata     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
47789071f35SKazu Hirata     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
478c5f402f9SEgor Zhdan     return {CtxID, NameID};
479bb352b6eSEgor Zhdan   }
480bb352b6eSEgor Zhdan 
481bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
482bb352b6eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
483bb352b6eSEgor Zhdan   }
484bb352b6eSEgor Zhdan 
485bb352b6eSEgor Zhdan   static GlobalVariableInfo readUnversioned(internal_key_type Key,
486bb352b6eSEgor Zhdan                                             const uint8_t *&Data) {
487bb352b6eSEgor Zhdan     GlobalVariableInfo Info;
488bb352b6eSEgor Zhdan     ReadVariableInfo(Data, Info);
489bb352b6eSEgor Zhdan     return Info;
490bb352b6eSEgor Zhdan   }
491bb352b6eSEgor Zhdan };
492bb352b6eSEgor Zhdan 
493bb352b6eSEgor Zhdan /// Used to deserialize the on-disk global function table.
494bb352b6eSEgor Zhdan class GlobalFunctionTableInfo
495c5f402f9SEgor Zhdan     : public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
496bb352b6eSEgor Zhdan                                 GlobalFunctionInfo> {
497bb352b6eSEgor Zhdan public:
498bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
49989071f35SKazu Hirata     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
50089071f35SKazu Hirata     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
501c5f402f9SEgor Zhdan     return {CtxID, NameID};
502bb352b6eSEgor Zhdan   }
503bb352b6eSEgor Zhdan 
504bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
505bb352b6eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
506bb352b6eSEgor Zhdan   }
507bb352b6eSEgor Zhdan 
508bb352b6eSEgor Zhdan   static GlobalFunctionInfo readUnversioned(internal_key_type Key,
509bb352b6eSEgor Zhdan                                             const uint8_t *&Data) {
510bb352b6eSEgor Zhdan     GlobalFunctionInfo Info;
511bb352b6eSEgor Zhdan     ReadFunctionInfo(Data, Info);
512bb352b6eSEgor Zhdan     return Info;
513bb352b6eSEgor Zhdan   }
514bb352b6eSEgor Zhdan };
515bb352b6eSEgor Zhdan 
5168a79dc7eSEgor Zhdan /// Used to deserialize the on-disk C++ method table.
5178a79dc7eSEgor Zhdan class CXXMethodTableInfo
5188a79dc7eSEgor Zhdan     : public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey,
5198a79dc7eSEgor Zhdan                                 CXXMethodInfo> {
5208a79dc7eSEgor Zhdan public:
5218a79dc7eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
5228a79dc7eSEgor Zhdan     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
5238a79dc7eSEgor Zhdan     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
5248a79dc7eSEgor Zhdan     return {CtxID, NameID};
5258a79dc7eSEgor Zhdan   }
5268a79dc7eSEgor Zhdan 
5278a79dc7eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
5288a79dc7eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
5298a79dc7eSEgor Zhdan   }
5308a79dc7eSEgor Zhdan 
5318a79dc7eSEgor Zhdan   static CXXMethodInfo readUnversioned(internal_key_type Key,
5328a79dc7eSEgor Zhdan                                        const uint8_t *&Data) {
5338a79dc7eSEgor Zhdan     CXXMethodInfo Info;
5345f4e3a3cSGábor Horváth 
5355f4e3a3cSGábor Horváth     uint8_t Payload = *Data++;
5365f4e3a3cSGábor Horváth     bool HasThis = Payload & 0x01;
5375f4e3a3cSGábor Horváth     Payload >>= 1;
5385f4e3a3cSGábor Horváth     assert(Payload == 0 && "Unable to fully decode 'Payload'.");
5395f4e3a3cSGábor Horváth 
5408a79dc7eSEgor Zhdan     ReadFunctionInfo(Data, Info);
5415f4e3a3cSGábor Horváth     if (HasThis) {
5425f4e3a3cSGábor Horváth       Info.This = ParamInfo{};
5435f4e3a3cSGábor Horváth       ReadParamInfo(Data, *Info.This);
5445f4e3a3cSGábor Horváth     }
5458a79dc7eSEgor Zhdan     return Info;
5468a79dc7eSEgor Zhdan   }
5478a79dc7eSEgor Zhdan };
5488a79dc7eSEgor Zhdan 
549bb352b6eSEgor Zhdan /// Used to deserialize the on-disk enumerator table.
550bb352b6eSEgor Zhdan class EnumConstantTableInfo
551bb352b6eSEgor Zhdan     : public VersionedTableInfo<EnumConstantTableInfo, uint32_t,
552bb352b6eSEgor Zhdan                                 EnumConstantInfo> {
553bb352b6eSEgor Zhdan public:
554bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
55589071f35SKazu Hirata     auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
556bb352b6eSEgor Zhdan     return NameID;
557bb352b6eSEgor Zhdan   }
558bb352b6eSEgor Zhdan 
559bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
560bb352b6eSEgor Zhdan     return static_cast<size_t>(llvm::hash_value(Key));
561bb352b6eSEgor Zhdan   }
562bb352b6eSEgor Zhdan 
563bb352b6eSEgor Zhdan   static EnumConstantInfo readUnversioned(internal_key_type Key,
564bb352b6eSEgor Zhdan                                           const uint8_t *&Data) {
565bb352b6eSEgor Zhdan     EnumConstantInfo Info;
566bb352b6eSEgor Zhdan     ReadCommonEntityInfo(Data, Info);
567bb352b6eSEgor Zhdan     return Info;
568bb352b6eSEgor Zhdan   }
569bb352b6eSEgor Zhdan };
570bb352b6eSEgor Zhdan 
571bb352b6eSEgor Zhdan /// Used to deserialize the on-disk tag table.
572bb352b6eSEgor Zhdan class TagTableInfo
573c5f402f9SEgor Zhdan     : public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {
574bb352b6eSEgor Zhdan public:
575bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
57689071f35SKazu Hirata     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
577bb352b6eSEgor Zhdan     auto NameID =
57889071f35SKazu Hirata         endian::readNext<IdentifierID, llvm::endianness::little>(Data);
579c5f402f9SEgor Zhdan     return {CtxID, NameID};
580bb352b6eSEgor Zhdan   }
581bb352b6eSEgor Zhdan 
582bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
583bb352b6eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
584bb352b6eSEgor Zhdan   }
585bb352b6eSEgor Zhdan 
586bb352b6eSEgor Zhdan   static TagInfo readUnversioned(internal_key_type Key, const uint8_t *&Data) {
587bb352b6eSEgor Zhdan     TagInfo Info;
588bb352b6eSEgor Zhdan 
589bb352b6eSEgor Zhdan     uint8_t Payload = *Data++;
590bb352b6eSEgor Zhdan     if (Payload & 1)
591bb352b6eSEgor Zhdan       Info.setFlagEnum(Payload & 2);
592bb352b6eSEgor Zhdan     Payload >>= 2;
593bb352b6eSEgor Zhdan     if (Payload > 0)
594bb352b6eSEgor Zhdan       Info.EnumExtensibility =
595bb352b6eSEgor Zhdan           static_cast<EnumExtensibilityKind>((Payload & 0x3) - 1);
596bb352b6eSEgor Zhdan 
597b2098db2SEgor Zhdan     uint8_t Copyable =
598b2098db2SEgor Zhdan         endian::readNext<uint8_t, llvm::endianness::little>(Data);
599d2db9bd7SGábor Horváth     if (Copyable == kSwiftConforms || Copyable == kSwiftDoesNotConform)
600d2db9bd7SGábor Horváth       Info.setSwiftCopyable(std::optional(Copyable == kSwiftConforms));
601d2db9bd7SGábor Horváth     uint8_t Escapable =
602d2db9bd7SGábor Horváth         endian::readNext<uint8_t, llvm::endianness::little>(Data);
603d2db9bd7SGábor Horváth     if (Escapable == kSwiftConforms || Escapable == kSwiftDoesNotConform)
604d2db9bd7SGábor Horváth       Info.setSwiftEscapable(std::optional(Escapable == kSwiftConforms));
605b2098db2SEgor Zhdan 
606bb352b6eSEgor Zhdan     unsigned ImportAsLength =
60789071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
608bb352b6eSEgor Zhdan     if (ImportAsLength > 0) {
609bb352b6eSEgor Zhdan       Info.SwiftImportAs =
610bb352b6eSEgor Zhdan           std::string(reinterpret_cast<const char *>(Data), ImportAsLength - 1);
611bb352b6eSEgor Zhdan       Data += ImportAsLength - 1;
612bb352b6eSEgor Zhdan     }
613bb352b6eSEgor Zhdan     unsigned RetainOpLength =
61489071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
615bb352b6eSEgor Zhdan     if (RetainOpLength > 0) {
616bb352b6eSEgor Zhdan       Info.SwiftRetainOp =
617bb352b6eSEgor Zhdan           std::string(reinterpret_cast<const char *>(Data), RetainOpLength - 1);
618bb352b6eSEgor Zhdan       Data += RetainOpLength - 1;
619bb352b6eSEgor Zhdan     }
620bb352b6eSEgor Zhdan     unsigned ReleaseOpLength =
62189071f35SKazu Hirata         endian::readNext<uint16_t, llvm::endianness::little>(Data);
622bb352b6eSEgor Zhdan     if (ReleaseOpLength > 0) {
623bb352b6eSEgor Zhdan       Info.SwiftReleaseOp = std::string(reinterpret_cast<const char *>(Data),
624bb352b6eSEgor Zhdan                                         ReleaseOpLength - 1);
625bb352b6eSEgor Zhdan       Data += ReleaseOpLength - 1;
626bb352b6eSEgor Zhdan     }
627dc8c217dSEgor Zhdan     if (unsigned ConformanceLength =
628dc8c217dSEgor Zhdan             endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
629dc8c217dSEgor Zhdan       Info.SwiftConformance = std::string(reinterpret_cast<const char *>(Data),
630dc8c217dSEgor Zhdan                                           ConformanceLength - 1);
631dc8c217dSEgor Zhdan       Data += ConformanceLength - 1;
632dc8c217dSEgor Zhdan     }
633bb352b6eSEgor Zhdan 
634bb352b6eSEgor Zhdan     ReadCommonTypeInfo(Data, Info);
635bb352b6eSEgor Zhdan     return Info;
636bb352b6eSEgor Zhdan   }
637bb352b6eSEgor Zhdan };
638bb352b6eSEgor Zhdan 
639bb352b6eSEgor Zhdan /// Used to deserialize the on-disk typedef table.
640bb352b6eSEgor Zhdan class TypedefTableInfo
641c5f402f9SEgor Zhdan     : public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,
642bb352b6eSEgor Zhdan                                 TypedefInfo> {
643bb352b6eSEgor Zhdan public:
644bb352b6eSEgor Zhdan   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
64589071f35SKazu Hirata     auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
646bb352b6eSEgor Zhdan     auto nameID =
64789071f35SKazu Hirata         endian::readNext<IdentifierID, llvm::endianness::little>(Data);
648c5f402f9SEgor Zhdan     return {CtxID, nameID};
649bb352b6eSEgor Zhdan   }
650bb352b6eSEgor Zhdan 
651bb352b6eSEgor Zhdan   hash_value_type ComputeHash(internal_key_type Key) {
652bb352b6eSEgor Zhdan     return static_cast<size_t>(Key.hashValue());
653bb352b6eSEgor Zhdan   }
654bb352b6eSEgor Zhdan 
655bb352b6eSEgor Zhdan   static TypedefInfo readUnversioned(internal_key_type Key,
656bb352b6eSEgor Zhdan                                      const uint8_t *&Data) {
657bb352b6eSEgor Zhdan     TypedefInfo Info;
658bb352b6eSEgor Zhdan 
659bb352b6eSEgor Zhdan     uint8_t Payload = *Data++;
660bb352b6eSEgor Zhdan     if (Payload > 0)
661bb352b6eSEgor Zhdan       Info.SwiftWrapper = static_cast<SwiftNewTypeKind>((Payload & 0x3) - 1);
662bb352b6eSEgor Zhdan 
663bb352b6eSEgor Zhdan     ReadCommonTypeInfo(Data, Info);
664bb352b6eSEgor Zhdan     return Info;
665bb352b6eSEgor Zhdan   }
666bb352b6eSEgor Zhdan };
667bb352b6eSEgor Zhdan } // end anonymous namespace
668bb352b6eSEgor Zhdan 
669bb352b6eSEgor Zhdan class APINotesReader::Implementation {
670bb352b6eSEgor Zhdan public:
671bb352b6eSEgor Zhdan   /// The input buffer for the API notes data.
672bb352b6eSEgor Zhdan   llvm::MemoryBuffer *InputBuffer;
673bb352b6eSEgor Zhdan 
674bb352b6eSEgor Zhdan   /// The Swift version to use for filtering.
675bb352b6eSEgor Zhdan   llvm::VersionTuple SwiftVersion;
676bb352b6eSEgor Zhdan 
677bb352b6eSEgor Zhdan   /// The name of the module that we read from the control block.
678bb352b6eSEgor Zhdan   std::string ModuleName;
679bb352b6eSEgor Zhdan 
680bb352b6eSEgor Zhdan   // The size and modification time of the source file from
681bb352b6eSEgor Zhdan   // which this API notes file was created, if known.
682bb352b6eSEgor Zhdan   std::optional<std::pair<off_t, time_t>> SourceFileSizeAndModTime;
683bb352b6eSEgor Zhdan 
684bb352b6eSEgor Zhdan   using SerializedIdentifierTable =
685bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
686bb352b6eSEgor Zhdan 
687bb352b6eSEgor Zhdan   /// The identifier table.
688bb352b6eSEgor Zhdan   std::unique_ptr<SerializedIdentifierTable> IdentifierTable;
689bb352b6eSEgor Zhdan 
69082ee7ae3SEgor Zhdan   using SerializedContextIDTable =
69182ee7ae3SEgor Zhdan       llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>;
692bb352b6eSEgor Zhdan 
69382ee7ae3SEgor Zhdan   /// The Objective-C / C++ context ID table.
69482ee7ae3SEgor Zhdan   std::unique_ptr<SerializedContextIDTable> ContextIDTable;
695bb352b6eSEgor Zhdan 
69682ee7ae3SEgor Zhdan   using SerializedContextInfoTable =
69782ee7ae3SEgor Zhdan       llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>;
698bb352b6eSEgor Zhdan 
699bb352b6eSEgor Zhdan   /// The Objective-C context info table.
70082ee7ae3SEgor Zhdan   std::unique_ptr<SerializedContextInfoTable> ContextInfoTable;
701bb352b6eSEgor Zhdan 
702bb352b6eSEgor Zhdan   using SerializedObjCPropertyTable =
703bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
704bb352b6eSEgor Zhdan 
705bb352b6eSEgor Zhdan   /// The Objective-C property table.
706bb352b6eSEgor Zhdan   std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;
707bb352b6eSEgor Zhdan 
708b8169771SEgor Zhdan   using SerializedFieldTable =
709b8169771SEgor Zhdan       llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;
710b8169771SEgor Zhdan 
711b8169771SEgor Zhdan   /// The C record field table.
712b8169771SEgor Zhdan   std::unique_ptr<SerializedFieldTable> FieldTable;
713b8169771SEgor Zhdan 
714bb352b6eSEgor Zhdan   using SerializedObjCMethodTable =
715bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
716bb352b6eSEgor Zhdan 
717bb352b6eSEgor Zhdan   /// The Objective-C method table.
718bb352b6eSEgor Zhdan   std::unique_ptr<SerializedObjCMethodTable> ObjCMethodTable;
719bb352b6eSEgor Zhdan 
7208a79dc7eSEgor Zhdan   using SerializedCXXMethodTable =
7218a79dc7eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<CXXMethodTableInfo>;
7228a79dc7eSEgor Zhdan 
7238a79dc7eSEgor Zhdan   /// The C++ method table.
7248a79dc7eSEgor Zhdan   std::unique_ptr<SerializedCXXMethodTable> CXXMethodTable;
7258a79dc7eSEgor Zhdan 
726bb352b6eSEgor Zhdan   using SerializedObjCSelectorTable =
727bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
728bb352b6eSEgor Zhdan 
729bb352b6eSEgor Zhdan   /// The Objective-C selector table.
730bb352b6eSEgor Zhdan   std::unique_ptr<SerializedObjCSelectorTable> ObjCSelectorTable;
731bb352b6eSEgor Zhdan 
732bb352b6eSEgor Zhdan   using SerializedGlobalVariableTable =
733bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
734bb352b6eSEgor Zhdan 
735bb352b6eSEgor Zhdan   /// The global variable table.
736bb352b6eSEgor Zhdan   std::unique_ptr<SerializedGlobalVariableTable> GlobalVariableTable;
737bb352b6eSEgor Zhdan 
738bb352b6eSEgor Zhdan   using SerializedGlobalFunctionTable =
739bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
740bb352b6eSEgor Zhdan 
741bb352b6eSEgor Zhdan   /// The global function table.
742bb352b6eSEgor Zhdan   std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable;
743bb352b6eSEgor Zhdan 
744bb352b6eSEgor Zhdan   using SerializedEnumConstantTable =
745bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
746bb352b6eSEgor Zhdan 
747bb352b6eSEgor Zhdan   /// The enumerator table.
748bb352b6eSEgor Zhdan   std::unique_ptr<SerializedEnumConstantTable> EnumConstantTable;
749bb352b6eSEgor Zhdan 
750bb352b6eSEgor Zhdan   using SerializedTagTable = llvm::OnDiskIterableChainedHashTable<TagTableInfo>;
751bb352b6eSEgor Zhdan 
752bb352b6eSEgor Zhdan   /// The tag table.
753bb352b6eSEgor Zhdan   std::unique_ptr<SerializedTagTable> TagTable;
754bb352b6eSEgor Zhdan 
755bb352b6eSEgor Zhdan   using SerializedTypedefTable =
756bb352b6eSEgor Zhdan       llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
757bb352b6eSEgor Zhdan 
758bb352b6eSEgor Zhdan   /// The typedef table.
759bb352b6eSEgor Zhdan   std::unique_ptr<SerializedTypedefTable> TypedefTable;
760bb352b6eSEgor Zhdan 
761bb352b6eSEgor Zhdan   /// Retrieve the identifier ID for the given string, or an empty
762bb352b6eSEgor Zhdan   /// optional if the string is unknown.
763bb352b6eSEgor Zhdan   std::optional<IdentifierID> getIdentifier(llvm::StringRef Str);
764bb352b6eSEgor Zhdan 
765bb352b6eSEgor Zhdan   /// Retrieve the selector ID for the given selector, or an empty
766bb352b6eSEgor Zhdan   /// optional if the string is unknown.
767bb352b6eSEgor Zhdan   std::optional<SelectorID> getSelector(ObjCSelectorRef Selector);
768bb352b6eSEgor Zhdan 
769bb352b6eSEgor Zhdan   bool readControlBlock(llvm::BitstreamCursor &Cursor,
770bb352b6eSEgor Zhdan                         llvm::SmallVectorImpl<uint64_t> &Scratch);
771bb352b6eSEgor Zhdan   bool readIdentifierBlock(llvm::BitstreamCursor &Cursor,
772bb352b6eSEgor Zhdan                            llvm::SmallVectorImpl<uint64_t> &Scratch);
77382ee7ae3SEgor Zhdan   bool readContextBlock(llvm::BitstreamCursor &Cursor,
774bb352b6eSEgor Zhdan                         llvm::SmallVectorImpl<uint64_t> &Scratch);
775bb352b6eSEgor Zhdan   bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor,
776bb352b6eSEgor Zhdan                              llvm::SmallVectorImpl<uint64_t> &Scratch);
777bb352b6eSEgor Zhdan   bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor,
778bb352b6eSEgor Zhdan                            llvm::SmallVectorImpl<uint64_t> &Scratch);
7798a79dc7eSEgor Zhdan   bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor,
7808a79dc7eSEgor Zhdan                           llvm::SmallVectorImpl<uint64_t> &Scratch);
781b8169771SEgor Zhdan   bool readFieldBlock(llvm::BitstreamCursor &Cursor,
782b8169771SEgor Zhdan                       llvm::SmallVectorImpl<uint64_t> &Scratch);
783bb352b6eSEgor Zhdan   bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor,
784bb352b6eSEgor Zhdan                              llvm::SmallVectorImpl<uint64_t> &Scratch);
785bb352b6eSEgor Zhdan   bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
786bb352b6eSEgor Zhdan                                llvm::SmallVectorImpl<uint64_t> &Scratch);
787bb352b6eSEgor Zhdan   bool readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor,
788bb352b6eSEgor Zhdan                                llvm::SmallVectorImpl<uint64_t> &Scratch);
789bb352b6eSEgor Zhdan   bool readEnumConstantBlock(llvm::BitstreamCursor &Cursor,
790bb352b6eSEgor Zhdan                              llvm::SmallVectorImpl<uint64_t> &Scratch);
791bb352b6eSEgor Zhdan   bool readTagBlock(llvm::BitstreamCursor &Cursor,
792bb352b6eSEgor Zhdan                     llvm::SmallVectorImpl<uint64_t> &Scratch);
793bb352b6eSEgor Zhdan   bool readTypedefBlock(llvm::BitstreamCursor &Cursor,
794bb352b6eSEgor Zhdan                         llvm::SmallVectorImpl<uint64_t> &Scratch);
795bb352b6eSEgor Zhdan };
796bb352b6eSEgor Zhdan 
797bb352b6eSEgor Zhdan std::optional<IdentifierID>
798bb352b6eSEgor Zhdan APINotesReader::Implementation::getIdentifier(llvm::StringRef Str) {
799bb352b6eSEgor Zhdan   if (!IdentifierTable)
800bb352b6eSEgor Zhdan     return std::nullopt;
801bb352b6eSEgor Zhdan 
802bb352b6eSEgor Zhdan   if (Str.empty())
803bb352b6eSEgor Zhdan     return IdentifierID(0);
804bb352b6eSEgor Zhdan 
805bb352b6eSEgor Zhdan   auto Known = IdentifierTable->find(Str);
806bb352b6eSEgor Zhdan   if (Known == IdentifierTable->end())
807bb352b6eSEgor Zhdan     return std::nullopt;
808bb352b6eSEgor Zhdan 
809bb352b6eSEgor Zhdan   return *Known;
810bb352b6eSEgor Zhdan }
811bb352b6eSEgor Zhdan 
812bb352b6eSEgor Zhdan std::optional<SelectorID>
813bb352b6eSEgor Zhdan APINotesReader::Implementation::getSelector(ObjCSelectorRef Selector) {
814bb352b6eSEgor Zhdan   if (!ObjCSelectorTable || !IdentifierTable)
815bb352b6eSEgor Zhdan     return std::nullopt;
816bb352b6eSEgor Zhdan 
817bb352b6eSEgor Zhdan   // Translate the identifiers.
818bb352b6eSEgor Zhdan   StoredObjCSelector Key;
81941021e8eSEgor Zhdan   Key.NumArgs = Selector.NumArgs;
820bb352b6eSEgor Zhdan   for (auto Ident : Selector.Identifiers) {
821bb352b6eSEgor Zhdan     if (auto IdentID = getIdentifier(Ident)) {
822bb352b6eSEgor Zhdan       Key.Identifiers.push_back(*IdentID);
823bb352b6eSEgor Zhdan     } else {
824bb352b6eSEgor Zhdan       return std::nullopt;
825bb352b6eSEgor Zhdan     }
826bb352b6eSEgor Zhdan   }
827bb352b6eSEgor Zhdan 
828bb352b6eSEgor Zhdan   auto Known = ObjCSelectorTable->find(Key);
829bb352b6eSEgor Zhdan   if (Known == ObjCSelectorTable->end())
830bb352b6eSEgor Zhdan     return std::nullopt;
831bb352b6eSEgor Zhdan 
832bb352b6eSEgor Zhdan   return *Known;
833bb352b6eSEgor Zhdan }
834bb352b6eSEgor Zhdan 
835bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readControlBlock(
836bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
837bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID))
838bb352b6eSEgor Zhdan     return true;
839bb352b6eSEgor Zhdan 
840bb352b6eSEgor Zhdan   bool SawMetadata = false;
841bb352b6eSEgor Zhdan 
842bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
843bb352b6eSEgor Zhdan   if (!MaybeNext) {
844bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
845bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
846bb352b6eSEgor Zhdan     return false;
847bb352b6eSEgor Zhdan   }
848bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
849bb352b6eSEgor Zhdan 
850bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
851bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
852bb352b6eSEgor Zhdan       return true;
853bb352b6eSEgor Zhdan 
854bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
855bb352b6eSEgor Zhdan       // Unknown metadata sub-block, possibly for use by a future version of the
856bb352b6eSEgor Zhdan       // API notes format.
857bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
858bb352b6eSEgor Zhdan         return true;
859bb352b6eSEgor Zhdan 
860bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
861bb352b6eSEgor Zhdan       if (!MaybeNext) {
862bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
863bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
864bb352b6eSEgor Zhdan         return false;
865bb352b6eSEgor Zhdan       }
866bb352b6eSEgor Zhdan       Next = MaybeNext.get();
867bb352b6eSEgor Zhdan       continue;
868bb352b6eSEgor Zhdan     }
869bb352b6eSEgor Zhdan 
870bb352b6eSEgor Zhdan     Scratch.clear();
871bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
872bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
873bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
874bb352b6eSEgor Zhdan     if (!MaybeKind) {
875bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
876bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
877bb352b6eSEgor Zhdan       return false;
878bb352b6eSEgor Zhdan     }
879bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
880bb352b6eSEgor Zhdan 
881bb352b6eSEgor Zhdan     switch (Kind) {
882bb352b6eSEgor Zhdan     case control_block::METADATA:
883bb352b6eSEgor Zhdan       // Already saw metadata.
884bb352b6eSEgor Zhdan       if (SawMetadata)
885bb352b6eSEgor Zhdan         return true;
886bb352b6eSEgor Zhdan 
887bb352b6eSEgor Zhdan       if (Scratch[0] != VERSION_MAJOR || Scratch[1] != VERSION_MINOR)
888bb352b6eSEgor Zhdan         return true;
889bb352b6eSEgor Zhdan 
890bb352b6eSEgor Zhdan       SawMetadata = true;
891bb352b6eSEgor Zhdan       break;
892bb352b6eSEgor Zhdan 
893bb352b6eSEgor Zhdan     case control_block::MODULE_NAME:
894bb352b6eSEgor Zhdan       ModuleName = BlobData.str();
895bb352b6eSEgor Zhdan       break;
896bb352b6eSEgor Zhdan 
897bb352b6eSEgor Zhdan     case control_block::MODULE_OPTIONS:
898bb352b6eSEgor Zhdan       break;
899bb352b6eSEgor Zhdan 
900bb352b6eSEgor Zhdan     case control_block::SOURCE_FILE:
901bb352b6eSEgor Zhdan       SourceFileSizeAndModTime = {Scratch[0], Scratch[1]};
902bb352b6eSEgor Zhdan       break;
903bb352b6eSEgor Zhdan 
904bb352b6eSEgor Zhdan     default:
905bb352b6eSEgor Zhdan       // Unknown metadata record, possibly for use by a future version of the
906bb352b6eSEgor Zhdan       // module format.
907bb352b6eSEgor Zhdan       break;
908bb352b6eSEgor Zhdan     }
909bb352b6eSEgor Zhdan 
910bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
911bb352b6eSEgor Zhdan     if (!MaybeNext) {
912bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
913bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
914bb352b6eSEgor Zhdan       return false;
915bb352b6eSEgor Zhdan     }
916bb352b6eSEgor Zhdan     Next = MaybeNext.get();
917bb352b6eSEgor Zhdan   }
918bb352b6eSEgor Zhdan 
919bb352b6eSEgor Zhdan   return !SawMetadata;
920bb352b6eSEgor Zhdan }
921bb352b6eSEgor Zhdan 
922bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readIdentifierBlock(
923bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
924bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID))
925bb352b6eSEgor Zhdan     return true;
926bb352b6eSEgor Zhdan 
927bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
928bb352b6eSEgor Zhdan   if (!MaybeNext) {
929bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
930bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
931bb352b6eSEgor Zhdan     return false;
932bb352b6eSEgor Zhdan   }
933bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
934bb352b6eSEgor Zhdan 
935bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
936bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
937bb352b6eSEgor Zhdan       return true;
938bb352b6eSEgor Zhdan 
939bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
940bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
941bb352b6eSEgor Zhdan       // API notes format.
942bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
943bb352b6eSEgor Zhdan         return true;
944bb352b6eSEgor Zhdan 
945bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
946bb352b6eSEgor Zhdan       if (!MaybeNext) {
947bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
948bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
949bb352b6eSEgor Zhdan         return false;
950bb352b6eSEgor Zhdan       }
951bb352b6eSEgor Zhdan       Next = MaybeNext.get();
952bb352b6eSEgor Zhdan       continue;
953bb352b6eSEgor Zhdan     }
954bb352b6eSEgor Zhdan 
955bb352b6eSEgor Zhdan     Scratch.clear();
956bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
957bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
958bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
959bb352b6eSEgor Zhdan     if (!MaybeKind) {
960bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
961bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
962bb352b6eSEgor Zhdan       return false;
963bb352b6eSEgor Zhdan     }
964bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
965bb352b6eSEgor Zhdan     switch (Kind) {
966bb352b6eSEgor Zhdan     case identifier_block::IDENTIFIER_DATA: {
967bb352b6eSEgor Zhdan       // Already saw identifier table.
968bb352b6eSEgor Zhdan       if (IdentifierTable)
969bb352b6eSEgor Zhdan         return true;
970bb352b6eSEgor Zhdan 
971bb352b6eSEgor Zhdan       uint32_t tableOffset;
972bb352b6eSEgor Zhdan       identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);
973bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
974bb352b6eSEgor Zhdan 
975bb352b6eSEgor Zhdan       IdentifierTable.reset(SerializedIdentifierTable::Create(
976bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
977bb352b6eSEgor Zhdan       break;
978bb352b6eSEgor Zhdan     }
979bb352b6eSEgor Zhdan 
980bb352b6eSEgor Zhdan     default:
981bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
982bb352b6eSEgor Zhdan       // module format.
983bb352b6eSEgor Zhdan       break;
984bb352b6eSEgor Zhdan     }
985bb352b6eSEgor Zhdan 
986bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
987bb352b6eSEgor Zhdan     if (!MaybeNext) {
988bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
989bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
990bb352b6eSEgor Zhdan       return false;
991bb352b6eSEgor Zhdan     }
992bb352b6eSEgor Zhdan     Next = MaybeNext.get();
993bb352b6eSEgor Zhdan   }
994bb352b6eSEgor Zhdan 
995bb352b6eSEgor Zhdan   return false;
996bb352b6eSEgor Zhdan }
997bb352b6eSEgor Zhdan 
99882ee7ae3SEgor Zhdan bool APINotesReader::Implementation::readContextBlock(
999bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1000bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID))
1001bb352b6eSEgor Zhdan     return true;
1002bb352b6eSEgor Zhdan 
1003bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1004bb352b6eSEgor Zhdan   if (!MaybeNext) {
1005bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1006bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1007bb352b6eSEgor Zhdan     return false;
1008bb352b6eSEgor Zhdan   }
1009bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1010bb352b6eSEgor Zhdan 
1011bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1012bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1013bb352b6eSEgor Zhdan       return true;
1014bb352b6eSEgor Zhdan 
1015bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1016bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1017bb352b6eSEgor Zhdan       // API notes format.
1018bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1019bb352b6eSEgor Zhdan         return true;
1020bb352b6eSEgor Zhdan 
1021bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1022bb352b6eSEgor Zhdan       if (!MaybeNext) {
1023bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1024bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1025bb352b6eSEgor Zhdan         return false;
1026bb352b6eSEgor Zhdan       }
1027bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1028bb352b6eSEgor Zhdan       continue;
1029bb352b6eSEgor Zhdan     }
1030bb352b6eSEgor Zhdan 
1031bb352b6eSEgor Zhdan     Scratch.clear();
1032bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1033bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1034bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1035bb352b6eSEgor Zhdan     if (!MaybeKind) {
1036bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1037bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1038bb352b6eSEgor Zhdan       return false;
1039bb352b6eSEgor Zhdan     }
1040bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1041bb352b6eSEgor Zhdan     switch (Kind) {
104282ee7ae3SEgor Zhdan     case context_block::CONTEXT_ID_DATA: {
104382ee7ae3SEgor Zhdan       // Already saw Objective-C / C++ context ID table.
104482ee7ae3SEgor Zhdan       if (ContextIDTable)
1045bb352b6eSEgor Zhdan         return true;
1046bb352b6eSEgor Zhdan 
1047bb352b6eSEgor Zhdan       uint32_t tableOffset;
104882ee7ae3SEgor Zhdan       context_block::ContextIDLayout::readRecord(Scratch, tableOffset);
1049bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1050bb352b6eSEgor Zhdan 
105182ee7ae3SEgor Zhdan       ContextIDTable.reset(SerializedContextIDTable::Create(
1052bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1053bb352b6eSEgor Zhdan       break;
1054bb352b6eSEgor Zhdan     }
1055bb352b6eSEgor Zhdan 
105682ee7ae3SEgor Zhdan     case context_block::CONTEXT_INFO_DATA: {
105782ee7ae3SEgor Zhdan       // Already saw Objective-C / C++ context info table.
105882ee7ae3SEgor Zhdan       if (ContextInfoTable)
1059bb352b6eSEgor Zhdan         return true;
1060bb352b6eSEgor Zhdan 
1061bb352b6eSEgor Zhdan       uint32_t tableOffset;
106282ee7ae3SEgor Zhdan       context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);
1063bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1064bb352b6eSEgor Zhdan 
106582ee7ae3SEgor Zhdan       ContextInfoTable.reset(SerializedContextInfoTable::Create(
1066bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1067bb352b6eSEgor Zhdan       break;
1068bb352b6eSEgor Zhdan     }
1069bb352b6eSEgor Zhdan 
1070bb352b6eSEgor Zhdan     default:
1071bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1072bb352b6eSEgor Zhdan       // module format.
1073bb352b6eSEgor Zhdan       break;
1074bb352b6eSEgor Zhdan     }
1075bb352b6eSEgor Zhdan 
1076bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1077bb352b6eSEgor Zhdan     if (!MaybeNext) {
1078bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1079bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1080bb352b6eSEgor Zhdan       return false;
1081bb352b6eSEgor Zhdan     }
1082bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1083bb352b6eSEgor Zhdan   }
1084bb352b6eSEgor Zhdan 
1085bb352b6eSEgor Zhdan   return false;
1086bb352b6eSEgor Zhdan }
1087bb352b6eSEgor Zhdan 
1088bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCPropertyBlock(
1089bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1090bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID))
1091bb352b6eSEgor Zhdan     return true;
1092bb352b6eSEgor Zhdan 
1093bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1094bb352b6eSEgor Zhdan   if (!MaybeNext) {
1095bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1096bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1097bb352b6eSEgor Zhdan     return false;
1098bb352b6eSEgor Zhdan   }
1099bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1100bb352b6eSEgor Zhdan 
1101bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1102bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1103bb352b6eSEgor Zhdan       return true;
1104bb352b6eSEgor Zhdan 
1105bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1106bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1107bb352b6eSEgor Zhdan       // API notes format.
1108bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1109bb352b6eSEgor Zhdan         return true;
1110bb352b6eSEgor Zhdan 
1111bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1112bb352b6eSEgor Zhdan       if (!MaybeNext) {
1113bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1114bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1115bb352b6eSEgor Zhdan         return false;
1116bb352b6eSEgor Zhdan       }
1117bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1118bb352b6eSEgor Zhdan       continue;
1119bb352b6eSEgor Zhdan     }
1120bb352b6eSEgor Zhdan 
1121bb352b6eSEgor Zhdan     Scratch.clear();
1122bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1123bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1124bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1125bb352b6eSEgor Zhdan     if (!MaybeKind) {
1126bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1127bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1128bb352b6eSEgor Zhdan       return false;
1129bb352b6eSEgor Zhdan     }
1130bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1131bb352b6eSEgor Zhdan     switch (Kind) {
1132bb352b6eSEgor Zhdan     case objc_property_block::OBJC_PROPERTY_DATA: {
1133bb352b6eSEgor Zhdan       // Already saw Objective-C property table.
1134bb352b6eSEgor Zhdan       if (ObjCPropertyTable)
1135bb352b6eSEgor Zhdan         return true;
1136bb352b6eSEgor Zhdan 
1137bb352b6eSEgor Zhdan       uint32_t tableOffset;
1138bb352b6eSEgor Zhdan       objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,
1139bb352b6eSEgor Zhdan                                                               tableOffset);
1140bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1141bb352b6eSEgor Zhdan 
1142bb352b6eSEgor Zhdan       ObjCPropertyTable.reset(SerializedObjCPropertyTable::Create(
1143bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1144bb352b6eSEgor Zhdan       break;
1145bb352b6eSEgor Zhdan     }
1146bb352b6eSEgor Zhdan 
1147bb352b6eSEgor Zhdan     default:
1148bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1149bb352b6eSEgor Zhdan       // module format.
1150bb352b6eSEgor Zhdan       break;
1151bb352b6eSEgor Zhdan     }
1152bb352b6eSEgor Zhdan 
1153bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1154bb352b6eSEgor Zhdan     if (!MaybeNext) {
1155bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1156bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1157bb352b6eSEgor Zhdan       return false;
1158bb352b6eSEgor Zhdan     }
1159bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1160bb352b6eSEgor Zhdan   }
1161bb352b6eSEgor Zhdan 
1162bb352b6eSEgor Zhdan   return false;
1163bb352b6eSEgor Zhdan }
1164bb352b6eSEgor Zhdan 
1165bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCMethodBlock(
1166bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1167bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID))
1168bb352b6eSEgor Zhdan     return true;
1169bb352b6eSEgor Zhdan 
1170bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1171bb352b6eSEgor Zhdan   if (!MaybeNext) {
1172bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1173bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1174bb352b6eSEgor Zhdan     return false;
1175bb352b6eSEgor Zhdan   }
1176bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1177bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1178bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1179bb352b6eSEgor Zhdan       return true;
1180bb352b6eSEgor Zhdan 
1181bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1182bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1183bb352b6eSEgor Zhdan       // API notes format.
1184bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1185bb352b6eSEgor Zhdan         return true;
1186bb352b6eSEgor Zhdan 
1187bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1188bb352b6eSEgor Zhdan       if (!MaybeNext) {
1189bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1190bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1191bb352b6eSEgor Zhdan         return false;
1192bb352b6eSEgor Zhdan       }
1193bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1194bb352b6eSEgor Zhdan       continue;
1195bb352b6eSEgor Zhdan     }
1196bb352b6eSEgor Zhdan 
1197bb352b6eSEgor Zhdan     Scratch.clear();
1198bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1199bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1200bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1201bb352b6eSEgor Zhdan     if (!MaybeKind) {
1202bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1203bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1204bb352b6eSEgor Zhdan       return false;
1205bb352b6eSEgor Zhdan     }
1206bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1207bb352b6eSEgor Zhdan     switch (Kind) {
1208bb352b6eSEgor Zhdan     case objc_method_block::OBJC_METHOD_DATA: {
1209bb352b6eSEgor Zhdan       // Already saw Objective-C method table.
1210bb352b6eSEgor Zhdan       if (ObjCMethodTable)
1211bb352b6eSEgor Zhdan         return true;
1212bb352b6eSEgor Zhdan 
1213bb352b6eSEgor Zhdan       uint32_t tableOffset;
1214bb352b6eSEgor Zhdan       objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);
1215bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1216bb352b6eSEgor Zhdan 
1217bb352b6eSEgor Zhdan       ObjCMethodTable.reset(SerializedObjCMethodTable::Create(
1218bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1219bb352b6eSEgor Zhdan       break;
1220bb352b6eSEgor Zhdan     }
1221bb352b6eSEgor Zhdan 
1222bb352b6eSEgor Zhdan     default:
1223bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1224bb352b6eSEgor Zhdan       // module format.
1225bb352b6eSEgor Zhdan       break;
1226bb352b6eSEgor Zhdan     }
1227bb352b6eSEgor Zhdan 
1228bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1229bb352b6eSEgor Zhdan     if (!MaybeNext) {
1230bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1231bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1232bb352b6eSEgor Zhdan       return false;
1233bb352b6eSEgor Zhdan     }
1234bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1235bb352b6eSEgor Zhdan   }
1236bb352b6eSEgor Zhdan 
1237bb352b6eSEgor Zhdan   return false;
1238bb352b6eSEgor Zhdan }
1239bb352b6eSEgor Zhdan 
12408a79dc7eSEgor Zhdan bool APINotesReader::Implementation::readCXXMethodBlock(
12418a79dc7eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
12428a79dc7eSEgor Zhdan   if (Cursor.EnterSubBlock(CXX_METHOD_BLOCK_ID))
12438a79dc7eSEgor Zhdan     return true;
12448a79dc7eSEgor Zhdan 
12458a79dc7eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
12468a79dc7eSEgor Zhdan   if (!MaybeNext) {
12478a79dc7eSEgor Zhdan     // FIXME this drops the error on the floor.
12488a79dc7eSEgor Zhdan     consumeError(MaybeNext.takeError());
12498a79dc7eSEgor Zhdan     return false;
12508a79dc7eSEgor Zhdan   }
12518a79dc7eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
12528a79dc7eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
12538a79dc7eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
12548a79dc7eSEgor Zhdan       return true;
12558a79dc7eSEgor Zhdan 
12568a79dc7eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
12578a79dc7eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
12588a79dc7eSEgor Zhdan       // API notes format.
12598a79dc7eSEgor Zhdan       if (Cursor.SkipBlock())
12608a79dc7eSEgor Zhdan         return true;
12618a79dc7eSEgor Zhdan 
12628a79dc7eSEgor Zhdan       MaybeNext = Cursor.advance();
12638a79dc7eSEgor Zhdan       if (!MaybeNext) {
12648a79dc7eSEgor Zhdan         // FIXME this drops the error on the floor.
12658a79dc7eSEgor Zhdan         consumeError(MaybeNext.takeError());
12668a79dc7eSEgor Zhdan         return false;
12678a79dc7eSEgor Zhdan       }
12688a79dc7eSEgor Zhdan       Next = MaybeNext.get();
12698a79dc7eSEgor Zhdan       continue;
12708a79dc7eSEgor Zhdan     }
12718a79dc7eSEgor Zhdan 
12728a79dc7eSEgor Zhdan     Scratch.clear();
12738a79dc7eSEgor Zhdan     llvm::StringRef BlobData;
12748a79dc7eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
12758a79dc7eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
12768a79dc7eSEgor Zhdan     if (!MaybeKind) {
12778a79dc7eSEgor Zhdan       // FIXME this drops the error on the floor.
12788a79dc7eSEgor Zhdan       consumeError(MaybeKind.takeError());
12798a79dc7eSEgor Zhdan       return false;
12808a79dc7eSEgor Zhdan     }
12818a79dc7eSEgor Zhdan     unsigned Kind = MaybeKind.get();
12828a79dc7eSEgor Zhdan     switch (Kind) {
12838a79dc7eSEgor Zhdan     case cxx_method_block::CXX_METHOD_DATA: {
12848a79dc7eSEgor Zhdan       // Already saw C++ method table.
12858a79dc7eSEgor Zhdan       if (CXXMethodTable)
12868a79dc7eSEgor Zhdan         return true;
12878a79dc7eSEgor Zhdan 
12888a79dc7eSEgor Zhdan       uint32_t tableOffset;
12898a79dc7eSEgor Zhdan       cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset);
12908a79dc7eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
12918a79dc7eSEgor Zhdan 
12928a79dc7eSEgor Zhdan       CXXMethodTable.reset(SerializedCXXMethodTable::Create(
12938a79dc7eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
12948a79dc7eSEgor Zhdan       break;
12958a79dc7eSEgor Zhdan     }
12968a79dc7eSEgor Zhdan 
12978a79dc7eSEgor Zhdan     default:
12988a79dc7eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
12998a79dc7eSEgor Zhdan       // module format.
13008a79dc7eSEgor Zhdan       break;
13018a79dc7eSEgor Zhdan     }
13028a79dc7eSEgor Zhdan 
13038a79dc7eSEgor Zhdan     MaybeNext = Cursor.advance();
13048a79dc7eSEgor Zhdan     if (!MaybeNext) {
13058a79dc7eSEgor Zhdan       // FIXME this drops the error on the floor.
13068a79dc7eSEgor Zhdan       consumeError(MaybeNext.takeError());
13078a79dc7eSEgor Zhdan       return false;
13088a79dc7eSEgor Zhdan     }
13098a79dc7eSEgor Zhdan     Next = MaybeNext.get();
13108a79dc7eSEgor Zhdan   }
13118a79dc7eSEgor Zhdan 
13128a79dc7eSEgor Zhdan   return false;
13138a79dc7eSEgor Zhdan }
13148a79dc7eSEgor Zhdan 
1315b8169771SEgor Zhdan bool APINotesReader::Implementation::readFieldBlock(
1316b8169771SEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1317b8169771SEgor Zhdan   if (Cursor.EnterSubBlock(FIELD_BLOCK_ID))
1318b8169771SEgor Zhdan     return true;
1319b8169771SEgor Zhdan 
1320b8169771SEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1321b8169771SEgor Zhdan   if (!MaybeNext) {
1322b8169771SEgor Zhdan     // FIXME this drops the error on the floor.
1323b8169771SEgor Zhdan     consumeError(MaybeNext.takeError());
1324b8169771SEgor Zhdan     return false;
1325b8169771SEgor Zhdan   }
1326b8169771SEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1327b8169771SEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1328b8169771SEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1329b8169771SEgor Zhdan       return true;
1330b8169771SEgor Zhdan 
1331b8169771SEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1332b8169771SEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1333b8169771SEgor Zhdan       // API notes format.
1334b8169771SEgor Zhdan       if (Cursor.SkipBlock())
1335b8169771SEgor Zhdan         return true;
1336b8169771SEgor Zhdan 
1337b8169771SEgor Zhdan       MaybeNext = Cursor.advance();
1338b8169771SEgor Zhdan       if (!MaybeNext) {
1339b8169771SEgor Zhdan         // FIXME this drops the error on the floor.
1340b8169771SEgor Zhdan         consumeError(MaybeNext.takeError());
1341b8169771SEgor Zhdan         return false;
1342b8169771SEgor Zhdan       }
1343b8169771SEgor Zhdan       Next = MaybeNext.get();
1344b8169771SEgor Zhdan       continue;
1345b8169771SEgor Zhdan     }
1346b8169771SEgor Zhdan 
1347b8169771SEgor Zhdan     Scratch.clear();
1348b8169771SEgor Zhdan     llvm::StringRef BlobData;
1349b8169771SEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1350b8169771SEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1351b8169771SEgor Zhdan     if (!MaybeKind) {
1352b8169771SEgor Zhdan       // FIXME this drops the error on the floor.
1353b8169771SEgor Zhdan       consumeError(MaybeKind.takeError());
1354b8169771SEgor Zhdan       return false;
1355b8169771SEgor Zhdan     }
1356b8169771SEgor Zhdan     unsigned Kind = MaybeKind.get();
1357b8169771SEgor Zhdan     switch (Kind) {
1358b8169771SEgor Zhdan     case field_block::FIELD_DATA: {
1359b8169771SEgor Zhdan       // Already saw field table.
1360b8169771SEgor Zhdan       if (FieldTable)
1361b8169771SEgor Zhdan         return true;
1362b8169771SEgor Zhdan 
1363b8169771SEgor Zhdan       uint32_t tableOffset;
1364b8169771SEgor Zhdan       field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
1365b8169771SEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1366b8169771SEgor Zhdan 
1367b8169771SEgor Zhdan       FieldTable.reset(SerializedFieldTable::Create(
1368b8169771SEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1369b8169771SEgor Zhdan       break;
1370b8169771SEgor Zhdan     }
1371b8169771SEgor Zhdan 
1372b8169771SEgor Zhdan     default:
1373b8169771SEgor Zhdan       // Unknown record, possibly for use by a future version of the
1374b8169771SEgor Zhdan       // module format.
1375b8169771SEgor Zhdan       break;
1376b8169771SEgor Zhdan     }
1377b8169771SEgor Zhdan 
1378b8169771SEgor Zhdan     MaybeNext = Cursor.advance();
1379b8169771SEgor Zhdan     if (!MaybeNext) {
1380b8169771SEgor Zhdan       // FIXME this drops the error on the floor.
1381b8169771SEgor Zhdan       consumeError(MaybeNext.takeError());
1382b8169771SEgor Zhdan       return false;
1383b8169771SEgor Zhdan     }
1384b8169771SEgor Zhdan     Next = MaybeNext.get();
1385b8169771SEgor Zhdan   }
1386b8169771SEgor Zhdan 
1387b8169771SEgor Zhdan   return false;
1388b8169771SEgor Zhdan }
1389b8169771SEgor Zhdan 
1390bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCSelectorBlock(
1391bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1392bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
1393bb352b6eSEgor Zhdan     return true;
1394bb352b6eSEgor Zhdan 
1395bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1396bb352b6eSEgor Zhdan   if (!MaybeNext) {
1397bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1398bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1399bb352b6eSEgor Zhdan     return false;
1400bb352b6eSEgor Zhdan   }
1401bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1402bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1403bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1404bb352b6eSEgor Zhdan       return true;
1405bb352b6eSEgor Zhdan 
1406bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1407bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1408bb352b6eSEgor Zhdan       // API notes format.
1409bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1410bb352b6eSEgor Zhdan         return true;
1411bb352b6eSEgor Zhdan 
1412bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1413bb352b6eSEgor Zhdan       if (!MaybeNext) {
1414bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1415bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1416bb352b6eSEgor Zhdan         return false;
1417bb352b6eSEgor Zhdan       }
1418bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1419bb352b6eSEgor Zhdan       continue;
1420bb352b6eSEgor Zhdan     }
1421bb352b6eSEgor Zhdan 
1422bb352b6eSEgor Zhdan     Scratch.clear();
1423bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1424bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1425bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1426bb352b6eSEgor Zhdan     if (!MaybeKind) {
1427bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1428bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1429bb352b6eSEgor Zhdan       return false;
1430bb352b6eSEgor Zhdan     }
1431bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1432bb352b6eSEgor Zhdan     switch (Kind) {
1433bb352b6eSEgor Zhdan     case objc_selector_block::OBJC_SELECTOR_DATA: {
1434bb352b6eSEgor Zhdan       // Already saw Objective-C selector table.
1435bb352b6eSEgor Zhdan       if (ObjCSelectorTable)
1436bb352b6eSEgor Zhdan         return true;
1437bb352b6eSEgor Zhdan 
1438bb352b6eSEgor Zhdan       uint32_t tableOffset;
1439bb352b6eSEgor Zhdan       objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,
1440bb352b6eSEgor Zhdan                                                               tableOffset);
1441bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1442bb352b6eSEgor Zhdan 
1443bb352b6eSEgor Zhdan       ObjCSelectorTable.reset(SerializedObjCSelectorTable::Create(
1444bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1445bb352b6eSEgor Zhdan       break;
1446bb352b6eSEgor Zhdan     }
1447bb352b6eSEgor Zhdan 
1448bb352b6eSEgor Zhdan     default:
1449bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1450bb352b6eSEgor Zhdan       // module format.
1451bb352b6eSEgor Zhdan       break;
1452bb352b6eSEgor Zhdan     }
1453bb352b6eSEgor Zhdan 
1454bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1455bb352b6eSEgor Zhdan     if (!MaybeNext) {
1456bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1457bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1458bb352b6eSEgor Zhdan       return false;
1459bb352b6eSEgor Zhdan     }
1460bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1461bb352b6eSEgor Zhdan   }
1462bb352b6eSEgor Zhdan 
1463bb352b6eSEgor Zhdan   return false;
1464bb352b6eSEgor Zhdan }
1465bb352b6eSEgor Zhdan 
1466bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readGlobalVariableBlock(
1467bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1468bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID))
1469bb352b6eSEgor Zhdan     return true;
1470bb352b6eSEgor Zhdan 
1471bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1472bb352b6eSEgor Zhdan   if (!MaybeNext) {
1473bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1474bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1475bb352b6eSEgor Zhdan     return false;
1476bb352b6eSEgor Zhdan   }
1477bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1478bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1479bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1480bb352b6eSEgor Zhdan       return true;
1481bb352b6eSEgor Zhdan 
1482bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1483bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1484bb352b6eSEgor Zhdan       // API notes format.
1485bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1486bb352b6eSEgor Zhdan         return true;
1487bb352b6eSEgor Zhdan 
1488bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1489bb352b6eSEgor Zhdan       if (!MaybeNext) {
1490bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1491bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1492bb352b6eSEgor Zhdan         return false;
1493bb352b6eSEgor Zhdan       }
1494bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1495bb352b6eSEgor Zhdan       continue;
1496bb352b6eSEgor Zhdan     }
1497bb352b6eSEgor Zhdan 
1498bb352b6eSEgor Zhdan     Scratch.clear();
1499bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1500bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1501bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1502bb352b6eSEgor Zhdan     if (!MaybeKind) {
1503bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1504bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1505bb352b6eSEgor Zhdan       return false;
1506bb352b6eSEgor Zhdan     }
1507bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1508bb352b6eSEgor Zhdan     switch (Kind) {
1509bb352b6eSEgor Zhdan     case global_variable_block::GLOBAL_VARIABLE_DATA: {
1510bb352b6eSEgor Zhdan       // Already saw global variable table.
1511bb352b6eSEgor Zhdan       if (GlobalVariableTable)
1512bb352b6eSEgor Zhdan         return true;
1513bb352b6eSEgor Zhdan 
1514bb352b6eSEgor Zhdan       uint32_t tableOffset;
1515bb352b6eSEgor Zhdan       global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,
1516bb352b6eSEgor Zhdan                                                                   tableOffset);
1517bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1518bb352b6eSEgor Zhdan 
1519bb352b6eSEgor Zhdan       GlobalVariableTable.reset(SerializedGlobalVariableTable::Create(
1520bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1521bb352b6eSEgor Zhdan       break;
1522bb352b6eSEgor Zhdan     }
1523bb352b6eSEgor Zhdan 
1524bb352b6eSEgor Zhdan     default:
1525bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1526bb352b6eSEgor Zhdan       // module format.
1527bb352b6eSEgor Zhdan       break;
1528bb352b6eSEgor Zhdan     }
1529bb352b6eSEgor Zhdan 
1530bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1531bb352b6eSEgor Zhdan     if (!MaybeNext) {
1532bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1533bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1534bb352b6eSEgor Zhdan       return false;
1535bb352b6eSEgor Zhdan     }
1536bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1537bb352b6eSEgor Zhdan   }
1538bb352b6eSEgor Zhdan 
1539bb352b6eSEgor Zhdan   return false;
1540bb352b6eSEgor Zhdan }
1541bb352b6eSEgor Zhdan 
1542bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readGlobalFunctionBlock(
1543bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1544bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID))
1545bb352b6eSEgor Zhdan     return true;
1546bb352b6eSEgor Zhdan 
1547bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1548bb352b6eSEgor Zhdan   if (!MaybeNext) {
1549bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1550bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1551bb352b6eSEgor Zhdan     return false;
1552bb352b6eSEgor Zhdan   }
1553bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1554bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1555bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1556bb352b6eSEgor Zhdan       return true;
1557bb352b6eSEgor Zhdan 
1558bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1559bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1560bb352b6eSEgor Zhdan       // API notes format.
1561bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1562bb352b6eSEgor Zhdan         return true;
1563bb352b6eSEgor Zhdan 
1564bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1565bb352b6eSEgor Zhdan       if (!MaybeNext) {
1566bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1567bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1568bb352b6eSEgor Zhdan         return false;
1569bb352b6eSEgor Zhdan       }
1570bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1571bb352b6eSEgor Zhdan       continue;
1572bb352b6eSEgor Zhdan     }
1573bb352b6eSEgor Zhdan 
1574bb352b6eSEgor Zhdan     Scratch.clear();
1575bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1576bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1577bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1578bb352b6eSEgor Zhdan     if (!MaybeKind) {
1579bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1580bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1581bb352b6eSEgor Zhdan       return false;
1582bb352b6eSEgor Zhdan     }
1583bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1584bb352b6eSEgor Zhdan     switch (Kind) {
1585bb352b6eSEgor Zhdan     case global_function_block::GLOBAL_FUNCTION_DATA: {
1586bb352b6eSEgor Zhdan       // Already saw global function table.
1587bb352b6eSEgor Zhdan       if (GlobalFunctionTable)
1588bb352b6eSEgor Zhdan         return true;
1589bb352b6eSEgor Zhdan 
1590bb352b6eSEgor Zhdan       uint32_t tableOffset;
1591bb352b6eSEgor Zhdan       global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,
1592bb352b6eSEgor Zhdan                                                                   tableOffset);
1593bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1594bb352b6eSEgor Zhdan 
1595bb352b6eSEgor Zhdan       GlobalFunctionTable.reset(SerializedGlobalFunctionTable::Create(
1596bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1597bb352b6eSEgor Zhdan       break;
1598bb352b6eSEgor Zhdan     }
1599bb352b6eSEgor Zhdan 
1600bb352b6eSEgor Zhdan     default:
1601bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1602bb352b6eSEgor Zhdan       // module format.
1603bb352b6eSEgor Zhdan       break;
1604bb352b6eSEgor Zhdan     }
1605bb352b6eSEgor Zhdan 
1606bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1607bb352b6eSEgor Zhdan     if (!MaybeNext) {
1608bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1609bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1610bb352b6eSEgor Zhdan       return false;
1611bb352b6eSEgor Zhdan     }
1612bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1613bb352b6eSEgor Zhdan   }
1614bb352b6eSEgor Zhdan 
1615bb352b6eSEgor Zhdan   return false;
1616bb352b6eSEgor Zhdan }
1617bb352b6eSEgor Zhdan 
1618bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readEnumConstantBlock(
1619bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1620bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID))
1621bb352b6eSEgor Zhdan     return true;
1622bb352b6eSEgor Zhdan 
1623bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1624bb352b6eSEgor Zhdan   if (!MaybeNext) {
1625bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1626bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1627bb352b6eSEgor Zhdan     return false;
1628bb352b6eSEgor Zhdan   }
1629bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1630bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1631bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1632bb352b6eSEgor Zhdan       return true;
1633bb352b6eSEgor Zhdan 
1634bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1635bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1636bb352b6eSEgor Zhdan       // API notes format.
1637bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1638bb352b6eSEgor Zhdan         return true;
1639bb352b6eSEgor Zhdan 
1640bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1641bb352b6eSEgor Zhdan       if (!MaybeNext) {
1642bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1643bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1644bb352b6eSEgor Zhdan         return false;
1645bb352b6eSEgor Zhdan       }
1646bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1647bb352b6eSEgor Zhdan       continue;
1648bb352b6eSEgor Zhdan     }
1649bb352b6eSEgor Zhdan 
1650bb352b6eSEgor Zhdan     Scratch.clear();
1651bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1652bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1653bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1654bb352b6eSEgor Zhdan     if (!MaybeKind) {
1655bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1656bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1657bb352b6eSEgor Zhdan       return false;
1658bb352b6eSEgor Zhdan     }
1659bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1660bb352b6eSEgor Zhdan     switch (Kind) {
1661bb352b6eSEgor Zhdan     case enum_constant_block::ENUM_CONSTANT_DATA: {
1662bb352b6eSEgor Zhdan       // Already saw enumerator table.
1663bb352b6eSEgor Zhdan       if (EnumConstantTable)
1664bb352b6eSEgor Zhdan         return true;
1665bb352b6eSEgor Zhdan 
1666bb352b6eSEgor Zhdan       uint32_t tableOffset;
1667bb352b6eSEgor Zhdan       enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,
1668bb352b6eSEgor Zhdan                                                               tableOffset);
1669bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1670bb352b6eSEgor Zhdan 
1671bb352b6eSEgor Zhdan       EnumConstantTable.reset(SerializedEnumConstantTable::Create(
1672bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1673bb352b6eSEgor Zhdan       break;
1674bb352b6eSEgor Zhdan     }
1675bb352b6eSEgor Zhdan 
1676bb352b6eSEgor Zhdan     default:
1677bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1678bb352b6eSEgor Zhdan       // module format.
1679bb352b6eSEgor Zhdan       break;
1680bb352b6eSEgor Zhdan     }
1681bb352b6eSEgor Zhdan 
1682bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1683bb352b6eSEgor Zhdan     if (!MaybeNext) {
1684bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1685bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1686bb352b6eSEgor Zhdan       return false;
1687bb352b6eSEgor Zhdan     }
1688bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1689bb352b6eSEgor Zhdan   }
1690bb352b6eSEgor Zhdan 
1691bb352b6eSEgor Zhdan   return false;
1692bb352b6eSEgor Zhdan }
1693bb352b6eSEgor Zhdan 
1694bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readTagBlock(
1695bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1696bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(TAG_BLOCK_ID))
1697bb352b6eSEgor Zhdan     return true;
1698bb352b6eSEgor Zhdan 
1699bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1700bb352b6eSEgor Zhdan   if (!MaybeNext) {
1701bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1702bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1703bb352b6eSEgor Zhdan     return false;
1704bb352b6eSEgor Zhdan   }
1705bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1706bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1707bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1708bb352b6eSEgor Zhdan       return true;
1709bb352b6eSEgor Zhdan 
1710bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1711bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1712bb352b6eSEgor Zhdan       // API notes format.
1713bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1714bb352b6eSEgor Zhdan         return true;
1715bb352b6eSEgor Zhdan 
1716bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1717bb352b6eSEgor Zhdan       if (!MaybeNext) {
1718bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1719bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1720bb352b6eSEgor Zhdan         return false;
1721bb352b6eSEgor Zhdan       }
1722bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1723bb352b6eSEgor Zhdan       continue;
1724bb352b6eSEgor Zhdan     }
1725bb352b6eSEgor Zhdan 
1726bb352b6eSEgor Zhdan     Scratch.clear();
1727bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1728bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1729bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1730bb352b6eSEgor Zhdan     if (!MaybeKind) {
1731bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1732bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1733bb352b6eSEgor Zhdan       return false;
1734bb352b6eSEgor Zhdan     }
1735bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1736bb352b6eSEgor Zhdan     switch (Kind) {
1737bb352b6eSEgor Zhdan     case tag_block::TAG_DATA: {
1738bb352b6eSEgor Zhdan       // Already saw tag table.
1739bb352b6eSEgor Zhdan       if (TagTable)
1740bb352b6eSEgor Zhdan         return true;
1741bb352b6eSEgor Zhdan 
1742bb352b6eSEgor Zhdan       uint32_t tableOffset;
1743bb352b6eSEgor Zhdan       tag_block::TagDataLayout::readRecord(Scratch, tableOffset);
1744bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1745bb352b6eSEgor Zhdan 
1746bb352b6eSEgor Zhdan       TagTable.reset(SerializedTagTable::Create(base + tableOffset,
1747bb352b6eSEgor Zhdan                                                 base + sizeof(uint32_t), base));
1748bb352b6eSEgor Zhdan       break;
1749bb352b6eSEgor Zhdan     }
1750bb352b6eSEgor Zhdan 
1751bb352b6eSEgor Zhdan     default:
1752bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1753bb352b6eSEgor Zhdan       // module format.
1754bb352b6eSEgor Zhdan       break;
1755bb352b6eSEgor Zhdan     }
1756bb352b6eSEgor Zhdan 
1757bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1758bb352b6eSEgor Zhdan     if (!MaybeNext) {
1759bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1760bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1761bb352b6eSEgor Zhdan       return false;
1762bb352b6eSEgor Zhdan     }
1763bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1764bb352b6eSEgor Zhdan   }
1765bb352b6eSEgor Zhdan 
1766bb352b6eSEgor Zhdan   return false;
1767bb352b6eSEgor Zhdan }
1768bb352b6eSEgor Zhdan 
1769bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readTypedefBlock(
1770bb352b6eSEgor Zhdan     llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1771bb352b6eSEgor Zhdan   if (Cursor.EnterSubBlock(TYPEDEF_BLOCK_ID))
1772bb352b6eSEgor Zhdan     return true;
1773bb352b6eSEgor Zhdan 
1774bb352b6eSEgor Zhdan   llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1775bb352b6eSEgor Zhdan   if (!MaybeNext) {
1776bb352b6eSEgor Zhdan     // FIXME this drops the error on the floor.
1777bb352b6eSEgor Zhdan     consumeError(MaybeNext.takeError());
1778bb352b6eSEgor Zhdan     return false;
1779bb352b6eSEgor Zhdan   }
1780bb352b6eSEgor Zhdan   llvm::BitstreamEntry Next = MaybeNext.get();
1781bb352b6eSEgor Zhdan   while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1782bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::Error)
1783bb352b6eSEgor Zhdan       return true;
1784bb352b6eSEgor Zhdan 
1785bb352b6eSEgor Zhdan     if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1786bb352b6eSEgor Zhdan       // Unknown sub-block, possibly for use by a future version of the
1787bb352b6eSEgor Zhdan       // API notes format.
1788bb352b6eSEgor Zhdan       if (Cursor.SkipBlock())
1789bb352b6eSEgor Zhdan         return true;
1790bb352b6eSEgor Zhdan 
1791bb352b6eSEgor Zhdan       MaybeNext = Cursor.advance();
1792bb352b6eSEgor Zhdan       if (!MaybeNext) {
1793bb352b6eSEgor Zhdan         // FIXME this drops the error on the floor.
1794bb352b6eSEgor Zhdan         consumeError(MaybeNext.takeError());
1795bb352b6eSEgor Zhdan         return false;
1796bb352b6eSEgor Zhdan       }
1797bb352b6eSEgor Zhdan       Next = MaybeNext.get();
1798bb352b6eSEgor Zhdan       continue;
1799bb352b6eSEgor Zhdan     }
1800bb352b6eSEgor Zhdan 
1801bb352b6eSEgor Zhdan     Scratch.clear();
1802bb352b6eSEgor Zhdan     llvm::StringRef BlobData;
1803bb352b6eSEgor Zhdan     llvm::Expected<unsigned> MaybeKind =
1804bb352b6eSEgor Zhdan         Cursor.readRecord(Next.ID, Scratch, &BlobData);
1805bb352b6eSEgor Zhdan     if (!MaybeKind) {
1806bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1807bb352b6eSEgor Zhdan       consumeError(MaybeKind.takeError());
1808bb352b6eSEgor Zhdan       return false;
1809bb352b6eSEgor Zhdan     }
1810bb352b6eSEgor Zhdan     unsigned Kind = MaybeKind.get();
1811bb352b6eSEgor Zhdan     switch (Kind) {
1812bb352b6eSEgor Zhdan     case typedef_block::TYPEDEF_DATA: {
1813bb352b6eSEgor Zhdan       // Already saw typedef table.
1814bb352b6eSEgor Zhdan       if (TypedefTable)
1815bb352b6eSEgor Zhdan         return true;
1816bb352b6eSEgor Zhdan 
1817bb352b6eSEgor Zhdan       uint32_t tableOffset;
1818bb352b6eSEgor Zhdan       typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);
1819bb352b6eSEgor Zhdan       auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1820bb352b6eSEgor Zhdan 
1821bb352b6eSEgor Zhdan       TypedefTable.reset(SerializedTypedefTable::Create(
1822bb352b6eSEgor Zhdan           base + tableOffset, base + sizeof(uint32_t), base));
1823bb352b6eSEgor Zhdan       break;
1824bb352b6eSEgor Zhdan     }
1825bb352b6eSEgor Zhdan 
1826bb352b6eSEgor Zhdan     default:
1827bb352b6eSEgor Zhdan       // Unknown record, possibly for use by a future version of the
1828bb352b6eSEgor Zhdan       // module format.
1829bb352b6eSEgor Zhdan       break;
1830bb352b6eSEgor Zhdan     }
1831bb352b6eSEgor Zhdan 
1832bb352b6eSEgor Zhdan     MaybeNext = Cursor.advance();
1833bb352b6eSEgor Zhdan     if (!MaybeNext) {
1834bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1835bb352b6eSEgor Zhdan       consumeError(MaybeNext.takeError());
1836bb352b6eSEgor Zhdan       return false;
1837bb352b6eSEgor Zhdan     }
1838bb352b6eSEgor Zhdan     Next = MaybeNext.get();
1839bb352b6eSEgor Zhdan   }
1840bb352b6eSEgor Zhdan 
1841bb352b6eSEgor Zhdan   return false;
1842bb352b6eSEgor Zhdan }
1843bb352b6eSEgor Zhdan 
1844bb352b6eSEgor Zhdan APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1845bb352b6eSEgor Zhdan                                llvm::VersionTuple SwiftVersion, bool &Failed)
1846bb352b6eSEgor Zhdan     : Implementation(new class Implementation) {
1847bb352b6eSEgor Zhdan   Failed = false;
1848bb352b6eSEgor Zhdan 
1849bb352b6eSEgor Zhdan   // Initialize the input buffer.
1850bb352b6eSEgor Zhdan   Implementation->InputBuffer = InputBuffer;
1851bb352b6eSEgor Zhdan   Implementation->SwiftVersion = SwiftVersion;
1852bb352b6eSEgor Zhdan   llvm::BitstreamCursor Cursor(*Implementation->InputBuffer);
1853bb352b6eSEgor Zhdan 
1854bb352b6eSEgor Zhdan   // Validate signature.
1855bb352b6eSEgor Zhdan   for (auto byte : API_NOTES_SIGNATURE) {
1856bb352b6eSEgor Zhdan     if (Cursor.AtEndOfStream()) {
1857bb352b6eSEgor Zhdan       Failed = true;
1858bb352b6eSEgor Zhdan       return;
1859bb352b6eSEgor Zhdan     }
1860bb352b6eSEgor Zhdan     if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead =
1861bb352b6eSEgor Zhdan             Cursor.Read(8)) {
1862bb352b6eSEgor Zhdan       if (maybeRead.get() != byte) {
1863bb352b6eSEgor Zhdan         Failed = true;
1864bb352b6eSEgor Zhdan         return;
1865bb352b6eSEgor Zhdan       }
1866bb352b6eSEgor Zhdan     } else {
1867bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1868bb352b6eSEgor Zhdan       consumeError(maybeRead.takeError());
1869bb352b6eSEgor Zhdan       Failed = true;
1870bb352b6eSEgor Zhdan       return;
1871bb352b6eSEgor Zhdan     }
1872bb352b6eSEgor Zhdan   }
1873bb352b6eSEgor Zhdan 
1874bb352b6eSEgor Zhdan   // Look at all of the blocks.
1875bb352b6eSEgor Zhdan   bool HasValidControlBlock = false;
1876bb352b6eSEgor Zhdan   llvm::SmallVector<uint64_t, 64> Scratch;
1877bb352b6eSEgor Zhdan   while (!Cursor.AtEndOfStream()) {
1878bb352b6eSEgor Zhdan     llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry = Cursor.advance();
1879bb352b6eSEgor Zhdan     if (!MaybeTopLevelEntry) {
1880bb352b6eSEgor Zhdan       // FIXME this drops the error on the floor.
1881bb352b6eSEgor Zhdan       consumeError(MaybeTopLevelEntry.takeError());
1882bb352b6eSEgor Zhdan       Failed = true;
1883bb352b6eSEgor Zhdan       return;
1884bb352b6eSEgor Zhdan     }
1885bb352b6eSEgor Zhdan     llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
1886bb352b6eSEgor Zhdan 
1887bb352b6eSEgor Zhdan     if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
1888bb352b6eSEgor Zhdan       break;
1889bb352b6eSEgor Zhdan 
1890bb352b6eSEgor Zhdan     switch (TopLevelEntry.ID) {
1891bb352b6eSEgor Zhdan     case llvm::bitc::BLOCKINFO_BLOCK_ID:
1892bb352b6eSEgor Zhdan       if (!Cursor.ReadBlockInfoBlock()) {
1893bb352b6eSEgor Zhdan         Failed = true;
1894bb352b6eSEgor Zhdan         break;
1895bb352b6eSEgor Zhdan       }
1896bb352b6eSEgor Zhdan       break;
1897bb352b6eSEgor Zhdan 
1898bb352b6eSEgor Zhdan     case CONTROL_BLOCK_ID:
1899bb352b6eSEgor Zhdan       // Only allow a single control block.
1900bb352b6eSEgor Zhdan       if (HasValidControlBlock ||
1901bb352b6eSEgor Zhdan           Implementation->readControlBlock(Cursor, Scratch)) {
1902bb352b6eSEgor Zhdan         Failed = true;
1903bb352b6eSEgor Zhdan         return;
1904bb352b6eSEgor Zhdan       }
1905bb352b6eSEgor Zhdan 
1906bb352b6eSEgor Zhdan       HasValidControlBlock = true;
1907bb352b6eSEgor Zhdan       break;
1908bb352b6eSEgor Zhdan 
1909bb352b6eSEgor Zhdan     case IDENTIFIER_BLOCK_ID:
1910bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1911bb352b6eSEgor Zhdan           Implementation->readIdentifierBlock(Cursor, Scratch)) {
1912bb352b6eSEgor Zhdan         Failed = true;
1913bb352b6eSEgor Zhdan         return;
1914bb352b6eSEgor Zhdan       }
1915bb352b6eSEgor Zhdan       break;
1916bb352b6eSEgor Zhdan 
1917bb352b6eSEgor Zhdan     case OBJC_CONTEXT_BLOCK_ID:
1918bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
191982ee7ae3SEgor Zhdan           Implementation->readContextBlock(Cursor, Scratch)) {
1920bb352b6eSEgor Zhdan         Failed = true;
1921bb352b6eSEgor Zhdan         return;
1922bb352b6eSEgor Zhdan       }
1923bb352b6eSEgor Zhdan 
1924bb352b6eSEgor Zhdan       break;
1925bb352b6eSEgor Zhdan 
1926bb352b6eSEgor Zhdan     case OBJC_PROPERTY_BLOCK_ID:
1927bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1928bb352b6eSEgor Zhdan           Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
1929bb352b6eSEgor Zhdan         Failed = true;
1930bb352b6eSEgor Zhdan         return;
1931bb352b6eSEgor Zhdan       }
1932bb352b6eSEgor Zhdan       break;
1933bb352b6eSEgor Zhdan 
1934bb352b6eSEgor Zhdan     case OBJC_METHOD_BLOCK_ID:
1935bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1936bb352b6eSEgor Zhdan           Implementation->readObjCMethodBlock(Cursor, Scratch)) {
1937bb352b6eSEgor Zhdan         Failed = true;
1938bb352b6eSEgor Zhdan         return;
1939bb352b6eSEgor Zhdan       }
1940bb352b6eSEgor Zhdan       break;
1941bb352b6eSEgor Zhdan 
19428a79dc7eSEgor Zhdan     case CXX_METHOD_BLOCK_ID:
19438a79dc7eSEgor Zhdan       if (!HasValidControlBlock ||
19448a79dc7eSEgor Zhdan           Implementation->readCXXMethodBlock(Cursor, Scratch)) {
19458a79dc7eSEgor Zhdan         Failed = true;
19468a79dc7eSEgor Zhdan         return;
19478a79dc7eSEgor Zhdan       }
19488a79dc7eSEgor Zhdan       break;
19498a79dc7eSEgor Zhdan 
1950b8169771SEgor Zhdan     case FIELD_BLOCK_ID:
1951b8169771SEgor Zhdan       if (!HasValidControlBlock ||
1952b8169771SEgor Zhdan           Implementation->readFieldBlock(Cursor, Scratch)) {
1953b8169771SEgor Zhdan         Failed = true;
1954b8169771SEgor Zhdan         return;
1955b8169771SEgor Zhdan       }
1956b8169771SEgor Zhdan       break;
1957b8169771SEgor Zhdan 
1958bb352b6eSEgor Zhdan     case OBJC_SELECTOR_BLOCK_ID:
1959bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1960bb352b6eSEgor Zhdan           Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
1961bb352b6eSEgor Zhdan         Failed = true;
1962bb352b6eSEgor Zhdan         return;
1963bb352b6eSEgor Zhdan       }
1964bb352b6eSEgor Zhdan       break;
1965bb352b6eSEgor Zhdan 
1966bb352b6eSEgor Zhdan     case GLOBAL_VARIABLE_BLOCK_ID:
1967bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1968bb352b6eSEgor Zhdan           Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
1969bb352b6eSEgor Zhdan         Failed = true;
1970bb352b6eSEgor Zhdan         return;
1971bb352b6eSEgor Zhdan       }
1972bb352b6eSEgor Zhdan       break;
1973bb352b6eSEgor Zhdan 
1974bb352b6eSEgor Zhdan     case GLOBAL_FUNCTION_BLOCK_ID:
1975bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1976bb352b6eSEgor Zhdan           Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
1977bb352b6eSEgor Zhdan         Failed = true;
1978bb352b6eSEgor Zhdan         return;
1979bb352b6eSEgor Zhdan       }
1980bb352b6eSEgor Zhdan       break;
1981bb352b6eSEgor Zhdan 
1982bb352b6eSEgor Zhdan     case ENUM_CONSTANT_BLOCK_ID:
1983bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1984bb352b6eSEgor Zhdan           Implementation->readEnumConstantBlock(Cursor, Scratch)) {
1985bb352b6eSEgor Zhdan         Failed = true;
1986bb352b6eSEgor Zhdan         return;
1987bb352b6eSEgor Zhdan       }
1988bb352b6eSEgor Zhdan       break;
1989bb352b6eSEgor Zhdan 
1990bb352b6eSEgor Zhdan     case TAG_BLOCK_ID:
1991bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
1992bb352b6eSEgor Zhdan           Implementation->readTagBlock(Cursor, Scratch)) {
1993bb352b6eSEgor Zhdan         Failed = true;
1994bb352b6eSEgor Zhdan         return;
1995bb352b6eSEgor Zhdan       }
1996bb352b6eSEgor Zhdan       break;
1997bb352b6eSEgor Zhdan 
1998bb352b6eSEgor Zhdan     case TYPEDEF_BLOCK_ID:
1999bb352b6eSEgor Zhdan       if (!HasValidControlBlock ||
2000bb352b6eSEgor Zhdan           Implementation->readTypedefBlock(Cursor, Scratch)) {
2001bb352b6eSEgor Zhdan         Failed = true;
2002bb352b6eSEgor Zhdan         return;
2003bb352b6eSEgor Zhdan       }
2004bb352b6eSEgor Zhdan       break;
2005bb352b6eSEgor Zhdan 
2006bb352b6eSEgor Zhdan     default:
2007bb352b6eSEgor Zhdan       // Unknown top-level block, possibly for use by a future version of the
2008bb352b6eSEgor Zhdan       // module format.
2009bb352b6eSEgor Zhdan       if (Cursor.SkipBlock()) {
2010bb352b6eSEgor Zhdan         Failed = true;
2011bb352b6eSEgor Zhdan         return;
2012bb352b6eSEgor Zhdan       }
2013bb352b6eSEgor Zhdan       break;
2014bb352b6eSEgor Zhdan     }
2015bb352b6eSEgor Zhdan   }
2016bb352b6eSEgor Zhdan 
2017bb352b6eSEgor Zhdan   if (!Cursor.AtEndOfStream()) {
2018bb352b6eSEgor Zhdan     Failed = true;
2019bb352b6eSEgor Zhdan     return;
2020bb352b6eSEgor Zhdan   }
2021bb352b6eSEgor Zhdan }
2022bb352b6eSEgor Zhdan 
2023bb352b6eSEgor Zhdan APINotesReader::~APINotesReader() { delete Implementation->InputBuffer; }
2024bb352b6eSEgor Zhdan 
2025bb352b6eSEgor Zhdan std::unique_ptr<APINotesReader>
2026bb352b6eSEgor Zhdan APINotesReader::Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
2027bb352b6eSEgor Zhdan                        llvm::VersionTuple SwiftVersion) {
2028bb352b6eSEgor Zhdan   bool Failed = false;
2029bb352b6eSEgor Zhdan   std::unique_ptr<APINotesReader> Reader(
2030bb352b6eSEgor Zhdan       new APINotesReader(InputBuffer.release(), SwiftVersion, Failed));
2031bb352b6eSEgor Zhdan   if (Failed)
2032bb352b6eSEgor Zhdan     return nullptr;
2033bb352b6eSEgor Zhdan 
2034bb352b6eSEgor Zhdan   return Reader;
2035bb352b6eSEgor Zhdan }
2036bb352b6eSEgor Zhdan 
2037bb352b6eSEgor Zhdan template <typename T>
2038bb352b6eSEgor Zhdan APINotesReader::VersionedInfo<T>::VersionedInfo(
2039bb352b6eSEgor Zhdan     llvm::VersionTuple Version,
20405e4c4365SEgor Zhdan     llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> R)
20415e4c4365SEgor Zhdan     : Results(std::move(R)) {
2042bb352b6eSEgor Zhdan 
2043bb352b6eSEgor Zhdan   assert(!Results.empty());
2044bb352b6eSEgor Zhdan   assert(std::is_sorted(
2045bb352b6eSEgor Zhdan       Results.begin(), Results.end(),
2046bb352b6eSEgor Zhdan       [](const std::pair<llvm::VersionTuple, T> &left,
2047bb352b6eSEgor Zhdan          const std::pair<llvm::VersionTuple, T> &right) -> bool {
2048*26f5d1eeSBjörn Pettersson         // The comparison function should be reflective, and with expensive
2049*26f5d1eeSBjörn Pettersson         // checks we can get callbacks basically checking that lambda(a,a) is
2050*26f5d1eeSBjörn Pettersson         // false. We could still check that we do not find equal elements when
2051*26f5d1eeSBjörn Pettersson         // left!=right.
2052*26f5d1eeSBjörn Pettersson         assert((&left == &right || left.first != right.first) &&
2053*26f5d1eeSBjörn Pettersson                "two entries for the same version");
2054bb352b6eSEgor Zhdan         return left.first < right.first;
2055bb352b6eSEgor Zhdan       }));
2056bb352b6eSEgor Zhdan 
2057bb352b6eSEgor Zhdan   Selected = std::nullopt;
2058bb352b6eSEgor Zhdan   for (unsigned i = 0, n = Results.size(); i != n; ++i) {
2059bb352b6eSEgor Zhdan     if (!Version.empty() && Results[i].first >= Version) {
2060bb352b6eSEgor Zhdan       // If the current version is "4", then entries for 4 are better than
2061bb352b6eSEgor Zhdan       // entries for 5, but both are valid. Because entries are sorted, we get
2062bb352b6eSEgor Zhdan       // that behavior by picking the first match.
2063bb352b6eSEgor Zhdan       Selected = i;
2064bb352b6eSEgor Zhdan       break;
2065bb352b6eSEgor Zhdan     }
2066bb352b6eSEgor Zhdan   }
2067bb352b6eSEgor Zhdan 
2068bb352b6eSEgor Zhdan   // If we didn't find a match but we have an unversioned result, use the
2069bb352b6eSEgor Zhdan   // unversioned result. This will always be the first entry because we encode
2070bb352b6eSEgor Zhdan   // it as version 0.
2071bb352b6eSEgor Zhdan   if (!Selected && Results[0].first.empty())
2072bb352b6eSEgor Zhdan     Selected = 0;
2073bb352b6eSEgor Zhdan }
2074bb352b6eSEgor Zhdan 
2075bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCClassID(llvm::StringRef Name)
2076bb352b6eSEgor Zhdan     -> std::optional<ContextID> {
207782ee7ae3SEgor Zhdan   if (!Implementation->ContextIDTable)
2078bb352b6eSEgor Zhdan     return std::nullopt;
2079bb352b6eSEgor Zhdan 
2080bb352b6eSEgor Zhdan   std::optional<IdentifierID> ClassID = Implementation->getIdentifier(Name);
2081bb352b6eSEgor Zhdan   if (!ClassID)
2082bb352b6eSEgor Zhdan     return std::nullopt;
2083bb352b6eSEgor Zhdan 
2084bb352b6eSEgor Zhdan   // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
2085bb352b6eSEgor Zhdan   // context.
208682ee7ae3SEgor Zhdan   auto KnownID = Implementation->ContextIDTable->find(
2087bb352b6eSEgor Zhdan       ContextTableKey(-1, (uint8_t)ContextKind::ObjCClass, *ClassID));
208882ee7ae3SEgor Zhdan   if (KnownID == Implementation->ContextIDTable->end())
2089bb352b6eSEgor Zhdan     return std::nullopt;
2090bb352b6eSEgor Zhdan 
2091bb352b6eSEgor Zhdan   return ContextID(*KnownID);
2092bb352b6eSEgor Zhdan }
2093bb352b6eSEgor Zhdan 
2094bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCClassInfo(llvm::StringRef Name)
209582ee7ae3SEgor Zhdan     -> VersionedInfo<ContextInfo> {
209682ee7ae3SEgor Zhdan   if (!Implementation->ContextInfoTable)
2097bb352b6eSEgor Zhdan     return std::nullopt;
2098bb352b6eSEgor Zhdan 
2099bb352b6eSEgor Zhdan   std::optional<ContextID> CtxID = lookupObjCClassID(Name);
2100bb352b6eSEgor Zhdan   if (!CtxID)
2101bb352b6eSEgor Zhdan     return std::nullopt;
2102bb352b6eSEgor Zhdan 
210382ee7ae3SEgor Zhdan   auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value);
210482ee7ae3SEgor Zhdan   if (KnownInfo == Implementation->ContextInfoTable->end())
2105bb352b6eSEgor Zhdan     return std::nullopt;
2106bb352b6eSEgor Zhdan 
2107bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *KnownInfo};
2108bb352b6eSEgor Zhdan }
2109bb352b6eSEgor Zhdan 
2110bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name)
2111bb352b6eSEgor Zhdan     -> std::optional<ContextID> {
211282ee7ae3SEgor Zhdan   if (!Implementation->ContextIDTable)
2113bb352b6eSEgor Zhdan     return std::nullopt;
2114bb352b6eSEgor Zhdan 
2115bb352b6eSEgor Zhdan   std::optional<IdentifierID> classID = Implementation->getIdentifier(Name);
2116bb352b6eSEgor Zhdan   if (!classID)
2117bb352b6eSEgor Zhdan     return std::nullopt;
2118bb352b6eSEgor Zhdan 
2119bb352b6eSEgor Zhdan   // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
2120bb352b6eSEgor Zhdan   // context.
212182ee7ae3SEgor Zhdan   auto KnownID = Implementation->ContextIDTable->find(
2122bb352b6eSEgor Zhdan       ContextTableKey(-1, (uint8_t)ContextKind::ObjCProtocol, *classID));
212382ee7ae3SEgor Zhdan   if (KnownID == Implementation->ContextIDTable->end())
2124bb352b6eSEgor Zhdan     return std::nullopt;
2125bb352b6eSEgor Zhdan 
2126bb352b6eSEgor Zhdan   return ContextID(*KnownID);
2127bb352b6eSEgor Zhdan }
2128bb352b6eSEgor Zhdan 
2129bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProtocolInfo(llvm::StringRef Name)
213082ee7ae3SEgor Zhdan     -> VersionedInfo<ContextInfo> {
213182ee7ae3SEgor Zhdan   if (!Implementation->ContextInfoTable)
2132bb352b6eSEgor Zhdan     return std::nullopt;
2133bb352b6eSEgor Zhdan 
2134bb352b6eSEgor Zhdan   std::optional<ContextID> CtxID = lookupObjCProtocolID(Name);
2135bb352b6eSEgor Zhdan   if (!CtxID)
2136bb352b6eSEgor Zhdan     return std::nullopt;
2137bb352b6eSEgor Zhdan 
213882ee7ae3SEgor Zhdan   auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value);
213982ee7ae3SEgor Zhdan   if (KnownInfo == Implementation->ContextInfoTable->end())
2140bb352b6eSEgor Zhdan     return std::nullopt;
2141bb352b6eSEgor Zhdan 
2142bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *KnownInfo};
2143bb352b6eSEgor Zhdan }
2144bb352b6eSEgor Zhdan 
2145bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProperty(ContextID CtxID, llvm::StringRef Name,
2146bb352b6eSEgor Zhdan                                         bool IsInstance)
2147bb352b6eSEgor Zhdan     -> VersionedInfo<ObjCPropertyInfo> {
2148bb352b6eSEgor Zhdan   if (!Implementation->ObjCPropertyTable)
2149bb352b6eSEgor Zhdan     return std::nullopt;
2150bb352b6eSEgor Zhdan 
2151bb352b6eSEgor Zhdan   std::optional<IdentifierID> PropertyID = Implementation->getIdentifier(Name);
2152bb352b6eSEgor Zhdan   if (!PropertyID)
2153bb352b6eSEgor Zhdan     return std::nullopt;
2154bb352b6eSEgor Zhdan 
2155bb352b6eSEgor Zhdan   auto Known = Implementation->ObjCPropertyTable->find(
2156bb352b6eSEgor Zhdan       std::make_tuple(CtxID.Value, *PropertyID, (char)IsInstance));
2157bb352b6eSEgor Zhdan   if (Known == Implementation->ObjCPropertyTable->end())
2158bb352b6eSEgor Zhdan     return std::nullopt;
2159bb352b6eSEgor Zhdan 
2160bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2161bb352b6eSEgor Zhdan }
2162bb352b6eSEgor Zhdan 
2163bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
2164bb352b6eSEgor Zhdan                                       bool IsInstanceMethod)
2165bb352b6eSEgor Zhdan     -> VersionedInfo<ObjCMethodInfo> {
2166bb352b6eSEgor Zhdan   if (!Implementation->ObjCMethodTable)
2167bb352b6eSEgor Zhdan     return std::nullopt;
2168bb352b6eSEgor Zhdan 
2169bb352b6eSEgor Zhdan   std::optional<SelectorID> SelID = Implementation->getSelector(Selector);
2170bb352b6eSEgor Zhdan   if (!SelID)
2171bb352b6eSEgor Zhdan     return std::nullopt;
2172bb352b6eSEgor Zhdan 
2173bb352b6eSEgor Zhdan   auto Known = Implementation->ObjCMethodTable->find(
2174bb352b6eSEgor Zhdan       ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
2175bb352b6eSEgor Zhdan                                              IsInstanceMethod});
2176bb352b6eSEgor Zhdan   if (Known == Implementation->ObjCMethodTable->end())
2177bb352b6eSEgor Zhdan     return std::nullopt;
2178bb352b6eSEgor Zhdan 
2179bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2180bb352b6eSEgor Zhdan }
2181bb352b6eSEgor Zhdan 
2182b8169771SEgor Zhdan auto APINotesReader::lookupField(ContextID CtxID, llvm::StringRef Name)
2183b8169771SEgor Zhdan     -> VersionedInfo<FieldInfo> {
2184b8169771SEgor Zhdan   if (!Implementation->FieldTable)
2185b8169771SEgor Zhdan     return std::nullopt;
2186b8169771SEgor Zhdan 
2187b8169771SEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2188b8169771SEgor Zhdan   if (!NameID)
2189b8169771SEgor Zhdan     return std::nullopt;
2190b8169771SEgor Zhdan 
2191b8169771SEgor Zhdan   auto Known = Implementation->FieldTable->find(
2192b8169771SEgor Zhdan       SingleDeclTableKey(CtxID.Value, *NameID));
2193b8169771SEgor Zhdan   if (Known == Implementation->FieldTable->end())
2194b8169771SEgor Zhdan     return std::nullopt;
2195b8169771SEgor Zhdan 
2196b8169771SEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2197b8169771SEgor Zhdan }
2198b8169771SEgor Zhdan 
21998a79dc7eSEgor Zhdan auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
22008a79dc7eSEgor Zhdan     -> VersionedInfo<CXXMethodInfo> {
22018a79dc7eSEgor Zhdan   if (!Implementation->CXXMethodTable)
22028a79dc7eSEgor Zhdan     return std::nullopt;
22038a79dc7eSEgor Zhdan 
22048a79dc7eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
22058a79dc7eSEgor Zhdan   if (!NameID)
22068a79dc7eSEgor Zhdan     return std::nullopt;
22078a79dc7eSEgor Zhdan 
22088a79dc7eSEgor Zhdan   auto Known = Implementation->CXXMethodTable->find(
22098a79dc7eSEgor Zhdan       SingleDeclTableKey(CtxID.Value, *NameID));
22108a79dc7eSEgor Zhdan   if (Known == Implementation->CXXMethodTable->end())
22118a79dc7eSEgor Zhdan     return std::nullopt;
22128a79dc7eSEgor Zhdan 
22138a79dc7eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
22148a79dc7eSEgor Zhdan }
22158a79dc7eSEgor Zhdan 
2216bb352b6eSEgor Zhdan auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name,
2217bb352b6eSEgor Zhdan                                           std::optional<Context> Ctx)
2218bb352b6eSEgor Zhdan     -> VersionedInfo<GlobalVariableInfo> {
2219bb352b6eSEgor Zhdan   if (!Implementation->GlobalVariableTable)
2220bb352b6eSEgor Zhdan     return std::nullopt;
2221bb352b6eSEgor Zhdan 
2222bb352b6eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2223bb352b6eSEgor Zhdan   if (!NameID)
2224bb352b6eSEgor Zhdan     return std::nullopt;
2225bb352b6eSEgor Zhdan 
2226c5f402f9SEgor Zhdan   SingleDeclTableKey Key(Ctx, *NameID);
2227bb352b6eSEgor Zhdan 
2228bb352b6eSEgor Zhdan   auto Known = Implementation->GlobalVariableTable->find(Key);
2229bb352b6eSEgor Zhdan   if (Known == Implementation->GlobalVariableTable->end())
2230bb352b6eSEgor Zhdan     return std::nullopt;
2231bb352b6eSEgor Zhdan 
2232bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2233bb352b6eSEgor Zhdan }
2234bb352b6eSEgor Zhdan 
2235bb352b6eSEgor Zhdan auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name,
2236bb352b6eSEgor Zhdan                                           std::optional<Context> Ctx)
2237bb352b6eSEgor Zhdan     -> VersionedInfo<GlobalFunctionInfo> {
2238bb352b6eSEgor Zhdan   if (!Implementation->GlobalFunctionTable)
2239bb352b6eSEgor Zhdan     return std::nullopt;
2240bb352b6eSEgor Zhdan 
2241bb352b6eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2242bb352b6eSEgor Zhdan   if (!NameID)
2243bb352b6eSEgor Zhdan     return std::nullopt;
2244bb352b6eSEgor Zhdan 
2245c5f402f9SEgor Zhdan   SingleDeclTableKey Key(Ctx, *NameID);
2246bb352b6eSEgor Zhdan 
2247bb352b6eSEgor Zhdan   auto Known = Implementation->GlobalFunctionTable->find(Key);
2248bb352b6eSEgor Zhdan   if (Known == Implementation->GlobalFunctionTable->end())
2249bb352b6eSEgor Zhdan     return std::nullopt;
2250bb352b6eSEgor Zhdan 
2251bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2252bb352b6eSEgor Zhdan }
2253bb352b6eSEgor Zhdan 
2254bb352b6eSEgor Zhdan auto APINotesReader::lookupEnumConstant(llvm::StringRef Name)
2255bb352b6eSEgor Zhdan     -> VersionedInfo<EnumConstantInfo> {
2256bb352b6eSEgor Zhdan   if (!Implementation->EnumConstantTable)
2257bb352b6eSEgor Zhdan     return std::nullopt;
2258bb352b6eSEgor Zhdan 
2259bb352b6eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2260bb352b6eSEgor Zhdan   if (!NameID)
2261bb352b6eSEgor Zhdan     return std::nullopt;
2262bb352b6eSEgor Zhdan 
2263bb352b6eSEgor Zhdan   auto Known = Implementation->EnumConstantTable->find(*NameID);
2264bb352b6eSEgor Zhdan   if (Known == Implementation->EnumConstantTable->end())
2265bb352b6eSEgor Zhdan     return std::nullopt;
2266bb352b6eSEgor Zhdan 
2267bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2268bb352b6eSEgor Zhdan }
2269bb352b6eSEgor Zhdan 
22708a79dc7eSEgor Zhdan auto APINotesReader::lookupTagID(llvm::StringRef Name,
22718a79dc7eSEgor Zhdan                                  std::optional<Context> ParentCtx)
22728a79dc7eSEgor Zhdan     -> std::optional<ContextID> {
22738a79dc7eSEgor Zhdan   if (!Implementation->ContextIDTable)
22748a79dc7eSEgor Zhdan     return std::nullopt;
22758a79dc7eSEgor Zhdan 
22768a79dc7eSEgor Zhdan   std::optional<IdentifierID> TagID = Implementation->getIdentifier(Name);
22778a79dc7eSEgor Zhdan   if (!TagID)
22788a79dc7eSEgor Zhdan     return std::nullopt;
22798a79dc7eSEgor Zhdan 
22808a79dc7eSEgor Zhdan   auto KnownID = Implementation->ContextIDTable->find(
22818a79dc7eSEgor Zhdan       ContextTableKey(ParentCtx, ContextKind::Tag, *TagID));
22828a79dc7eSEgor Zhdan   if (KnownID == Implementation->ContextIDTable->end())
22838a79dc7eSEgor Zhdan     return std::nullopt;
22848a79dc7eSEgor Zhdan 
22858a79dc7eSEgor Zhdan   return ContextID(*KnownID);
22868a79dc7eSEgor Zhdan }
22878a79dc7eSEgor Zhdan 
2288bb352b6eSEgor Zhdan auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional<Context> Ctx)
2289bb352b6eSEgor Zhdan     -> VersionedInfo<TagInfo> {
2290bb352b6eSEgor Zhdan   if (!Implementation->TagTable)
2291bb352b6eSEgor Zhdan     return std::nullopt;
2292bb352b6eSEgor Zhdan 
2293bb352b6eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2294bb352b6eSEgor Zhdan   if (!NameID)
2295bb352b6eSEgor Zhdan     return std::nullopt;
2296bb352b6eSEgor Zhdan 
2297c5f402f9SEgor Zhdan   SingleDeclTableKey Key(Ctx, *NameID);
2298bb352b6eSEgor Zhdan 
2299bb352b6eSEgor Zhdan   auto Known = Implementation->TagTable->find(Key);
2300bb352b6eSEgor Zhdan   if (Known == Implementation->TagTable->end())
2301bb352b6eSEgor Zhdan     return std::nullopt;
2302bb352b6eSEgor Zhdan 
2303bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2304bb352b6eSEgor Zhdan }
2305bb352b6eSEgor Zhdan 
2306bb352b6eSEgor Zhdan auto APINotesReader::lookupTypedef(llvm::StringRef Name,
2307bb352b6eSEgor Zhdan                                    std::optional<Context> Ctx)
2308bb352b6eSEgor Zhdan     -> VersionedInfo<TypedefInfo> {
2309bb352b6eSEgor Zhdan   if (!Implementation->TypedefTable)
2310bb352b6eSEgor Zhdan     return std::nullopt;
2311bb352b6eSEgor Zhdan 
2312bb352b6eSEgor Zhdan   std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
2313bb352b6eSEgor Zhdan   if (!NameID)
2314bb352b6eSEgor Zhdan     return std::nullopt;
2315bb352b6eSEgor Zhdan 
2316c5f402f9SEgor Zhdan   SingleDeclTableKey Key(Ctx, *NameID);
2317bb352b6eSEgor Zhdan 
2318bb352b6eSEgor Zhdan   auto Known = Implementation->TypedefTable->find(Key);
2319bb352b6eSEgor Zhdan   if (Known == Implementation->TypedefTable->end())
2320bb352b6eSEgor Zhdan     return std::nullopt;
2321bb352b6eSEgor Zhdan 
2322bb352b6eSEgor Zhdan   return {Implementation->SwiftVersion, *Known};
2323bb352b6eSEgor Zhdan }
2324bb352b6eSEgor Zhdan 
2325bb352b6eSEgor Zhdan auto APINotesReader::lookupNamespaceID(
2326bb352b6eSEgor Zhdan     llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2327bb352b6eSEgor Zhdan     -> std::optional<ContextID> {
232882ee7ae3SEgor Zhdan   if (!Implementation->ContextIDTable)
2329bb352b6eSEgor Zhdan     return std::nullopt;
2330bb352b6eSEgor Zhdan 
2331bb352b6eSEgor Zhdan   std::optional<IdentifierID> NamespaceID = Implementation->getIdentifier(Name);
2332bb352b6eSEgor Zhdan   if (!NamespaceID)
2333bb352b6eSEgor Zhdan     return std::nullopt;
2334bb352b6eSEgor Zhdan 
2335bb352b6eSEgor Zhdan   uint32_t RawParentNamespaceID =
2336bb352b6eSEgor Zhdan       ParentNamespaceID ? ParentNamespaceID->Value : -1;
233782ee7ae3SEgor Zhdan   auto KnownID = Implementation->ContextIDTable->find(
2338bb352b6eSEgor Zhdan       {RawParentNamespaceID, (uint8_t)ContextKind::Namespace, *NamespaceID});
233982ee7ae3SEgor Zhdan   if (KnownID == Implementation->ContextIDTable->end())
2340bb352b6eSEgor Zhdan     return std::nullopt;
2341bb352b6eSEgor Zhdan 
2342bb352b6eSEgor Zhdan   return ContextID(*KnownID);
2343bb352b6eSEgor Zhdan }
2344bb352b6eSEgor Zhdan 
2345bb352b6eSEgor Zhdan } // namespace api_notes
2346bb352b6eSEgor Zhdan } // namespace clang
2347