]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
Merge ^/head r312309 through r312623.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / CodeView / TypeTableBuilder.h
1 //===- TypeTableBuilder.h ---------------------------------------*- C++ -*-===//
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 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
11 #define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
12
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"
20 #include <algorithm>
21 #include <cassert>
22 #include <cstdint>
23 #include <type_traits>
24
25 namespace llvm {
26 namespace codeview {
27
28 class TypeTableBuilder {
29 private:
30   TypeIndex handleError(Error EC) const {
31     assert(false && "Couldn't write Type!");
32     consumeError(std::move(EC));
33     return TypeIndex();
34   }
35
36   BumpPtrAllocator &Allocator;
37   TypeSerializer Serializer;
38
39 public:
40   explicit TypeTableBuilder(BumpPtrAllocator &Allocator)
41       : Allocator(Allocator), Serializer(Allocator) {}
42   TypeTableBuilder(const TypeTableBuilder &) = delete;
43   TypeTableBuilder &operator=(const TypeTableBuilder &) = delete;
44
45   bool empty() const { return Serializer.records().empty(); }
46
47   BumpPtrAllocator &getAllocator() const { return Allocator; }
48
49   template <typename T> TypeIndex writeKnownType(T &Record) {
50     static_assert(!std::is_same<T, FieldListRecord>::value,
51                   "Can't serialize FieldList!");
52
53     CVType Type;
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));
59
60     auto ExpectedIndex = Serializer.visitTypeEndGetIndex(Type);
61     if (!ExpectedIndex)
62       return handleError(ExpectedIndex.takeError());
63
64     return *ExpectedIndex;
65   }
66
67   TypeIndex writeSerializedRecord(MutableArrayRef<uint8_t> Record) {
68     return Serializer.insertRecordBytes(Record);
69   }
70
71   template <typename TFunc> void ForEachRecord(TFunc Func) {
72     uint32_t Index = TypeIndex::FirstNonSimpleIndex;
73
74     for (auto Record : Serializer.records()) {
75       Func(TypeIndex(Index), Record);
76       ++Index;
77     }
78   }
79
80   ArrayRef<MutableArrayRef<uint8_t>> records() const {
81     return Serializer.records();
82   }
83 };
84
85 class FieldListRecordBuilder {
86   TypeTableBuilder &TypeTable;
87   TypeSerializer TempSerializer;
88   CVType Type;
89
90 public:
91   explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
92       : TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
93     Type.Type = TypeLeafKind::LF_FIELDLIST;
94   }
95
96   void begin() {
97     if (auto EC = TempSerializer.visitTypeBegin(Type))
98       consumeError(std::move(EC));
99   }
100
101   template <typename T> void writeMemberType(T &Record) {
102     CVMemberRecord CVMR;
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));
110   }
111
112   TypeIndex end() {
113     if (auto EC = TempSerializer.visitTypeEnd(Type)) {
114       consumeError(std::move(EC));
115       return TypeIndex();
116     }
117
118     TypeIndex Index;
119     for (auto Record : TempSerializer.records()) {
120       Index = TypeTable.writeSerializedRecord(Record);
121     }
122     return Index;
123   }
124 };
125
126 } // end namespace codeview
127 } // end namespace llvm
128
129 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H