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