File indexing completed on 2026-05-10 08:43:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
0011
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/DenseMap.h"
0014 #include "llvm/ADT/SmallVector.h"
0015 #include "llvm/DebugInfo/CodeView/CVRecord.h"
0016 #include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
0017 #include "llvm/DebugInfo/CodeView/TypeCollection.h"
0018 #include "llvm/DebugInfo/CodeView/TypeHashing.h"
0019 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
0020 #include "llvm/Support/Allocator.h"
0021 #include <cassert>
0022 #include <cstdint>
0023
0024 namespace llvm {
0025 namespace codeview {
0026
0027 class ContinuationRecordBuilder;
0028
0029 class GlobalTypeTableBuilder : public TypeCollection {
0030
0031 BumpPtrAllocator &RecordStorage;
0032
0033
0034
0035
0036 SimpleTypeSerializer SimpleSerializer;
0037
0038
0039 DenseMap<GloballyHashedType, TypeIndex> HashedRecords;
0040
0041
0042 SmallVector<ArrayRef<uint8_t>, 2> SeenRecords;
0043
0044
0045 SmallVector<GloballyHashedType, 2> SeenHashes;
0046
0047 public:
0048 explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage);
0049 ~GlobalTypeTableBuilder();
0050
0051
0052 std::optional<TypeIndex> getFirst() override;
0053 std::optional<TypeIndex> getNext(TypeIndex Prev) override;
0054 CVType getType(TypeIndex Index) override;
0055 StringRef getTypeName(TypeIndex Index) override;
0056 bool contains(TypeIndex Index) override;
0057 uint32_t size() override;
0058 uint32_t capacity() override;
0059 bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
0060
0061
0062 void reset();
0063 TypeIndex nextTypeIndex() const;
0064
0065 BumpPtrAllocator &getAllocator() { return RecordStorage; }
0066
0067 ArrayRef<ArrayRef<uint8_t>> records() const;
0068 ArrayRef<GloballyHashedType> hashes() const;
0069
0070 template <typename CreateFunc>
0071 TypeIndex insertRecordAs(GloballyHashedType Hash, size_t RecordSize,
0072 CreateFunc Create) {
0073 assert(RecordSize < UINT32_MAX && "Record too big");
0074 assert(RecordSize % 4 == 0 &&
0075 "RecordSize is not a multiple of 4 bytes which will cause "
0076 "misalignment in the output TPI stream!");
0077
0078 auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex());
0079
0080 if (LLVM_UNLIKELY(Result.second ||
0081 Result.first->second.isSimple())) {
0082 uint8_t *Stable = RecordStorage.Allocate<uint8_t>(RecordSize);
0083 MutableArrayRef<uint8_t> Data(Stable, RecordSize);
0084 ArrayRef<uint8_t> StableRecord = Create(Data);
0085 if (StableRecord.empty()) {
0086
0087
0088 Result.first->getSecond() = TypeIndex(SimpleTypeKind::NotTranslated);
0089 return TypeIndex(SimpleTypeKind::NotTranslated);
0090 }
0091 if (Result.first->second.isSimple()) {
0092 assert(Result.first->second.getIndex() ==
0093 (uint32_t)SimpleTypeKind::NotTranslated);
0094
0095
0096
0097
0098 Result.first->second = nextTypeIndex();
0099 }
0100 SeenRecords.push_back(StableRecord);
0101 SeenHashes.push_back(Hash);
0102 }
0103
0104 return Result.first->second;
0105 }
0106
0107 TypeIndex insertRecordBytes(ArrayRef<uint8_t> Data);
0108 TypeIndex insertRecord(ContinuationRecordBuilder &Builder);
0109
0110 template <typename T> TypeIndex writeLeafType(T &Record) {
0111 ArrayRef<uint8_t> Data = SimpleSerializer.serialize(Record);
0112 return insertRecordBytes(Data);
0113 }
0114 };
0115
0116 }
0117 }
0118
0119 #endif