1 //===- TypeTableBuilder.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
11 #define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/DebugInfo/CodeView/CodeView.h"
15 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
16 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
17 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
18 #include "llvm/Support/Allocator.h"
19 #include "llvm/Support/Error.h"
23 #include <type_traits>
28 class TypeTableBuilder {
30 TypeIndex handleError(Error EC) const {
31 assert(false && "Couldn't write Type!");
32 consumeError(std::move(EC));
36 BumpPtrAllocator &Allocator;
37 TypeSerializer Serializer;
40 explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
41 : Allocator(Allocator), Serializer(Allocator) {}
42 TypeTableBuilder(const TypeTableBuilder &) = delete;
43 TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
45 bool empty() const { return Serializer.records().empty(); }
47 BumpPtrAllocator &getAllocator() const { return Allocator; }
49 template <typename T> TypeIndex writeKnownType(T &Record) {
50 static_assert(!std::is_same<T, FieldListRecord>::value,
51 "Can't serialize FieldList!");
54 Type.Type = static_cast<TypeLeafKind>(Record.getKind());
55 if (auto EC = Serializer.visitTypeBegin(Type))
56 return handleError(std::move(EC));
57 if (auto EC = Serializer.visitKnownRecord(Type, Record))
58 return handleError(std::move(EC));
60 auto ExpectedIndex = Serializer.visitTypeEndGetIndex(Type);
62 return handleError(ExpectedIndex.takeError());
64 return *ExpectedIndex;
67 TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
68 return Serializer.insertRecordBytes(Record);
71 template <typename TFunc> void ForEachRecord(TFunc Func) {
72 uint32_t Index = TypeIndex::FirstNonSimpleIndex;
74 for (auto Record : Serializer.records()) {
75 Func(TypeIndex(Index), Record);
80 ArrayRef<MutableArrayRef<uint8_t>> records() const {
81 return Serializer.records();
85 class FieldListRecordBuilder {
86 TypeTableBuilder &TypeTable;
87 TypeSerializer TempSerializer;
91 explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
92 : TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
93 Type.Type = TypeLeafKind::LF_FIELDLIST;
97 if (auto EC = TempSerializer.visitTypeBegin(Type))
98 consumeError(std::move(EC));
101 template <typename T> void writeMemberType(T &Record) {
103 CVMR.Kind = static_cast<TypeLeafKind>(Record.getKind());
104 if (auto EC = TempSerializer.visitMemberBegin(CVMR))
105 consumeError(std::move(EC));
106 if (auto EC = TempSerializer.visitKnownMember(CVMR, Record))
107 consumeError(std::move(EC));
108 if (auto EC = TempSerializer.visitMemberEnd(CVMR))
109 consumeError(std::move(EC));
113 if (auto EC = TempSerializer.visitTypeEnd(Type)) {
114 consumeError(std::move(EC));
119 for (auto Record : TempSerializer.records()) {
120 Index = TypeTable.writeSerializedRecord(Record);
126 } // end namespace codeview
127 } // end namespace llvm
129 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H