1 //===- SymbolDeserializer.h -------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
10 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
14 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
15 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
16 #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
17 #include "llvm/Support/BinaryByteStream.h"
18 #include "llvm/Support/BinaryStreamReader.h"
19 #include "llvm/Support/Error.h"
23 class SymbolVisitorDelegate
;
24 class SymbolDeserializer
: public SymbolVisitorCallbacks
{
26 MappingInfo(ArrayRef
<uint8_t> RecordData
, CodeViewContainer Container
)
27 : Stream(RecordData
, llvm::support::little
), Reader(Stream
),
28 Mapping(Reader
, Container
) {}
30 BinaryByteStream Stream
;
31 BinaryStreamReader Reader
;
32 SymbolRecordMapping Mapping
;
36 template <typename T
> static Error
deserializeAs(CVSymbol Symbol
, T
&Record
) {
37 // If we're just deserializing one record, then don't worry about alignment
38 // as there's nothing that comes after.
39 SymbolDeserializer
S(nullptr, CodeViewContainer::ObjectFile
);
40 if (auto EC
= S
.visitSymbolBegin(Symbol
))
42 if (auto EC
= S
.visitKnownRecord(Symbol
, Record
))
44 if (auto EC
= S
.visitSymbolEnd(Symbol
))
46 return Error::success();
48 template <typename T
> static Expected
<T
> deserializeAs(CVSymbol Symbol
) {
49 T
Record(static_cast<SymbolRecordKind
>(Symbol
.kind()));
50 if (auto EC
= deserializeAs
<T
>(Symbol
, Record
))
55 explicit SymbolDeserializer(SymbolVisitorDelegate
*Delegate
,
56 CodeViewContainer Container
)
57 : Delegate(Delegate
), Container(Container
) {}
59 Error
visitSymbolBegin(CVSymbol
&Record
, uint32_t Offset
) override
{
60 return visitSymbolBegin(Record
);
63 Error
visitSymbolBegin(CVSymbol
&Record
) override
{
64 assert(!Mapping
&& "Already in a symbol mapping!");
65 Mapping
= std::make_unique
<MappingInfo
>(Record
.content(), Container
);
66 return Mapping
->Mapping
.visitSymbolBegin(Record
);
68 Error
visitSymbolEnd(CVSymbol
&Record
) override
{
69 assert(Mapping
&& "Not in a symbol mapping!");
70 auto EC
= Mapping
->Mapping
.visitSymbolEnd(Record
);
75 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
76 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
77 return visitKnownRecordImpl(CVR, Record); \
79 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
80 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
83 template <typename T
> Error
visitKnownRecordImpl(CVSymbol
&CVR
, T
&Record
) {
86 Delegate
? Delegate
->getRecordOffset(Mapping
->Reader
) : 0;
87 if (auto EC
= Mapping
->Mapping
.visitKnownRecord(CVR
, Record
))
89 return Error::success();
92 SymbolVisitorDelegate
*Delegate
;
93 CodeViewContainer Container
;
94 std::unique_ptr
<MappingInfo
> Mapping
;