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