LLVM 24.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 Mapping.StartOffset = Mapping.Reader.getOffset();
121 return Mapping.Mapping.visitMemberBegin(Record);
122 }
123
125 if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
126 return EC;
127 return Error::success();
128 }
129
130#define TYPE_RECORD(EnumName, EnumVal, Name)
131#define MEMBER_RECORD(EnumName, EnumVal, Name) \
132 Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
133 return visitKnownMemberImpl<Name##Record>(CVR, Record); \
134 }
135#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
136#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
137#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
138
139private:
140 template <typename RecordType>
141 Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
142 if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
143 return EC;
144
145 uint32_t EndOffset = Mapping.Reader.getOffset();
146 uint32_t RecordLength = EndOffset - Mapping.StartOffset;
147 Mapping.Reader.setOffset(Mapping.StartOffset);
148 if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
149 return EC;
150 assert(Mapping.Reader.getOffset() == EndOffset);
151 return Error::success();
152 }
153 MappingInfo Mapping;
154};
155
156} // end namespace codeview
157} // end namespace llvm
158
159#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:57
#define T
This file contains some templates that are useful if you are working with the STL at all.
FunctionLoweringInfo::StatepointRelocationRecord RecordType
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
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:27
This is an optimization pass for GlobalISel generic memory operations.
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
ArrayRef< uint8_t > Data
Definition TypeRecord.h:36