1 //===- AppendingTypeTableBuilder.cpp --------------------------------------===// 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 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h" 10 #include "llvm/ADT/ArrayRef.h" 11 #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" 12 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 13 #include "llvm/Support/Allocator.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include <cassert> 16 #include <cstdint> 17 #include <cstring> 18 19 using namespace llvm; 20 using namespace llvm::codeview; 21 22 TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const { 23 return TypeIndex::fromArrayIndex(SeenRecords.size()); 24 } 25 26 AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage) 27 : RecordStorage(Storage) {} 28 29 AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default; 30 31 std::optional<TypeIndex> AppendingTypeTableBuilder::getFirst() { 32 if (empty()) 33 return std::nullopt; 34 35 return TypeIndex(TypeIndex::FirstNonSimpleIndex); 36 } 37 38 std::optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) { 39 if (++Prev == nextTypeIndex()) 40 return std::nullopt; 41 return Prev; 42 } 43 44 CVType AppendingTypeTableBuilder::getType(TypeIndex Index){ 45 return CVType(SeenRecords[Index.toArrayIndex()]); 46 } 47 48 StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) { 49 llvm_unreachable("Method not implemented"); 50 } 51 52 bool AppendingTypeTableBuilder::contains(TypeIndex Index) { 53 if (Index.isSimple() || Index.isNoneType()) 54 return false; 55 56 return Index.toArrayIndex() < SeenRecords.size(); 57 } 58 59 uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); } 60 61 uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); } 62 63 ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const { 64 return SeenRecords; 65 } 66 67 void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } 68 69 static ArrayRef<uint8_t> stabilize(BumpPtrAllocator &RecordStorage, 70 ArrayRef<uint8_t> Record) { 71 uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); 72 memcpy(Stable, Record.data(), Record.size()); 73 return ArrayRef<uint8_t>(Stable, Record.size()); 74 } 75 76 TypeIndex 77 AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) { 78 TypeIndex NewTI = nextTypeIndex(); 79 Record = stabilize(RecordStorage, Record); 80 SeenRecords.push_back(Record); 81 return NewTI; 82 } 83 84 TypeIndex 85 AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { 86 TypeIndex TI; 87 auto Fragments = Builder.end(nextTypeIndex()); 88 assert(!Fragments.empty()); 89 for (auto C : Fragments) 90 TI = insertRecordBytes(C.RecordData); 91 return TI; 92 } 93 94 bool AppendingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data, 95 bool Stabilize) { 96 assert(Index.toArrayIndex() < SeenRecords.size() && 97 "This function cannot be used to insert records!"); 98 99 ArrayRef<uint8_t> Record = Data.data(); 100 if (Stabilize) 101 Record = stabilize(RecordStorage, Record); 102 SeenRecords[Index.toArrayIndex()] = Record; 103 return true; 104 } 105