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