| 670 | }; |
| 671 | |
| 672 | Expected<bool> |
| 673 | MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { |
| 674 | IndexCursor = Stream; |
| 675 | SmallVector<uint64_t, 64> Record; |
| 676 | // Get the abbrevs, and preload record positions to make them lazy-loadable. |
| 677 | while (true) { |
| 678 | BitstreamEntry Entry = IndexCursor.advanceSkippingSubblocks( |
| 679 | BitstreamCursor::AF_DontPopBlockAtEnd); |
| 680 | switch (Entry.Kind) { |
| 681 | case BitstreamEntry::SubBlock: // Handled for us already. |
| 682 | case BitstreamEntry::Error: |
| 683 | return error("Malformed block"); |
| 684 | case BitstreamEntry::EndBlock: { |
| 685 | return true; |
| 686 | } |
| 687 | case BitstreamEntry::Record: { |
| 688 | // The interesting case. |
| 689 | ++NumMDRecordLoaded; |
| 690 | uint64_t CurrentPos = IndexCursor.GetCurrentBitNo(); |
| 691 | auto Code = IndexCursor.skipRecord(Entry.ID); |
| 692 | switch (Code) { |
| 693 | case bitc::METADATA_STRINGS: { |
| 694 | // Rewind and parse the strings. |
| 695 | IndexCursor.JumpToBit(CurrentPos); |
| 696 | StringRef Blob; |
| 697 | Record.clear(); |
| 698 | IndexCursor.readRecord(Entry.ID, Record, &Blob); |
| 699 | unsigned NumStrings = Record[0]; |
| 700 | MDStringRef.reserve(NumStrings); |
| 701 | auto IndexNextMDString = [&](StringRef Str) { |
| 702 | MDStringRef.push_back(Str); |
| 703 | }; |
| 704 | if (auto Err = parseMetadataStrings(Record, Blob, IndexNextMDString)) |
| 705 | return std::move(Err); |
| 706 | break; |
| 707 | } |
| 708 | case bitc::METADATA_INDEX_OFFSET: { |
| 709 | // This is the offset to the index, when we see this we skip all the |
| 710 | // records and load only an index to these. |
| 711 | IndexCursor.JumpToBit(CurrentPos); |
| 712 | Record.clear(); |
| 713 | IndexCursor.readRecord(Entry.ID, Record); |
| 714 | if (Record.size() != 2) |
| 715 | return error("Invalid record"); |
| 716 | auto Offset = Record[0] + (Record[1] << 32); |
| 717 | auto BeginPos = IndexCursor.GetCurrentBitNo(); |
| 718 | IndexCursor.JumpToBit(BeginPos + Offset); |
| 719 | Entry = IndexCursor.advanceSkippingSubblocks( |
| 720 | BitstreamCursor::AF_DontPopBlockAtEnd); |
| 721 | assert(Entry.Kind == BitstreamEntry::Record && |
| 722 | "Corrupted bitcode: Expected `Record` when trying to find the " |
| 723 | "Metadata index"); |
| 724 | Record.clear(); |
| 725 | auto Code = IndexCursor.readRecord(Entry.ID, Record); |
| 726 | (void)Code; |
| 727 | assert(Code == bitc::METADATA_INDEX && "Corrupted bitcode: Expected " |
| 728 | "`METADATA_INDEX` when trying " |
| 729 | "to find the Metadata index"); |
nothing calls this directly
no test coverage detected