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