[Alignment][NFC] Migrate Instructions to Align
[llvm-core.git] / include / llvm / DebugInfo / CodeView / SymbolDeserializer.h
blob108abb291498e3e57dce64e1ee8e2f19fb2b5108
1 //===- SymbolDeserializer.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 //===----------------------------------------------------------------------===//
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"
21 namespace llvm {
22 namespace codeview {
23 class SymbolVisitorDelegate;
24 class SymbolDeserializer : public SymbolVisitorCallbacks {
25 struct MappingInfo {
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;
35 public:
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))
41 return EC;
42 if (auto EC = S.visitKnownRecord(Symbol, Record))
43 return EC;
44 if (auto EC = S.visitSymbolEnd(Symbol))
45 return EC;
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))
51 return std::move(EC);
52 return 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);
71 Mapping.reset();
72 return EC;
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"
82 private:
83 template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
85 Record.RecordOffset =
86 Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
87 if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
88 return EC;
89 return Error::success();
92 SymbolVisitorDelegate *Delegate;
93 CodeViewContainer Container;
94 std::unique_ptr<MappingInfo> Mapping;
99 #endif