1 //===- GlobalTypeTableBuilder.h ----------------------------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
10 #define LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseSet.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/DebugInfo/CodeView/CodeView.h"
16 #include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
17 #include "llvm/DebugInfo/CodeView/TypeCollection.h"
18 #include "llvm/DebugInfo/CodeView/TypeHashing.h"
19 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
20 #include "llvm/Support/Allocator.h"
29 class ContinuationRecordBuilder
;
31 class GlobalTypeTableBuilder
: public TypeCollection
{
32 /// Storage for records. These need to outlive the TypeTableBuilder.
33 BumpPtrAllocator
&RecordStorage
;
35 /// A serializer that can write non-continuation leaf types. Only used as
36 /// a convenience function so that we can provide an interface method to
37 /// write an unserialized record.
38 SimpleTypeSerializer SimpleSerializer
;
41 DenseMap
<GloballyHashedType
, TypeIndex
> HashedRecords
;
43 /// Contains a list of all records indexed by TypeIndex.toArrayIndex().
44 SmallVector
<ArrayRef
<uint8_t>, 2> SeenRecords
;
46 /// Contains a list of all hash values inexed by TypeIndex.toArrayIndex().
47 SmallVector
<GloballyHashedType
, 2> SeenHashes
;
50 explicit GlobalTypeTableBuilder(BumpPtrAllocator
&Storage
);
51 ~GlobalTypeTableBuilder();
53 // TypeTableCollection overrides
54 Optional
<TypeIndex
> getFirst() override
;
55 Optional
<TypeIndex
> getNext(TypeIndex Prev
) override
;
56 CVType
getType(TypeIndex Index
) override
;
57 StringRef
getTypeName(TypeIndex Index
) override
;
58 bool contains(TypeIndex Index
) override
;
59 uint32_t size() override
;
60 uint32_t capacity() override
;
64 TypeIndex
nextTypeIndex() const;
66 BumpPtrAllocator
&getAllocator() { return RecordStorage
; }
68 ArrayRef
<ArrayRef
<uint8_t>> records() const;
69 ArrayRef
<GloballyHashedType
> hashes() const;
71 template <typename CreateFunc
>
72 TypeIndex
insertRecordAs(GloballyHashedType Hash
, size_t RecordSize
,
74 auto Result
= HashedRecords
.try_emplace(Hash
, nextTypeIndex());
76 if (LLVM_UNLIKELY(Result
.second
/*inserted*/ ||
77 Result
.first
->second
.isSimple())) {
78 uint8_t *Stable
= RecordStorage
.Allocate
<uint8_t>(RecordSize
);
79 MutableArrayRef
<uint8_t> Data(Stable
, RecordSize
);
80 ArrayRef
<uint8_t> StableRecord
= Create(Data
);
81 if (StableRecord
.empty()) {
82 // Records with forward references into the Type stream will be deferred
83 // for insertion at a later time, on the second pass.
84 Result
.first
->getSecond() = TypeIndex(SimpleTypeKind::NotTranslated
);
85 return TypeIndex(SimpleTypeKind::NotTranslated
);
87 if (Result
.first
->second
.isSimple()) {
88 assert(Result
.first
->second
.getIndex() ==
89 (uint32_t)SimpleTypeKind::NotTranslated
);
90 // On the second pass, update with index to remapped record. The
91 // (initially misbehaved) record will now come *after* other records
92 // resolved in the first pass, with proper *back* references in the
94 Result
.first
->second
= nextTypeIndex();
96 SeenRecords
.push_back(StableRecord
);
97 SeenHashes
.push_back(Hash
);
100 return Result
.first
->second
;
103 TypeIndex
insertRecordBytes(ArrayRef
<uint8_t> Data
);
104 TypeIndex
insertRecord(ContinuationRecordBuilder
&Builder
);
106 template <typename T
> TypeIndex
writeLeafType(T
&Record
) {
107 ArrayRef
<uint8_t> Data
= SimpleSerializer
.serialize(Record
);
108 return insertRecordBytes(Data
);
112 } // end namespace codeview
113 } // end namespace llvm
115 #endif // LLVM_DEBUGINFO_CODEVIEW_MERGINGTYPETABLEBUILDER_H