From ca6dbf1440e66f8a726cda3797c5e61b2376ec8d Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 30 Nov 2017 18:39:50 +0000 Subject: Split TypeTableBuilder into two classes. llvm-svn: 319456 --- .../CodeView/AppendingTypeTableBuilder.cpp | 101 ++++++++++ llvm/lib/DebugInfo/CodeView/CMakeLists.txt | 3 +- .../DebugInfo/CodeView/MergingTypeTableBuilder.cpp | 206 ++++++++++++++++++++ llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp | 30 +-- llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp | 215 --------------------- 5 files changed, 325 insertions(+), 230 deletions(-) create mode 100644 llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp create mode 100644 llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp delete mode 100644 llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp (limited to 'llvm/lib/DebugInfo') diff --git a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp new file mode 100644 index 00000000000..8828671d9be --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp @@ -0,0 +1,101 @@ +//===- AppendingTypeTableBuilder.cpp --------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include +#include +#include +#include + +using namespace llvm; +using namespace llvm::codeview; + +TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const { + return TypeIndex::fromArrayIndex(SeenRecords.size()); +} + +AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage) + : RecordStorage(Storage) {} + +AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default; + +Optional AppendingTypeTableBuilder::getFirst() { + if (empty()) + return None; + + return TypeIndex(TypeIndex::FirstNonSimpleIndex); +} + +Optional AppendingTypeTableBuilder::getNext(TypeIndex Prev) { + if (++Prev == nextTypeIndex()) + return None; + return Prev; +} + +CVType AppendingTypeTableBuilder::getType(TypeIndex Index) { + CVType Type; + Type.RecordData = SeenRecords[Index.toArrayIndex()]; + const RecordPrefix *P = + reinterpret_cast(Type.RecordData.data()); + Type.Type = static_cast(uint16_t(P->RecordKind)); + return Type; +} + +StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) { + llvm_unreachable("Method not implemented"); +} + +bool AppendingTypeTableBuilder::contains(TypeIndex Index) { + if (Index.isSimple() || Index.isNoneType()) + return false; + + return Index.toArrayIndex() < SeenRecords.size(); +} + +uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); } + +uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); } + +ArrayRef> AppendingTypeTableBuilder::records() const { + return SeenRecords; +} + +void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } + +TypeIndex +AppendingTypeTableBuilder::insertRecordBytes(ArrayRef &Record) { + TypeIndex NewTI = nextTypeIndex(); + uint8_t *Stable = RecordStorage.Allocate(Record.size()); + memcpy(Stable, Record.data(), Record.size()); + Record = ArrayRef(Stable, Record.size()); + SeenRecords.push_back(Record); + return NewTI; +} + +TypeIndex +AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { + TypeIndex TI; + auto Fragments = Builder.end(nextTypeIndex()); + assert(!Fragments.empty()); + for (auto C : Fragments) + TI = insertRecordBytes(C.RecordData); + return TI; +} diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt index 566ebaeae80..7d18c98bdc3 100644 --- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMDebugInfoCodeView + AppendingTypeTableBuilder.cpp CodeViewError.cpp CodeViewRecordIO.cpp ContinuationRecordBuilder.cpp @@ -20,6 +21,7 @@ add_llvm_library(LLVMDebugInfoCodeView Formatters.cpp LazyRandomTypeCollection.cpp Line.cpp + MergingTypeTableBuilder.cpp RecordName.cpp RecordSerialization.cpp SimpleTypeSerializer.cpp @@ -31,7 +33,6 @@ add_llvm_library(LLVMDebugInfoCodeView TypeIndex.cpp TypeIndexDiscovery.cpp TypeRecordMapping.cpp - TypeTableBuilder.cpp TypeStreamMerger.cpp TypeTableCollection.cpp diff --git a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp new file mode 100644 index 00000000000..6513f1fd739 --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp @@ -0,0 +1,206 @@ +//===- MergingTypeTableBuilder.cpp ----------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include +#include +#include +#include + +using namespace llvm; +using namespace llvm::codeview; + +namespace { + +struct HashedType { + hash_code Hash; + ArrayRef Data; + TypeIndex Index; +}; + +/// Wrapper around a poitner to a HashedType. Hash and equality operations are +/// based on data in the pointee. +struct HashedTypePtr { + HashedTypePtr() = default; + HashedTypePtr(HashedType *Ptr) : Ptr(Ptr) {} + + HashedType *Ptr = nullptr; +}; + +} // end anonymous namespace + +namespace llvm { + +template <> struct DenseMapInfo { + static inline HashedTypePtr getEmptyKey() { return HashedTypePtr(nullptr); } + + static inline HashedTypePtr getTombstoneKey() { + return HashedTypePtr(reinterpret_cast(1)); + } + + static unsigned getHashValue(HashedTypePtr Val) { + assert(Val.Ptr != getEmptyKey().Ptr && Val.Ptr != getTombstoneKey().Ptr); + return Val.Ptr->Hash; + } + + static bool isEqual(HashedTypePtr LHSP, HashedTypePtr RHSP) { + HashedType *LHS = LHSP.Ptr; + HashedType *RHS = RHSP.Ptr; + if (RHS == getEmptyKey().Ptr || RHS == getTombstoneKey().Ptr) + return LHS == RHS; + if (LHS->Hash != RHS->Hash) + return false; + return LHS->Data == RHS->Data; + } +}; + +} // end namespace llvm + +/// Private implementation so that we don't leak our DenseMap instantiations to +/// users. +class llvm::codeview::TypeHasher { +private: + /// Storage for type record provided by the caller. Records will outlive the + /// hasher object, so they should be allocated here. + BumpPtrAllocator &RecordStorage; + + /// Storage for hash keys. These only need to live as long as the hashing + /// operation. + BumpPtrAllocator KeyStorage; + + /// Hash table. We really want a DenseMap, TypeIndex> here, + /// but DenseMap is inefficient when the keys are long (like type records) + /// because it recomputes the hash value of every key when it grows. This + /// value type stores the hash out of line in KeyStorage, so that table + /// entries are small and easy to rehash. + DenseSet HashedRecords; + +public: + TypeHasher(BumpPtrAllocator &RecordStorage) : RecordStorage(RecordStorage) {} + + void reset() { HashedRecords.clear(); } + + /// Takes the bytes of type record, inserts them into the hash table, saves + /// them, and returns a pointer to an identical stable type record along with + /// its type index in the destination stream. + TypeIndex getOrCreateRecord(ArrayRef &Record, TypeIndex TI); +}; + +TypeIndex TypeHasher::getOrCreateRecord(ArrayRef &Record, + TypeIndex TI) { + assert(Record.size() < UINT32_MAX && "Record too big"); + assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); + + // Compute the hash up front so we can store it in the key. + HashedType TempHashedType = {hash_value(Record), Record, TI}; + auto Result = HashedRecords.insert(HashedTypePtr(&TempHashedType)); + HashedType *&Hashed = Result.first->Ptr; + + if (Result.second) { + // This was a new type record. We need stable storage for both the key and + // the record. The record should outlive the hashing operation. + Hashed = KeyStorage.Allocate(); + *Hashed = TempHashedType; + + uint8_t *Stable = RecordStorage.Allocate(Record.size()); + memcpy(Stable, Record.data(), Record.size()); + Hashed->Data = makeArrayRef(Stable, Record.size()); + } + + // Update the caller's copy of Record to point a stable copy. + Record = Hashed->Data; + return Hashed->Index; +} + +TypeIndex MergingTypeTableBuilder::nextTypeIndex() const { + return TypeIndex::fromArrayIndex(SeenRecords.size()); +} + +MergingTypeTableBuilder::MergingTypeTableBuilder(BumpPtrAllocator &Storage) + : RecordStorage(Storage) { + Hasher = llvm::make_unique(Storage); +} + +MergingTypeTableBuilder::~MergingTypeTableBuilder() = default; + +Optional MergingTypeTableBuilder::getFirst() { + if (empty()) + return None; + + return TypeIndex(TypeIndex::FirstNonSimpleIndex); +} + +Optional MergingTypeTableBuilder::getNext(TypeIndex Prev) { + if (++Prev == nextTypeIndex()) + return None; + return Prev; +} + +CVType MergingTypeTableBuilder::getType(TypeIndex Index) { + CVType Type; + Type.RecordData = SeenRecords[Index.toArrayIndex()]; + const RecordPrefix *P = + reinterpret_cast(Type.RecordData.data()); + Type.Type = static_cast(uint16_t(P->RecordKind)); + return Type; +} + +StringRef MergingTypeTableBuilder::getTypeName(TypeIndex Index) { + llvm_unreachable("Method not implemented"); +} + +bool MergingTypeTableBuilder::contains(TypeIndex Index) { + if (Index.isSimple() || Index.isNoneType()) + return false; + + return Index.toArrayIndex() < SeenRecords.size(); +} + +uint32_t MergingTypeTableBuilder::size() { return SeenRecords.size(); } + +uint32_t MergingTypeTableBuilder::capacity() { return SeenRecords.size(); } + +ArrayRef> MergingTypeTableBuilder::records() const { + return SeenRecords; +} + +void MergingTypeTableBuilder::reset() { + Hasher->reset(); + SeenRecords.clear(); +} + +TypeIndex +MergingTypeTableBuilder::insertRecordBytes(ArrayRef &Record) { + TypeIndex ActualTI = Hasher->getOrCreateRecord(Record, nextTypeIndex()); + if (nextTypeIndex() == ActualTI) + SeenRecords.push_back(Record); + return ActualTI; +} + +TypeIndex +MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { + TypeIndex TI; + auto Fragments = Builder.end(nextTypeIndex()); + assert(!Fragments.empty()); + for (auto C : Fragments) + TI = insertRecordBytes(C.RecordData); + return TI; +} diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index 465f01aab9d..5865ed97969 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -10,11 +10,11 @@ #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/Support/Error.h" #include "llvm/Support/ScopedPrinter.h" @@ -64,12 +64,14 @@ public: static const TypeIndex Untranslated; - Error mergeTypesAndIds(TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes, + Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds, + MergingTypeTableBuilder &DestTypes, const CVTypeArray &IdsAndTypes); - Error mergeIdRecords(TypeTableBuilder &Dest, + Error mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef TypeSourceToDest, const CVTypeArray &Ids); - Error mergeTypeRecords(TypeTableBuilder &Dest, const CVTypeArray &Types); + Error mergeTypeRecords(MergingTypeTableBuilder &Dest, + const CVTypeArray &Types); private: Error doit(const CVTypeArray &Types); @@ -106,8 +108,8 @@ private: TypeIndex CurIndex{TypeIndex::FirstNonSimpleIndex}; - TypeTableBuilder *DestIdStream = nullptr; - TypeTableBuilder *DestTypeStream = nullptr; + MergingTypeTableBuilder *DestIdStream = nullptr; + MergingTypeTableBuilder *DestTypeStream = nullptr; // If we're only mapping id records, this array contains the mapping for // type records. @@ -221,14 +223,14 @@ bool TypeStreamMerger::remapItemIndex(TypeIndex &Idx) { return remapIndex(Idx, IndexMap); } -Error TypeStreamMerger::mergeTypeRecords(TypeTableBuilder &Dest, +Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest, const CVTypeArray &Types) { DestTypeStream = &Dest; return doit(Types); } -Error TypeStreamMerger::mergeIdRecords(TypeTableBuilder &Dest, +Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef TypeSourceToDest, const CVTypeArray &Ids) { DestIdStream = &Dest; @@ -237,8 +239,8 @@ Error TypeStreamMerger::mergeIdRecords(TypeTableBuilder &Dest, return doit(Ids); } -Error TypeStreamMerger::mergeTypesAndIds(TypeTableBuilder &DestIds, - TypeTableBuilder &DestTypes, +Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds, + MergingTypeTableBuilder &DestTypes, const CVTypeArray &IdsAndTypes) { DestIdStream = &DestIds; DestTypeStream = &DestTypes; @@ -286,7 +288,7 @@ Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) { } Error TypeStreamMerger::remapType(const CVType &Type) { - TypeTableBuilder &Dest = + MergingTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; RemappedType R(Type); @@ -329,14 +331,14 @@ bool TypeStreamMerger::remapIndices(RemappedType &Record, return Success; } -Error llvm::codeview::mergeTypeRecords(TypeTableBuilder &Dest, +Error llvm::codeview::mergeTypeRecords(MergingTypeTableBuilder &Dest, SmallVectorImpl &SourceToDest, const CVTypeArray &Types) { TypeStreamMerger M(SourceToDest); return M.mergeTypeRecords(Dest, Types); } -Error llvm::codeview::mergeIdRecords(TypeTableBuilder &Dest, +Error llvm::codeview::mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef TypeSourceToDest, SmallVectorImpl &SourceToDest, const CVTypeArray &Ids) { @@ -345,7 +347,7 @@ Error llvm::codeview::mergeIdRecords(TypeTableBuilder &Dest, } Error llvm::codeview::mergeTypeAndIdRecords( - TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes, + MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, SmallVectorImpl &SourceToDest, const CVTypeArray &IdsAndTypes) { TypeStreamMerger M(SourceToDest); return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes); diff --git a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp deleted file mode 100644 index ad61b0b220b..00000000000 --- a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp +++ /dev/null @@ -1,215 +0,0 @@ -//===- TypeSerialzier.cpp -------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" -#include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/BinaryByteStream.h" -#include "llvm/Support/BinaryStreamWriter.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include -#include -#include -#include - -using namespace llvm; -using namespace llvm::codeview; - -namespace { - -struct HashedType { - hash_code Hash; - ArrayRef Data; - TypeIndex Index; -}; - -/// Wrapper around a poitner to a HashedType. Hash and equality operations are -/// based on data in the pointee. -struct HashedTypePtr { - HashedTypePtr() = default; - HashedTypePtr(HashedType *Ptr) : Ptr(Ptr) {} - - HashedType *Ptr = nullptr; -}; - -} // end anonymous namespace - -namespace llvm { - -template <> struct DenseMapInfo { - static inline HashedTypePtr getEmptyKey() { return HashedTypePtr(nullptr); } - - static inline HashedTypePtr getTombstoneKey() { - return HashedTypePtr(reinterpret_cast(1)); - } - - static unsigned getHashValue(HashedTypePtr Val) { - assert(Val.Ptr != getEmptyKey().Ptr && Val.Ptr != getTombstoneKey().Ptr); - return Val.Ptr->Hash; - } - - static bool isEqual(HashedTypePtr LHSP, HashedTypePtr RHSP) { - HashedType *LHS = LHSP.Ptr; - HashedType *RHS = RHSP.Ptr; - if (RHS == getEmptyKey().Ptr || RHS == getTombstoneKey().Ptr) - return LHS == RHS; - if (LHS->Hash != RHS->Hash) - return false; - return LHS->Data == RHS->Data; - } -}; - -} // end namespace llvm - -/// Private implementation so that we don't leak our DenseMap instantiations to -/// users. -class llvm::codeview::TypeHasher { -private: - /// Storage for type record provided by the caller. Records will outlive the - /// hasher object, so they should be allocated here. - BumpPtrAllocator &RecordStorage; - - /// Storage for hash keys. These only need to live as long as the hashing - /// operation. - BumpPtrAllocator KeyStorage; - - /// Hash table. We really want a DenseMap, TypeIndex> here, - /// but DenseMap is inefficient when the keys are long (like type records) - /// because it recomputes the hash value of every key when it grows. This - /// value type stores the hash out of line in KeyStorage, so that table - /// entries are small and easy to rehash. - DenseSet HashedRecords; - -public: - TypeHasher(BumpPtrAllocator &RecordStorage) : RecordStorage(RecordStorage) {} - - void reset() { HashedRecords.clear(); } - - /// Takes the bytes of type record, inserts them into the hash table, saves - /// them, and returns a pointer to an identical stable type record along with - /// its type index in the destination stream. - TypeIndex getOrCreateRecord(ArrayRef &Record, TypeIndex TI); -}; - -TypeIndex TypeHasher::getOrCreateRecord(ArrayRef &Record, - TypeIndex TI) { - assert(Record.size() < UINT32_MAX && "Record too big"); - assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); - - // Compute the hash up front so we can store it in the key. - HashedType TempHashedType = {hash_value(Record), Record, TI}; - auto Result = HashedRecords.insert(HashedTypePtr(&TempHashedType)); - HashedType *&Hashed = Result.first->Ptr; - - if (Result.second) { - // This was a new type record. We need stable storage for both the key and - // the record. The record should outlive the hashing operation. - Hashed = KeyStorage.Allocate(); - *Hashed = TempHashedType; - - uint8_t *Stable = RecordStorage.Allocate(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Hashed->Data = makeArrayRef(Stable, Record.size()); - } - - // Update the caller's copy of Record to point a stable copy. - Record = Hashed->Data; - return Hashed->Index; -} - -TypeIndex TypeTableBuilder::nextTypeIndex() const { - return TypeIndex::fromArrayIndex(SeenRecords.size()); -} - -TypeTableBuilder::TypeTableBuilder(BumpPtrAllocator &Storage, bool Hash) - : RecordStorage(Storage) { - if (Hash) - Hasher = llvm::make_unique(Storage); -} - -TypeTableBuilder::~TypeTableBuilder() = default; - -Optional TypeTableBuilder::getFirst() { - if (empty()) - return None; - - return TypeIndex(TypeIndex::FirstNonSimpleIndex); -} - -Optional TypeTableBuilder::getNext(TypeIndex Prev) { - if (++Prev == nextTypeIndex()) - return None; - return Prev; -} - -CVType TypeTableBuilder::getType(TypeIndex Index) { - CVType Type; - Type.RecordData = SeenRecords[Index.toArrayIndex()]; - const RecordPrefix *P = - reinterpret_cast(Type.RecordData.data()); - Type.Type = static_cast(uint16_t(P->RecordKind)); - return Type; -} - -StringRef TypeTableBuilder::getTypeName(TypeIndex Index) { - llvm_unreachable("Method not implemented"); -} - -bool TypeTableBuilder::contains(TypeIndex Index) { - if (Index.isSimple() || Index.isNoneType()) - return false; - - return Index.toArrayIndex() < SeenRecords.size(); -} - -uint32_t TypeTableBuilder::size() { return SeenRecords.size(); } - -uint32_t TypeTableBuilder::capacity() { return SeenRecords.size(); } - -ArrayRef> TypeTableBuilder::records() const { - return SeenRecords; -} - -void TypeTableBuilder::reset() { - if (Hasher) - Hasher->reset(); - SeenRecords.clear(); -} - -TypeIndex TypeTableBuilder::insertRecordBytes(ArrayRef &Record) { - if (Hasher) { - TypeIndex ActualTI = Hasher->getOrCreateRecord(Record, nextTypeIndex()); - if (nextTypeIndex() == ActualTI) - SeenRecords.push_back(Record); - return ActualTI; - } - - TypeIndex NewTI = nextTypeIndex(); - uint8_t *Stable = RecordStorage.Allocate(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Record = ArrayRef(Stable, Record.size()); - SeenRecords.push_back(Record); - return NewTI; -} - -TypeIndex TypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { - TypeIndex TI; - auto Fragments = Builder.end(nextTypeIndex()); - assert(!Fragments.empty()); - for (auto C : Fragments) - TI = insertRecordBytes(C.RecordData); - return TI; -} -- cgit v1.2.3