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