LLVM 20.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
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
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.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Kind kind() const
Definition: CVRecord.h:42
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:96
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
Definition: CodeView.h:27
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1069
Helper object to track which of three possible relocation mechanisms are used for a particular value ...