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