1 //===- AppendingTypeTableBuilder.cpp --------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h" 11 #include "llvm/ADT/ArrayRef.h" 12 #include "llvm/ADT/DenseSet.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/DebugInfo/CodeView/CodeView.h" 15 #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" 16 #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 17 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 18 #include "llvm/Support/Allocator.h" 19 #include "llvm/Support/BinaryByteStream.h" 20 #include "llvm/Support/BinaryStreamWriter.h" 21 #include "llvm/Support/Endian.h" 22 #include "llvm/Support/Error.h" 23 #include <algorithm> 24 #include <cassert> 25 #include <cstdint> 26 #include <cstring> 27 28 using namespace llvm; 29 using namespace llvm::codeview; 30 nextTypeIndex() const31TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const { 32 return TypeIndex::fromArrayIndex(SeenRecords.size()); 33 } 34 AppendingTypeTableBuilder(BumpPtrAllocator & Storage)35AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage) 36 : RecordStorage(Storage) {} 37 38 AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default; 39 getFirst()40Optional<TypeIndex> AppendingTypeTableBuilder::getFirst() { 41 if (empty()) 42 return None; 43 44 return TypeIndex(TypeIndex::FirstNonSimpleIndex); 45 } 46 getNext(TypeIndex Prev)47Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) { 48 if (++Prev == nextTypeIndex()) 49 return None; 50 return Prev; 51 } 52 getType(TypeIndex Index)53CVType AppendingTypeTableBuilder::getType(TypeIndex Index) { 54 CVType Type; 55 Type.RecordData = SeenRecords[Index.toArrayIndex()]; 56 const RecordPrefix *P = 57 reinterpret_cast<const RecordPrefix *>(Type.RecordData.data()); 58 Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind)); 59 return Type; 60 } 61 getTypeName(TypeIndex Index)62StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) { 63 llvm_unreachable("Method not implemented"); 64 } 65 contains(TypeIndex Index)66bool AppendingTypeTableBuilder::contains(TypeIndex Index) { 67 if (Index.isSimple() || Index.isNoneType()) 68 return false; 69 70 return Index.toArrayIndex() < SeenRecords.size(); 71 } 72 size()73uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); } 74 capacity()75uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); } 76 records() const77ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const { 78 return SeenRecords; 79 } 80 reset()81void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } 82 83 TypeIndex insertRecordBytes(ArrayRef<uint8_t> & Record)84AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) { 85 TypeIndex NewTI = nextTypeIndex(); 86 uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); 87 memcpy(Stable, Record.data(), Record.size()); 88 Record = ArrayRef<uint8_t>(Stable, Record.size()); 89 SeenRecords.push_back(Record); 90 return NewTI; 91 } 92 93 TypeIndex insertRecord(ContinuationRecordBuilder & Builder)94AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { 95 TypeIndex TI; 96 auto Fragments = Builder.end(nextTypeIndex()); 97 assert(!Fragments.empty()); 98 for (auto C : Fragments) 99 TI = insertRecordBytes(C.RecordData); 100 return TI; 101 } 102