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