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