LLVM 22.0.0git
TypeDeserializer.h
Go to the documentation of this file.
1//===- TypeDeserializer.h ---------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
10#define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/ADT/STLExtras.h"
20#include "llvm/Support/Error.h"
21#include <cassert>
22#include <cstdint>
23#include <memory>
24
25namespace llvm {
26namespace codeview {
27
29 struct MappingInfo {
30 explicit MappingInfo(ArrayRef<uint8_t> RecordData)
31 : Stream(RecordData, llvm::endianness::little), Reader(Stream),
32 Mapping(Reader) {}
33
34 BinaryByteStream Stream;
35 BinaryStreamReader Reader;
36 TypeRecordMapping Mapping;
37 };
38
39public:
40 TypeDeserializer() = default;
41
42 template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
43 Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
44 MappingInfo I(CVT.content());
45 if (auto EC = I.Mapping.visitTypeBegin(CVT))
46 return EC;
47 if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
48 return EC;
49 if (auto EC = I.Mapping.visitTypeEnd(CVT))
50 return EC;
51 return Error::success();
52 }
53
54 template <typename T>
56 const RecordPrefix *Prefix =
57 reinterpret_cast<const RecordPrefix *>(Data.data());
59 static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
60 T Record(K);
61 CVType CVT(Data);
62 if (auto EC = deserializeAs<T>(CVT, Record))
63 return std::move(EC);
64 return Record;
65 }
66
68 assert(!Mapping && "Already in a type mapping!");
69 Mapping = std::make_unique<MappingInfo>(Record.content());
70 return Mapping->Mapping.visitTypeBegin(Record);
71 }
72
74 return visitTypeBegin(Record);
75 }
76
78 assert(Mapping && "Not in a type mapping!");
79 auto EC = Mapping->Mapping.visitTypeEnd(Record);
80 Mapping.reset();
81 return EC;
82 }
83
84#define TYPE_RECORD(EnumName, EnumVal, Name) \
85 Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
86 return visitKnownRecordImpl<Name##Record>(CVR, Record); \
87 }
88#define MEMBER_RECORD(EnumName, EnumVal, Name)
89#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
90#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
91#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
92
93private:
94 template <typename RecordType>
95 Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
96 return Mapping->Mapping.visitKnownRecord(CVR, Record);
97 }
98
99 std::unique_ptr<MappingInfo> Mapping;
100};
101
103 struct MappingInfo {
104 explicit MappingInfo(BinaryStreamReader &R)
105 : Reader(R), Mapping(Reader), StartOffset(0) {}
106
107 BinaryStreamReader &Reader;
108 TypeRecordMapping Mapping;
109 uint32_t StartOffset;
110 };
111
112public:
113 explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
114 RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
115 CVType FieldList(&Pre, sizeof(Pre));
116 consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
117 }
118
120 RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
121 CVType FieldList(&Pre, sizeof(Pre));
122 consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
123 }
124
126 Mapping.StartOffset = Mapping.Reader.getOffset();
127 return Mapping.Mapping.visitMemberBegin(Record);
128 }
129
131 if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
132 return EC;
133 return Error::success();
134 }
135
136#define TYPE_RECORD(EnumName, EnumVal, Name)
137#define MEMBER_RECORD(EnumName, EnumVal, Name) \
138 Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
139 return visitKnownMemberImpl<Name##Record>(CVR, Record); \
140 }
141#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
142#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
143#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
144
145private:
146 template <typename RecordType>
147 Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
148 if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
149 return EC;
150
151 uint32_t EndOffset = Mapping.Reader.getOffset();
152 uint32_t RecordLength = EndOffset - Mapping.StartOffset;
153 Mapping.Reader.setOffset(Mapping.StartOffset);
154 if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
155 return EC;
156 assert(Mapping.Reader.getOffset() == EndOffset);
157 return Error::success();
158 }
159 MappingInfo Mapping;
160};
161
162} // end namespace codeview
163} // end namespace llvm
164
165#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:58
#define T
This file contains some templates that are useful if you are working with the STL at all.
FunctionLoweringInfo::StatepointRelocationRecord RecordType
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
LLVM_ABI Error readBytes(ArrayRef< uint8_t > &Buffer, uint32_t Size)
Read Size bytes from the underlying stream at the current offset and and set Buffer to the resulting ...
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
ArrayRef< uint8_t > content() const
Definition CVRecord.h:56
Error visitMemberEnd(CVMemberRecord &Record) override
FieldListDeserializer(BinaryStreamReader &Reader)
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitTypeEnd(CVType &Record) override
Error visitTypeBegin(CVType &Record, TypeIndex Index) override
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
static Expected< T > deserializeAs(ArrayRef< uint8_t > Data)
static Error deserializeAs(CVType &CVT, T &Record)
A 32-bit type reference.
Definition TypeIndex.h:97
CVRecord< TypeLeafKind > CVType
Definition CVRecord.h:64
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
Definition CodeView.h:28
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1083
ArrayRef< uint8_t > Data
Definition TypeRecord.h:36