1 //===- SymbolSerializer.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_SYMBOLSERIALIZER_H
10 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/DebugInfo/CodeView/CodeView.h"
14 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
15 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
17 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
18 #include "llvm/Support/Allocator.h"
19 #include "llvm/Support/BinaryByteStream.h"
20 #include "llvm/Support/BinaryStreamWriter.h"
21 #include "llvm/Support/Error.h"
28 class SymbolSerializer
: public SymbolVisitorCallbacks
{
29 BumpPtrAllocator
&Storage
;
30 // Since this is a fixed size buffer, use a stack allocated buffer. This
31 // yields measurable performance increase over the repeated heap allocations
32 // when serializing many independent records via writeOneSymbol.
33 std::array
<uint8_t, MaxRecordLength
> RecordBuffer
;
34 MutableBinaryByteStream Stream
;
35 BinaryStreamWriter Writer
;
36 SymbolRecordMapping Mapping
;
37 Optional
<SymbolKind
> CurrentSymbol
;
39 Error
writeRecordPrefix(SymbolKind Kind
) {
41 Prefix
.RecordKind
= Kind
;
43 if (auto EC
= Writer
.writeObject(Prefix
))
45 return Error::success();
49 SymbolSerializer(BumpPtrAllocator
&Storage
, CodeViewContainer Container
);
51 template <typename SymType
>
52 static CVSymbol
writeOneSymbol(SymType
&Sym
, BumpPtrAllocator
&Storage
,
53 CodeViewContainer Container
) {
54 RecordPrefix Prefix
{uint16_t(Sym
.Kind
)};
55 CVSymbol
Result(&Prefix
, sizeof(Prefix
));
56 SymbolSerializer
Serializer(Storage
, Container
);
57 consumeError(Serializer
.visitSymbolBegin(Result
));
58 consumeError(Serializer
.visitKnownRecord(Result
, Sym
));
59 consumeError(Serializer
.visitSymbolEnd(Result
));
63 Error
visitSymbolBegin(CVSymbol
&Record
) override
;
64 Error
visitSymbolEnd(CVSymbol
&Record
) override
;
66 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
67 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
68 return visitKnownRecordImpl(CVR, Record); \
70 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
71 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
74 template <typename RecordKind
>
75 Error
visitKnownRecordImpl(CVSymbol
&CVR
, RecordKind
&Record
) {
76 return Mapping
.visitKnownRecord(CVR
, Record
);
80 } // end namespace codeview
81 } // end namespace llvm
83 #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H