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 llvm::Error readControlBlock(llvm::BitstreamCursor &Cursor,
786 llvm::SmallVectorImpl<uint64_t> &Scratch);
787 llvm::Error readIdentifierBlock(llvm::BitstreamCursor &Cursor,
788 llvm::SmallVectorImpl<uint64_t> &Scratch);
789 llvm::Error readContextBlock(llvm::BitstreamCursor &Cursor,
790 llvm::SmallVectorImpl<uint64_t> &Scratch);
791 llvm::Error readObjCPropertyBlock(llvm::BitstreamCursor &Cursor,
792 llvm::SmallVectorImpl<uint64_t> &Scratch);
793 llvm::Error readObjCMethodBlock(llvm::BitstreamCursor &Cursor,
794 llvm::SmallVectorImpl<uint64_t> &Scratch);
795 llvm::Error readCXXMethodBlock(llvm::BitstreamCursor &Cursor,
796 llvm::SmallVectorImpl<uint64_t> &Scratch);
797 llvm::Error readFieldBlock(llvm::BitstreamCursor &Cursor,
798 llvm::SmallVectorImpl<uint64_t> &Scratch);
799 llvm::Error readObjCSelectorBlock(llvm::BitstreamCursor &Cursor,
800 llvm::SmallVectorImpl<uint64_t> &Scratch);
801 llvm::Error readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
802 llvm::SmallVectorImpl<uint64_t> &Scratch);
803 llvm::Error readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor,
804 llvm::SmallVectorImpl<uint64_t> &Scratch);
805 llvm::Error readEnumConstantBlock(llvm::BitstreamCursor &Cursor,
806 llvm::SmallVectorImpl<uint64_t> &Scratch);
807 llvm::Error readTagBlock(llvm::BitstreamCursor &Cursor,
808 llvm::SmallVectorImpl<uint64_t> &Scratch);
809 llvm::Error 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
851llvm::Error APINotesReader::Implementation::readControlBlock(
852 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
853 if (Cursor.EnterSubBlock(BlockID: CONTROL_BLOCK_ID))
854 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
855 S: "Failed to enter control block");
856
857 bool SawMetadata = false;
858
859 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
860 if (!MaybeNext)
861 return MaybeNext.takeError();
862
863 llvm::BitstreamEntry Next = MaybeNext.get();
864
865 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
866 if (Next.Kind == llvm::BitstreamEntry::Error)
867 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
868 S: "Malformed bitstream entry");
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 llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
875 S: "Failed to skip sub-block");
876
877 MaybeNext = Cursor.advance();
878 if (!MaybeNext)
879 return MaybeNext.takeError();
880
881 Next = MaybeNext.get();
882 continue;
883 }
884
885 Scratch.clear();
886 llvm::StringRef BlobData;
887 llvm::Expected<unsigned> MaybeKind =
888 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
889 if (!MaybeKind) {
890 return MaybeKind.takeError();
891 }
892 unsigned Kind = MaybeKind.get();
893
894 switch (Kind) {
895 case control_block::METADATA:
896 // Already saw metadata.
897 if (SawMetadata)
898 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
899 S: "Multiple metadata records found");
900
901 if (Scratch[0] != VERSION_MAJOR || Scratch[1] != VERSION_MINOR)
902 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
903 S: "Version mismatch in API Notes");
904
905 SawMetadata = true;
906 break;
907
908 case control_block::MODULE_NAME:
909 ModuleName = BlobData.str();
910 break;
911
912 case control_block::MODULE_OPTIONS:
913 break;
914
915 case control_block::SOURCE_FILE:
916 SourceFileSizeAndModTime = {Scratch[0], Scratch[1]};
917 break;
918
919 default:
920 // Unknown metadata record, possibly for use by a future version of the
921 // module format.
922 break;
923 }
924
925 MaybeNext = Cursor.advance();
926 if (!MaybeNext)
927 return MaybeNext.takeError();
928
929 Next = MaybeNext.get();
930 }
931
932 if (!SawMetadata)
933 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
934 S: "Missing metadata record");
935
936 return llvm::Error::success();
937}
938
939llvm::Error APINotesReader::Implementation::readIdentifierBlock(
940 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
941 if (Cursor.EnterSubBlock(BlockID: IDENTIFIER_BLOCK_ID))
942 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
943 S: "Failed to enter identifier block");
944
945 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
946 if (!MaybeNext)
947 return MaybeNext.takeError();
948
949 llvm::BitstreamEntry Next = MaybeNext.get();
950
951 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
952 if (Next.Kind == llvm::BitstreamEntry::Error)
953 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
954 S: "Malformed bitstream entry");
955
956 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
957 // Unknown sub-block, possibly for use by a future version of the
958 // API notes format.
959 if (Cursor.SkipBlock())
960 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
961 S: "Failed to skip sub-block");
962
963 MaybeNext = Cursor.advance();
964 if (!MaybeNext)
965 return MaybeNext.takeError();
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 return MaybeKind.takeError();
977 }
978 unsigned Kind = MaybeKind.get();
979 switch (Kind) {
980 case identifier_block::IDENTIFIER_DATA: {
981 // Already saw identifier table.
982 if (IdentifierTable)
983 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
984 S: "Multiple identifier records found");
985
986 uint32_t tableOffset;
987 identifier_block::IdentifierDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
988 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
989
990 IdentifierTable.reset(p: SerializedIdentifierTable::Create(
991 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
992 break;
993 }
994
995 default:
996 // Unknown record, possibly for use by a future version of the
997 // module format.
998 break;
999 }
1000
1001 MaybeNext = Cursor.advance();
1002 if (!MaybeNext)
1003 return MaybeNext.takeError();
1004
1005 Next = MaybeNext.get();
1006 }
1007
1008 return llvm::Error::success();
1009}
1010
1011llvm::Error APINotesReader::Implementation::readContextBlock(
1012 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1013 if (Cursor.EnterSubBlock(BlockID: OBJC_CONTEXT_BLOCK_ID))
1014 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1015 S: "Failed to enter Objective-C context block");
1016
1017 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1018 if (!MaybeNext)
1019 return MaybeNext.takeError();
1020
1021 llvm::BitstreamEntry Next = MaybeNext.get();
1022
1023 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1024 if (Next.Kind == llvm::BitstreamEntry::Error)
1025 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1026 S: "Malformed bitstream entry");
1027
1028 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1029 // Unknown sub-block, possibly for use by a future version of the
1030 // API notes format.
1031 if (Cursor.SkipBlock())
1032 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1033 S: "Failed to skip sub-block");
1034
1035 MaybeNext = Cursor.advance();
1036 if (!MaybeNext)
1037 return MaybeNext.takeError();
1038
1039 Next = MaybeNext.get();
1040 continue;
1041 }
1042
1043 Scratch.clear();
1044 llvm::StringRef BlobData;
1045 llvm::Expected<unsigned> MaybeKind =
1046 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1047 if (!MaybeKind) {
1048 return MaybeKind.takeError();
1049 }
1050 unsigned Kind = MaybeKind.get();
1051 switch (Kind) {
1052 case context_block::CONTEXT_ID_DATA: {
1053 // Already saw Objective-C / C++ context ID table.
1054 if (ContextIDTable)
1055 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1056 S: "Multiple context ID records found");
1057
1058 uint32_t tableOffset;
1059 context_block::ContextIDLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1060 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1061
1062 ContextIDTable.reset(p: SerializedContextIDTable::Create(
1063 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1064 break;
1065 }
1066
1067 case context_block::CONTEXT_INFO_DATA: {
1068 // Already saw Objective-C / C++ context info table.
1069 if (ContextInfoTable)
1070 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1071 S: "Multiple context info records found");
1072
1073 uint32_t tableOffset;
1074 context_block::ContextInfoLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1075 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1076
1077 ContextInfoTable.reset(p: SerializedContextInfoTable::Create(
1078 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1079 break;
1080 }
1081
1082 default:
1083 // Unknown record, possibly for use by a future version of the
1084 // module format.
1085 break;
1086 }
1087
1088 MaybeNext = Cursor.advance();
1089 if (!MaybeNext)
1090 return MaybeNext.takeError();
1091
1092 Next = MaybeNext.get();
1093 }
1094
1095 return llvm::Error::success();
1096}
1097
1098llvm::Error APINotesReader::Implementation::readObjCPropertyBlock(
1099 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1100 if (Cursor.EnterSubBlock(BlockID: OBJC_PROPERTY_BLOCK_ID))
1101 return llvm::createStringError(
1102 EC: llvm::inconvertibleErrorCode(),
1103 S: "Failed to enter Objective-C property block");
1104
1105 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1106 if (!MaybeNext)
1107 return MaybeNext.takeError();
1108
1109 llvm::BitstreamEntry Next = MaybeNext.get();
1110
1111 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1112 if (Next.Kind == llvm::BitstreamEntry::Error)
1113 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1114 S: "Malformed bitstream entry");
1115
1116 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1117 // Unknown sub-block, possibly for use by a future version of the
1118 // API notes format.
1119 if (Cursor.SkipBlock())
1120 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1121 S: "Failed to skip sub-block");
1122
1123 MaybeNext = Cursor.advance();
1124 if (!MaybeNext)
1125 return MaybeNext.takeError();
1126
1127 Next = MaybeNext.get();
1128 continue;
1129 }
1130
1131 Scratch.clear();
1132 llvm::StringRef BlobData;
1133 llvm::Expected<unsigned> MaybeKind =
1134 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1135 if (!MaybeKind) {
1136 return MaybeKind.takeError();
1137 }
1138 unsigned Kind = MaybeKind.get();
1139 switch (Kind) {
1140 case objc_property_block::OBJC_PROPERTY_DATA: {
1141 // Already saw Objective-C property table.
1142 if (ObjCPropertyTable)
1143 return llvm::createStringError(
1144 EC: llvm::inconvertibleErrorCode(),
1145 S: "Multiple Objective-C property records found");
1146
1147 uint32_t tableOffset;
1148 objc_property_block::ObjCPropertyDataLayout::readRecord(buffer&: Scratch,
1149 data&: tableOffset);
1150 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1151
1152 ObjCPropertyTable.reset(p: SerializedObjCPropertyTable::Create(
1153 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1154 break;
1155 }
1156
1157 default:
1158 // Unknown record, possibly for use by a future version of the
1159 // module format.
1160 break;
1161 }
1162
1163 MaybeNext = Cursor.advance();
1164 if (!MaybeNext)
1165 return MaybeNext.takeError();
1166
1167 Next = MaybeNext.get();
1168 }
1169
1170 return llvm::Error::success();
1171}
1172
1173llvm::Error APINotesReader::Implementation::readObjCMethodBlock(
1174 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1175 if (Cursor.EnterSubBlock(BlockID: OBJC_METHOD_BLOCK_ID))
1176 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1177 S: "Failed to enter Objective-C method block");
1178
1179 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1180 if (!MaybeNext)
1181 return MaybeNext.takeError();
1182
1183 llvm::BitstreamEntry Next = MaybeNext.get();
1184 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1185 if (Next.Kind == llvm::BitstreamEntry::Error)
1186 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1187 S: "Malformed bitstream entry");
1188
1189 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1190 // Unknown sub-block, possibly for use by a future version of the
1191 // API notes format.
1192 if (Cursor.SkipBlock())
1193 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1194 S: "Failed to skip sub-block");
1195
1196 MaybeNext = Cursor.advance();
1197 if (!MaybeNext)
1198 return MaybeNext.takeError();
1199
1200 Next = MaybeNext.get();
1201 continue;
1202 }
1203
1204 Scratch.clear();
1205 llvm::StringRef BlobData;
1206 llvm::Expected<unsigned> MaybeKind =
1207 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1208 if (!MaybeKind) {
1209 return MaybeKind.takeError();
1210 }
1211 unsigned Kind = MaybeKind.get();
1212 switch (Kind) {
1213 case objc_method_block::OBJC_METHOD_DATA: {
1214 // Already saw Objective-C method table.
1215 if (ObjCMethodTable)
1216 return llvm::createStringError(
1217 EC: llvm::inconvertibleErrorCode(),
1218 S: "Multiple Objective-C method records found");
1219
1220 uint32_t tableOffset;
1221 objc_method_block::ObjCMethodDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1222 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1223
1224 ObjCMethodTable.reset(p: SerializedObjCMethodTable::Create(
1225 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1226 break;
1227 }
1228
1229 default:
1230 // Unknown record, possibly for use by a future version of the
1231 // module format.
1232 break;
1233 }
1234
1235 MaybeNext = Cursor.advance();
1236 if (!MaybeNext)
1237 return MaybeNext.takeError();
1238
1239 Next = MaybeNext.get();
1240 }
1241
1242 return llvm::Error::success();
1243}
1244
1245llvm::Error APINotesReader::Implementation::readCXXMethodBlock(
1246 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1247 if (Cursor.EnterSubBlock(BlockID: CXX_METHOD_BLOCK_ID))
1248 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1249 S: "Failed to enter C++ method block");
1250
1251 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1252 if (!MaybeNext)
1253 return MaybeNext.takeError();
1254
1255 llvm::BitstreamEntry Next = MaybeNext.get();
1256 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1257 if (Next.Kind == llvm::BitstreamEntry::Error)
1258 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1259 S: "Malformed bitstream entry");
1260
1261 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1262 // Unknown sub-block, possibly for use by a future version of the
1263 // API notes format.
1264 if (Cursor.SkipBlock())
1265 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1266 S: "Failed to skip sub-block");
1267
1268 MaybeNext = Cursor.advance();
1269 if (!MaybeNext)
1270 return MaybeNext.takeError();
1271
1272 Next = MaybeNext.get();
1273 continue;
1274 }
1275
1276 Scratch.clear();
1277 llvm::StringRef BlobData;
1278 llvm::Expected<unsigned> MaybeKind =
1279 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1280 if (!MaybeKind) {
1281 return MaybeKind.takeError();
1282 }
1283 unsigned Kind = MaybeKind.get();
1284 switch (Kind) {
1285 case cxx_method_block::CXX_METHOD_DATA: {
1286 // Already saw C++ method table.
1287 if (CXXMethodTable)
1288 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1289 S: "Multiple C++ method records found");
1290
1291 uint32_t tableOffset;
1292 cxx_method_block::CXXMethodDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1293 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1294
1295 CXXMethodTable.reset(p: SerializedCXXMethodTable::Create(
1296 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1297 break;
1298 }
1299
1300 default:
1301 // Unknown record, possibly for use by a future version of the
1302 // module format.
1303 break;
1304 }
1305
1306 MaybeNext = Cursor.advance();
1307 if (!MaybeNext)
1308 return MaybeNext.takeError();
1309
1310 Next = MaybeNext.get();
1311 }
1312
1313 return llvm::Error::success();
1314}
1315
1316llvm::Error APINotesReader::Implementation::readFieldBlock(
1317 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1318 if (Cursor.EnterSubBlock(BlockID: FIELD_BLOCK_ID))
1319 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1320 S: "Failed to enter field block");
1321
1322 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1323 if (!MaybeNext)
1324 return MaybeNext.takeError();
1325
1326 llvm::BitstreamEntry Next = MaybeNext.get();
1327 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1328 if (Next.Kind == llvm::BitstreamEntry::Error)
1329 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1330 S: "Malformed bitstream entry");
1331
1332 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1333 // Unknown sub-block, possibly for use by a future version of the
1334 // API notes format.
1335 if (Cursor.SkipBlock())
1336 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1337 S: "Failed to skip sub-block");
1338
1339 MaybeNext = Cursor.advance();
1340 if (!MaybeNext)
1341 return MaybeNext.takeError();
1342
1343 Next = MaybeNext.get();
1344 continue;
1345 }
1346
1347 Scratch.clear();
1348 llvm::StringRef BlobData;
1349 llvm::Expected<unsigned> MaybeKind =
1350 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1351 if (!MaybeKind) {
1352 return MaybeKind.takeError();
1353 }
1354 unsigned Kind = MaybeKind.get();
1355 switch (Kind) {
1356 case field_block::FIELD_DATA: {
1357 // Already saw field table.
1358 if (FieldTable)
1359 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1360 S: "Multiple field records found");
1361
1362 uint32_t tableOffset;
1363 field_block::FieldDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1364 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1365
1366 FieldTable.reset(p: SerializedFieldTable::Create(
1367 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1368 break;
1369 }
1370
1371 default:
1372 // Unknown record, possibly for use by a future version of the
1373 // module format.
1374 break;
1375 }
1376
1377 MaybeNext = Cursor.advance();
1378 if (!MaybeNext)
1379 return MaybeNext.takeError();
1380
1381 Next = MaybeNext.get();
1382 }
1383
1384 return llvm::Error::success();
1385}
1386
1387llvm::Error APINotesReader::Implementation::readObjCSelectorBlock(
1388 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1389 if (Cursor.EnterSubBlock(BlockID: OBJC_SELECTOR_BLOCK_ID))
1390 return llvm::createStringError(
1391 EC: llvm::inconvertibleErrorCode(),
1392 S: "Failed to enter Objective-C selector block");
1393
1394 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1395 if (!MaybeNext)
1396 return MaybeNext.takeError();
1397
1398 llvm::BitstreamEntry Next = MaybeNext.get();
1399 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1400 if (Next.Kind == llvm::BitstreamEntry::Error)
1401 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1402 S: "Malformed bitstream entry");
1403
1404 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1405 // Unknown sub-block, possibly for use by a future version of the
1406 // API notes format.
1407 if (Cursor.SkipBlock())
1408 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1409 S: "Failed to skip sub-block");
1410
1411 MaybeNext = Cursor.advance();
1412 if (!MaybeNext)
1413 return MaybeNext.takeError();
1414
1415 Next = MaybeNext.get();
1416 continue;
1417 }
1418
1419 Scratch.clear();
1420 llvm::StringRef BlobData;
1421 llvm::Expected<unsigned> MaybeKind =
1422 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1423 if (!MaybeKind) {
1424 return MaybeKind.takeError();
1425 }
1426 unsigned Kind = MaybeKind.get();
1427 switch (Kind) {
1428 case objc_selector_block::OBJC_SELECTOR_DATA: {
1429 // Already saw Objective-C selector table.
1430 if (ObjCSelectorTable)
1431 return llvm::createStringError(
1432 EC: llvm::inconvertibleErrorCode(),
1433 S: "Multiple Objective-C selector records found");
1434
1435 uint32_t tableOffset;
1436 objc_selector_block::ObjCSelectorDataLayout::readRecord(buffer&: Scratch,
1437 data&: tableOffset);
1438 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1439
1440 ObjCSelectorTable.reset(p: SerializedObjCSelectorTable::Create(
1441 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1442 break;
1443 }
1444
1445 default:
1446 // Unknown record, possibly for use by a future version of the
1447 // module format.
1448 break;
1449 }
1450
1451 MaybeNext = Cursor.advance();
1452 if (!MaybeNext)
1453 return MaybeNext.takeError();
1454
1455 Next = MaybeNext.get();
1456 }
1457
1458 return llvm::Error::success();
1459}
1460
1461llvm::Error APINotesReader::Implementation::readGlobalVariableBlock(
1462 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1463 if (Cursor.EnterSubBlock(BlockID: GLOBAL_VARIABLE_BLOCK_ID))
1464 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1465 S: "Failed to enter global variable block");
1466
1467 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1468 if (!MaybeNext)
1469 return MaybeNext.takeError();
1470
1471 llvm::BitstreamEntry Next = MaybeNext.get();
1472 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1473 if (Next.Kind == llvm::BitstreamEntry::Error)
1474 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1475 S: "Malformed bitstream entry");
1476
1477 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1478 // Unknown sub-block, possibly for use by a future version of the
1479 // API notes format.
1480 if (Cursor.SkipBlock())
1481 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1482 S: "Failed to skip sub-block");
1483
1484 MaybeNext = Cursor.advance();
1485 if (!MaybeNext)
1486 return MaybeNext.takeError();
1487
1488 Next = MaybeNext.get();
1489 continue;
1490 }
1491
1492 Scratch.clear();
1493 llvm::StringRef BlobData;
1494 llvm::Expected<unsigned> MaybeKind =
1495 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1496 if (!MaybeKind) {
1497 return MaybeKind.takeError();
1498 }
1499 unsigned Kind = MaybeKind.get();
1500 switch (Kind) {
1501 case global_variable_block::GLOBAL_VARIABLE_DATA: {
1502 // Already saw global variable table.
1503 if (GlobalVariableTable)
1504 return llvm::createStringError(
1505 EC: llvm::inconvertibleErrorCode(),
1506 S: "Multiple global variable records found");
1507
1508 uint32_t tableOffset;
1509 global_variable_block::GlobalVariableDataLayout::readRecord(buffer&: Scratch,
1510 data&: tableOffset);
1511 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1512
1513 GlobalVariableTable.reset(p: SerializedGlobalVariableTable::Create(
1514 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1515 break;
1516 }
1517
1518 default:
1519 // Unknown record, possibly for use by a future version of the
1520 // module format.
1521 break;
1522 }
1523
1524 MaybeNext = Cursor.advance();
1525 if (!MaybeNext)
1526 return MaybeNext.takeError();
1527
1528 Next = MaybeNext.get();
1529 }
1530
1531 return llvm::Error::success();
1532}
1533
1534llvm::Error APINotesReader::Implementation::readGlobalFunctionBlock(
1535 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1536 if (Cursor.EnterSubBlock(BlockID: GLOBAL_FUNCTION_BLOCK_ID))
1537 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1538 S: "Failed to enter global function block");
1539
1540 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1541 if (!MaybeNext)
1542 return MaybeNext.takeError();
1543
1544 llvm::BitstreamEntry Next = MaybeNext.get();
1545 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1546 if (Next.Kind == llvm::BitstreamEntry::Error)
1547 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1548 S: "Malformed bitstream entry");
1549
1550 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1551 // Unknown sub-block, possibly for use by a future version of the
1552 // API notes format.
1553 if (Cursor.SkipBlock())
1554 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1555 S: "Failed to skip sub-block");
1556
1557 MaybeNext = Cursor.advance();
1558 if (!MaybeNext)
1559 return MaybeNext.takeError();
1560
1561 Next = MaybeNext.get();
1562 continue;
1563 }
1564
1565 Scratch.clear();
1566 llvm::StringRef BlobData;
1567 llvm::Expected<unsigned> MaybeKind =
1568 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1569 if (!MaybeKind) {
1570 return MaybeKind.takeError();
1571 }
1572 unsigned Kind = MaybeKind.get();
1573 switch (Kind) {
1574 case global_function_block::GLOBAL_FUNCTION_DATA: {
1575 // Already saw global function table.
1576 if (GlobalFunctionTable)
1577 return llvm::createStringError(
1578 EC: llvm::inconvertibleErrorCode(),
1579 S: "Multiple global function records found");
1580
1581 uint32_t tableOffset;
1582 global_function_block::GlobalFunctionDataLayout::readRecord(buffer&: Scratch,
1583 data&: tableOffset);
1584 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1585
1586 GlobalFunctionTable.reset(p: SerializedGlobalFunctionTable::Create(
1587 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1588 break;
1589 }
1590
1591 default:
1592 // Unknown record, possibly for use by a future version of the
1593 // module format.
1594 break;
1595 }
1596
1597 MaybeNext = Cursor.advance();
1598 if (!MaybeNext)
1599 return MaybeNext.takeError();
1600
1601 Next = MaybeNext.get();
1602 }
1603
1604 return llvm::Error::success();
1605}
1606
1607llvm::Error APINotesReader::Implementation::readEnumConstantBlock(
1608 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1609 if (Cursor.EnterSubBlock(BlockID: ENUM_CONSTANT_BLOCK_ID))
1610 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1611 S: "Failed to enter enum constant block");
1612
1613 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1614 if (!MaybeNext)
1615 return MaybeNext.takeError();
1616
1617 llvm::BitstreamEntry Next = MaybeNext.get();
1618 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1619 if (Next.Kind == llvm::BitstreamEntry::Error)
1620 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1621 S: "Malformed bitstream entry");
1622
1623 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1624 // Unknown sub-block, possibly for use by a future version of the
1625 // API notes format.
1626 if (Cursor.SkipBlock())
1627 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1628 S: "Failed to skip sub-block");
1629
1630 MaybeNext = Cursor.advance();
1631 if (!MaybeNext)
1632 return MaybeNext.takeError();
1633
1634 Next = MaybeNext.get();
1635 continue;
1636 }
1637
1638 Scratch.clear();
1639 llvm::StringRef BlobData;
1640 llvm::Expected<unsigned> MaybeKind =
1641 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1642 if (!MaybeKind) {
1643 return MaybeKind.takeError();
1644 }
1645 unsigned Kind = MaybeKind.get();
1646 switch (Kind) {
1647 case enum_constant_block::ENUM_CONSTANT_DATA: {
1648 // Already saw enumerator table.
1649 if (EnumConstantTable)
1650 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1651 S: "Multiple enum constant records found");
1652
1653 uint32_t tableOffset;
1654 enum_constant_block::EnumConstantDataLayout::readRecord(buffer&: Scratch,
1655 data&: tableOffset);
1656 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1657
1658 EnumConstantTable.reset(p: SerializedEnumConstantTable::Create(
1659 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1660 break;
1661 }
1662
1663 default:
1664 // Unknown record, possibly for use by a future version of the
1665 // module format.
1666 break;
1667 }
1668
1669 MaybeNext = Cursor.advance();
1670 if (!MaybeNext)
1671 return MaybeNext.takeError();
1672
1673 Next = MaybeNext.get();
1674 }
1675
1676 return llvm::Error::success();
1677}
1678
1679llvm::Error APINotesReader::Implementation::readTagBlock(
1680 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1681 if (Cursor.EnterSubBlock(BlockID: TAG_BLOCK_ID))
1682 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1683 S: "Failed to enter tag block");
1684
1685 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1686 if (!MaybeNext)
1687 return MaybeNext.takeError();
1688
1689 llvm::BitstreamEntry Next = MaybeNext.get();
1690 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1691 if (Next.Kind == llvm::BitstreamEntry::Error)
1692 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1693 S: "Malformed bitstream entry");
1694
1695 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1696 // Unknown sub-block, possibly for use by a future version of the
1697 // API notes format.
1698 if (Cursor.SkipBlock())
1699 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1700 S: "Failed to skip sub-block");
1701
1702 MaybeNext = Cursor.advance();
1703 if (!MaybeNext)
1704 return MaybeNext.takeError();
1705
1706 Next = MaybeNext.get();
1707 continue;
1708 }
1709
1710 Scratch.clear();
1711 llvm::StringRef BlobData;
1712 llvm::Expected<unsigned> MaybeKind =
1713 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1714 if (!MaybeKind) {
1715 return MaybeKind.takeError();
1716 }
1717 unsigned Kind = MaybeKind.get();
1718 switch (Kind) {
1719 case tag_block::TAG_DATA: {
1720 // Already saw tag table.
1721 if (TagTable)
1722 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1723 S: "Multiple tag records found");
1724
1725 uint32_t tableOffset;
1726 tag_block::TagDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1727 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1728
1729 TagTable.reset(p: SerializedTagTable::Create(Buckets: base + tableOffset,
1730 Payload: base + sizeof(uint32_t), Base: base));
1731 break;
1732 }
1733
1734 default:
1735 // Unknown record, possibly for use by a future version of the
1736 // module format.
1737 break;
1738 }
1739
1740 MaybeNext = Cursor.advance();
1741 if (!MaybeNext)
1742 return MaybeNext.takeError();
1743
1744 Next = MaybeNext.get();
1745 }
1746
1747 return llvm::Error::success();
1748}
1749
1750llvm::Error APINotesReader::Implementation::readTypedefBlock(
1751 llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
1752 if (Cursor.EnterSubBlock(BlockID: TYPEDEF_BLOCK_ID))
1753 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1754 S: "Failed to enter typedef block");
1755
1756 llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
1757 if (!MaybeNext)
1758 return MaybeNext.takeError();
1759
1760 llvm::BitstreamEntry Next = MaybeNext.get();
1761 while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
1762 if (Next.Kind == llvm::BitstreamEntry::Error)
1763 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1764 S: "Malformed bitstream entry");
1765
1766 if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
1767 // Unknown sub-block, possibly for use by a future version of the
1768 // API notes format.
1769 if (Cursor.SkipBlock())
1770 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1771 S: "Failed to skip sub-block");
1772
1773 MaybeNext = Cursor.advance();
1774 if (!MaybeNext)
1775 return MaybeNext.takeError();
1776
1777 Next = MaybeNext.get();
1778 continue;
1779 }
1780
1781 Scratch.clear();
1782 llvm::StringRef BlobData;
1783 llvm::Expected<unsigned> MaybeKind =
1784 Cursor.readRecord(AbbrevID: Next.ID, Vals&: Scratch, Blob: &BlobData);
1785 if (!MaybeKind) {
1786 return MaybeKind.takeError();
1787 }
1788 unsigned Kind = MaybeKind.get();
1789 switch (Kind) {
1790 case typedef_block::TYPEDEF_DATA: {
1791 // Already saw typedef table.
1792 if (TypedefTable)
1793 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1794 S: "Multiple typedef records found");
1795
1796 uint32_t tableOffset;
1797 typedef_block::TypedefDataLayout::readRecord(buffer&: Scratch, data&: tableOffset);
1798 auto base = reinterpret_cast<const uint8_t *>(BlobData.data());
1799
1800 TypedefTable.reset(p: SerializedTypedefTable::Create(
1801 Buckets: base + tableOffset, Payload: base + sizeof(uint32_t), Base: base));
1802 break;
1803 }
1804
1805 default:
1806 // Unknown record, possibly for use by a future version of the
1807 // module format.
1808 break;
1809 }
1810
1811 MaybeNext = Cursor.advance();
1812 if (!MaybeNext)
1813 return MaybeNext.takeError();
1814
1815 Next = MaybeNext.get();
1816 }
1817
1818 return llvm::Error::success();
1819}
1820
1821APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1822 llvm::VersionTuple SwiftVersion,
1823 llvm::Error &Err)
1824 : Implementation(new class Implementation) {
1825
1826 // Initialize the input buffer.
1827 Implementation->InputBuffer = InputBuffer;
1828 Implementation->SwiftVersion = SwiftVersion;
1829 llvm::BitstreamCursor Cursor(*Implementation->InputBuffer);
1830
1831 // Validate signature.
1832 for (auto byte : API_NOTES_SIGNATURE) {
1833 if (Cursor.AtEndOfStream()) {
1834 Err = llvm::createStringError(
1835 EC: llvm::inconvertibleErrorCode(),
1836 S: "Unexpected end of stream while reading signature");
1837 return;
1838 }
1839 llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead =
1840 Cursor.Read(NumBits: 8);
1841 if (!maybeRead) {
1842 Err = maybeRead.takeError();
1843 return;
1844 }
1845 if (maybeRead.get() != byte) {
1846 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1847 S: "Invalid signature in API notes file");
1848 return;
1849 }
1850 }
1851
1852 // Look at all of the blocks.
1853 bool HasValidControlBlock = false;
1854 llvm::SmallVector<uint64_t, 64> Scratch;
1855 while (!Cursor.AtEndOfStream()) {
1856 llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry = Cursor.advance();
1857 if (!MaybeTopLevelEntry) {
1858 Err = MaybeTopLevelEntry.takeError();
1859 return;
1860 }
1861 llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
1862
1863 if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
1864 break;
1865
1866 switch (TopLevelEntry.ID) {
1867 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1868 if (!Cursor.ReadBlockInfoBlock()) {
1869 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1870 S: "Failed to read block info");
1871 return;
1872 }
1873 break;
1874
1875 case CONTROL_BLOCK_ID:
1876 // Only allow a single control block.
1877 if (HasValidControlBlock) {
1878 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1879 S: "Multiple control blocks found");
1880 return;
1881 }
1882 if (llvm::Error BlockErr =
1883 Implementation->readControlBlock(Cursor, Scratch)) {
1884 Err = std::move(BlockErr);
1885 return;
1886 }
1887 HasValidControlBlock = true;
1888 break;
1889
1890 case IDENTIFIER_BLOCK_ID:
1891 if (!HasValidControlBlock) {
1892 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1893 S: "Missing control block");
1894 return;
1895 }
1896 if (llvm::Error BlockErr =
1897 Implementation->readIdentifierBlock(Cursor, Scratch)) {
1898 Err = std::move(BlockErr);
1899 return;
1900 }
1901 break;
1902
1903 case OBJC_CONTEXT_BLOCK_ID:
1904 if (!HasValidControlBlock) {
1905 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1906 S: "Missing control block");
1907 return;
1908 }
1909 if (llvm::Error BlockErr =
1910 Implementation->readContextBlock(Cursor, Scratch)) {
1911 Err = std::move(BlockErr);
1912 return;
1913 }
1914 break;
1915
1916 case OBJC_PROPERTY_BLOCK_ID:
1917 if (!HasValidControlBlock) {
1918 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1919 S: "Missing control block");
1920 return;
1921 }
1922 if (llvm::Error BlockErr =
1923 Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
1924 Err = std::move(BlockErr);
1925 return;
1926 }
1927 break;
1928
1929 case OBJC_METHOD_BLOCK_ID:
1930 if (!HasValidControlBlock) {
1931 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1932 S: "Missing control block");
1933 return;
1934 }
1935 if (llvm::Error BlockErr =
1936 Implementation->readObjCMethodBlock(Cursor, Scratch)) {
1937 Err = std::move(BlockErr);
1938 return;
1939 }
1940 break;
1941
1942 case CXX_METHOD_BLOCK_ID:
1943 if (!HasValidControlBlock) {
1944 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1945 S: "Missing control block");
1946 return;
1947 }
1948 if (llvm::Error BlockErr =
1949 Implementation->readCXXMethodBlock(Cursor, Scratch)) {
1950 Err = std::move(BlockErr);
1951 return;
1952 }
1953 break;
1954
1955 case FIELD_BLOCK_ID:
1956 if (!HasValidControlBlock) {
1957 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1958 S: "Missing control block");
1959 return;
1960 }
1961 if (llvm::Error BlockErr =
1962 Implementation->readFieldBlock(Cursor, Scratch)) {
1963 Err = std::move(BlockErr);
1964 return;
1965 }
1966 break;
1967
1968 case OBJC_SELECTOR_BLOCK_ID:
1969 if (!HasValidControlBlock) {
1970 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1971 S: "Missing control block");
1972 return;
1973 }
1974 if (llvm::Error BlockErr =
1975 Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
1976 Err = std::move(BlockErr);
1977 return;
1978 }
1979 break;
1980
1981 case GLOBAL_VARIABLE_BLOCK_ID:
1982 if (!HasValidControlBlock) {
1983 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1984 S: "Missing control block");
1985 return;
1986 }
1987 if (llvm::Error BlockErr =
1988 Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
1989 Err = std::move(BlockErr);
1990 return;
1991 }
1992 break;
1993
1994 case GLOBAL_FUNCTION_BLOCK_ID:
1995 if (!HasValidControlBlock) {
1996 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1997 S: "Missing control block");
1998 return;
1999 }
2000 if (llvm::Error BlockErr =
2001 Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
2002 Err = std::move(BlockErr);
2003 return;
2004 }
2005 break;
2006
2007 case ENUM_CONSTANT_BLOCK_ID:
2008 if (!HasValidControlBlock) {
2009 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
2010 S: "Missing control block");
2011 return;
2012 }
2013 if (llvm::Error BlockErr =
2014 Implementation->readEnumConstantBlock(Cursor, Scratch)) {
2015 Err = std::move(BlockErr);
2016 return;
2017 }
2018 break;
2019
2020 case TAG_BLOCK_ID:
2021 if (!HasValidControlBlock) {
2022 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
2023 S: "Missing control block");
2024 return;
2025 }
2026 if (llvm::Error BlockErr =
2027 Implementation->readTagBlock(Cursor, Scratch)) {
2028 Err = std::move(BlockErr);
2029 return;
2030 }
2031 break;
2032
2033 case TYPEDEF_BLOCK_ID:
2034 if (!HasValidControlBlock) {
2035 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
2036 S: "Missing control block");
2037 return;
2038 }
2039 if (llvm::Error BlockErr =
2040 Implementation->readTypedefBlock(Cursor, Scratch)) {
2041 Err = std::move(BlockErr);
2042 return;
2043 }
2044 break;
2045
2046 default:
2047 // Unknown top-level block, possibly for use by a future version of the
2048 // module format.
2049 if (Cursor.SkipBlock()) {
2050 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
2051 S: "Failed to skip unknown top-level block");
2052 return;
2053 }
2054 break;
2055 }
2056 }
2057
2058 if (!Cursor.AtEndOfStream()) {
2059 Err = llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
2060 S: "Bitstream has unread data after all blocks");
2061 return;
2062 }
2063}
2064
2065APINotesReader::~APINotesReader() { delete Implementation->InputBuffer; }
2066
2067llvm::Expected<std::unique_ptr<APINotesReader>>
2068APINotesReader::Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
2069 llvm::VersionTuple SwiftVersion) {
2070 llvm::Error Err = llvm::Error::success();
2071 std::unique_ptr<APINotesReader> Reader(
2072 new APINotesReader(InputBuffer.release(), SwiftVersion, Err));
2073
2074 if (Err)
2075 return Err;
2076
2077 return std::move(Reader);
2078}
2079
2080template <typename T>
2081APINotesReader::VersionedInfo<T>::VersionedInfo(
2082 llvm::VersionTuple Version,
2083 llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> R)
2084 : Results(std::move(R)) {
2085
2086 assert(!Results.empty());
2087 assert(llvm::is_sorted(
2088 Results,
2089 [](const std::pair<llvm::VersionTuple, T> &left,
2090 const std::pair<llvm::VersionTuple, T> &right) -> bool {
2091 // The comparison function should be reflective, and with expensive
2092 // checks we can get callbacks basically checking that lambda(a,a) is
2093 // false. We could still check that we do not find equal elements when
2094 // left!=right.
2095 assert((&left == &right || left.first != right.first) &&
2096 "two entries for the same version");
2097 return left.first < right.first;
2098 }));
2099
2100 Selected = std::nullopt;
2101 for (unsigned i = 0, n = Results.size(); i != n; ++i) {
2102 if (!Version.empty() && Results[i].first >= Version) {
2103 // If the current version is "4", then entries for 4 are better than
2104 // entries for 5, but both are valid. Because entries are sorted, we get
2105 // that behavior by picking the first match.
2106 Selected = i;
2107 break;
2108 }
2109 }
2110
2111 // If we didn't find a match but we have an unversioned result, use the
2112 // unversioned result. This will always be the first entry because we encode
2113 // it as version 0.
2114 if (!Selected && Results[0].first.empty())
2115 Selected = 0;
2116}
2117
2118auto APINotesReader::lookupObjCClassID(llvm::StringRef Name)
2119 -> std::optional<ContextID> {
2120 if (!Implementation->ContextIDTable)
2121 return std::nullopt;
2122
2123 std::optional<IdentifierID> ClassID = Implementation->getIdentifier(Str: Name);
2124 if (!ClassID)
2125 return std::nullopt;
2126
2127 // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
2128 // context.
2129 auto KnownID = Implementation->ContextIDTable->find(
2130 EKey: ContextTableKey(-1, (uint8_t)ContextKind::ObjCClass, *ClassID));
2131 if (KnownID == Implementation->ContextIDTable->end())
2132 return std::nullopt;
2133
2134 return ContextID(*KnownID);
2135}
2136
2137auto APINotesReader::lookupObjCClassInfo(llvm::StringRef Name)
2138 -> VersionedInfo<ContextInfo> {
2139 if (!Implementation->ContextInfoTable)
2140 return std::nullopt;
2141
2142 std::optional<ContextID> CtxID = lookupObjCClassID(Name);
2143 if (!CtxID)
2144 return std::nullopt;
2145
2146 auto KnownInfo = Implementation->ContextInfoTable->find(EKey: CtxID->Value);
2147 if (KnownInfo == Implementation->ContextInfoTable->end())
2148 return std::nullopt;
2149
2150 return {Implementation->SwiftVersion, *KnownInfo};
2151}
2152
2153auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name)
2154 -> std::optional<ContextID> {
2155 if (!Implementation->ContextIDTable)
2156 return std::nullopt;
2157
2158 std::optional<IdentifierID> classID = Implementation->getIdentifier(Str: Name);
2159 if (!classID)
2160 return std::nullopt;
2161
2162 // ObjC classes can't be declared in C++ namespaces, so use -1 as the global
2163 // context.
2164 auto KnownID = Implementation->ContextIDTable->find(
2165 EKey: ContextTableKey(-1, (uint8_t)ContextKind::ObjCProtocol, *classID));
2166 if (KnownID == Implementation->ContextIDTable->end())
2167 return std::nullopt;
2168
2169 return ContextID(*KnownID);
2170}
2171
2172auto APINotesReader::lookupObjCProtocolInfo(llvm::StringRef Name)
2173 -> VersionedInfo<ContextInfo> {
2174 if (!Implementation->ContextInfoTable)
2175 return std::nullopt;
2176
2177 std::optional<ContextID> CtxID = lookupObjCProtocolID(Name);
2178 if (!CtxID)
2179 return std::nullopt;
2180
2181 auto KnownInfo = Implementation->ContextInfoTable->find(EKey: CtxID->Value);
2182 if (KnownInfo == Implementation->ContextInfoTable->end())
2183 return std::nullopt;
2184
2185 return {Implementation->SwiftVersion, *KnownInfo};
2186}
2187
2188auto APINotesReader::lookupObjCProperty(ContextID CtxID, llvm::StringRef Name,
2189 bool IsInstance)
2190 -> VersionedInfo<ObjCPropertyInfo> {
2191 if (!Implementation->ObjCPropertyTable)
2192 return std::nullopt;
2193
2194 std::optional<IdentifierID> PropertyID = Implementation->getIdentifier(Str: Name);
2195 if (!PropertyID)
2196 return std::nullopt;
2197
2198 auto Known = Implementation->ObjCPropertyTable->find(
2199 EKey: std::make_tuple(args&: CtxID.Value, args&: *PropertyID, args: (char)IsInstance));
2200 if (Known == Implementation->ObjCPropertyTable->end())
2201 return std::nullopt;
2202
2203 return {Implementation->SwiftVersion, *Known};
2204}
2205
2206auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
2207 bool IsInstanceMethod)
2208 -> VersionedInfo<ObjCMethodInfo> {
2209 if (!Implementation->ObjCMethodTable)
2210 return std::nullopt;
2211
2212 std::optional<SelectorID> SelID = Implementation->getSelector(Selector);
2213 if (!SelID)
2214 return std::nullopt;
2215
2216 auto Known = Implementation->ObjCMethodTable->find(
2217 EKey: ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
2218 IsInstanceMethod});
2219 if (Known == Implementation->ObjCMethodTable->end())
2220 return std::nullopt;
2221
2222 return {Implementation->SwiftVersion, *Known};
2223}
2224
2225auto APINotesReader::lookupField(ContextID CtxID, llvm::StringRef Name)
2226 -> VersionedInfo<FieldInfo> {
2227 if (!Implementation->FieldTable)
2228 return std::nullopt;
2229
2230 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2231 if (!NameID)
2232 return std::nullopt;
2233
2234 auto Known = Implementation->FieldTable->find(
2235 EKey: SingleDeclTableKey(CtxID.Value, *NameID));
2236 if (Known == Implementation->FieldTable->end())
2237 return std::nullopt;
2238
2239 return {Implementation->SwiftVersion, *Known};
2240}
2241
2242auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
2243 -> VersionedInfo<CXXMethodInfo> {
2244 if (!Implementation->CXXMethodTable)
2245 return std::nullopt;
2246
2247 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2248 if (!NameID)
2249 return std::nullopt;
2250
2251 auto Known = Implementation->CXXMethodTable->find(
2252 EKey: SingleDeclTableKey(CtxID.Value, *NameID));
2253 if (Known == Implementation->CXXMethodTable->end())
2254 return std::nullopt;
2255
2256 return {Implementation->SwiftVersion, *Known};
2257}
2258
2259auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name,
2260 std::optional<Context> Ctx)
2261 -> VersionedInfo<GlobalVariableInfo> {
2262 if (!Implementation->GlobalVariableTable)
2263 return std::nullopt;
2264
2265 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2266 if (!NameID)
2267 return std::nullopt;
2268
2269 SingleDeclTableKey Key(Ctx, *NameID);
2270
2271 auto Known = Implementation->GlobalVariableTable->find(EKey: Key);
2272 if (Known == Implementation->GlobalVariableTable->end())
2273 return std::nullopt;
2274
2275 return {Implementation->SwiftVersion, *Known};
2276}
2277
2278auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name,
2279 std::optional<Context> Ctx)
2280 -> VersionedInfo<GlobalFunctionInfo> {
2281 if (!Implementation->GlobalFunctionTable)
2282 return std::nullopt;
2283
2284 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2285 if (!NameID)
2286 return std::nullopt;
2287
2288 SingleDeclTableKey Key(Ctx, *NameID);
2289
2290 auto Known = Implementation->GlobalFunctionTable->find(EKey: Key);
2291 if (Known == Implementation->GlobalFunctionTable->end())
2292 return std::nullopt;
2293
2294 return {Implementation->SwiftVersion, *Known};
2295}
2296
2297auto APINotesReader::lookupEnumConstant(llvm::StringRef Name)
2298 -> VersionedInfo<EnumConstantInfo> {
2299 if (!Implementation->EnumConstantTable)
2300 return std::nullopt;
2301
2302 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2303 if (!NameID)
2304 return std::nullopt;
2305
2306 auto Known = Implementation->EnumConstantTable->find(EKey: *NameID);
2307 if (Known == Implementation->EnumConstantTable->end())
2308 return std::nullopt;
2309
2310 return {Implementation->SwiftVersion, *Known};
2311}
2312
2313auto APINotesReader::lookupTagID(llvm::StringRef Name,
2314 std::optional<Context> ParentCtx)
2315 -> std::optional<ContextID> {
2316 if (!Implementation->ContextIDTable)
2317 return std::nullopt;
2318
2319 std::optional<IdentifierID> TagID = Implementation->getIdentifier(Str: Name);
2320 if (!TagID)
2321 return std::nullopt;
2322
2323 auto KnownID = Implementation->ContextIDTable->find(
2324 EKey: ContextTableKey(ParentCtx, ContextKind::Tag, *TagID));
2325 if (KnownID == Implementation->ContextIDTable->end())
2326 return std::nullopt;
2327
2328 return ContextID(*KnownID);
2329}
2330
2331auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional<Context> Ctx)
2332 -> VersionedInfo<TagInfo> {
2333 if (!Implementation->TagTable)
2334 return std::nullopt;
2335
2336 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2337 if (!NameID)
2338 return std::nullopt;
2339
2340 SingleDeclTableKey Key(Ctx, *NameID);
2341
2342 auto Known = Implementation->TagTable->find(EKey: Key);
2343 if (Known == Implementation->TagTable->end())
2344 return std::nullopt;
2345
2346 return {Implementation->SwiftVersion, *Known};
2347}
2348
2349auto APINotesReader::lookupTypedef(llvm::StringRef Name,
2350 std::optional<Context> Ctx)
2351 -> VersionedInfo<TypedefInfo> {
2352 if (!Implementation->TypedefTable)
2353 return std::nullopt;
2354
2355 std::optional<IdentifierID> NameID = Implementation->getIdentifier(Str: Name);
2356 if (!NameID)
2357 return std::nullopt;
2358
2359 SingleDeclTableKey Key(Ctx, *NameID);
2360
2361 auto Known = Implementation->TypedefTable->find(EKey: Key);
2362 if (Known == Implementation->TypedefTable->end())
2363 return std::nullopt;
2364
2365 return {Implementation->SwiftVersion, *Known};
2366}
2367
2368auto APINotesReader::lookupNamespaceID(
2369 llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2370 -> std::optional<ContextID> {
2371 if (!Implementation->ContextIDTable)
2372 return std::nullopt;
2373
2374 std::optional<IdentifierID> NamespaceID = Implementation->getIdentifier(Str: Name);
2375 if (!NamespaceID)
2376 return std::nullopt;
2377
2378 uint32_t RawParentNamespaceID =
2379 ParentNamespaceID ? ParentNamespaceID->Value : -1;
2380 auto KnownID = Implementation->ContextIDTable->find(
2381 EKey: {RawParentNamespaceID, (uint8_t)ContextKind::Namespace, *NamespaceID});
2382 if (KnownID == Implementation->ContextIDTable->end())
2383 return std::nullopt;
2384
2385 return ContextID(*KnownID);
2386}
2387
2388} // namespace api_notes
2389} // namespace clang
2390