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 27using namespace llvm; 28using namespace llvm::codeview; 29 30TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const { 31 return TypeIndex::fromArrayIndex(SeenRecords.size()); 32} 33 34AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage) 35 : RecordStorage(Storage) {} 36 37AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default; 38 39Optional<TypeIndex> AppendingTypeTableBuilder::getFirst() { 40 if (empty()) 41 return None; 42 43 return TypeIndex(TypeIndex::FirstNonSimpleIndex); 44} 45 46Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) { 47 if (++Prev == nextTypeIndex()) 48 return None; 49 return Prev; 50} 51 52CVType AppendingTypeTableBuilder::getType(TypeIndex Index){ 53 return CVType(SeenRecords[Index.toArrayIndex()]); 54} 55 56StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) { 57 llvm_unreachable("Method not implemented"); 58} 59 60bool AppendingTypeTableBuilder::contains(TypeIndex Index) { 61 if (Index.isSimple() || Index.isNoneType()) 62 return false; 63 64 return Index.toArrayIndex() < SeenRecords.size(); 65} 66 67uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); } 68 69uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); } 70 71ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const { 72 return SeenRecords; 73} 74 75void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } 76 77TypeIndex 78AppendingTypeTableBuilder::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 87TypeIndex 88AppendingTypeTableBuilder::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