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