Line data Source code
1 : //===- SymbolSerializer.h ---------------------------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
11 : #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
12 :
13 : #include "llvm/ADT/Optional.h"
14 : #include "llvm/DebugInfo/CodeView/CodeView.h"
15 : #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
16 : #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
17 : #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
18 : #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
19 : #include "llvm/Support/Allocator.h"
20 : #include "llvm/Support/BinaryByteStream.h"
21 : #include "llvm/Support/BinaryStreamWriter.h"
22 : #include "llvm/Support/Error.h"
23 : #include <cstdint>
24 : #include <vector>
25 :
26 : namespace llvm {
27 : namespace codeview {
28 :
29 : class SymbolSerializer : public SymbolVisitorCallbacks {
30 : BumpPtrAllocator &Storage;
31 : // Since this is a fixed size buffer, use a stack allocated buffer. This
32 : // yields measurable performance increase over the repeated heap allocations
33 : // when serializing many independent records via writeOneSymbol.
34 : std::array<uint8_t, MaxRecordLength> RecordBuffer;
35 : MutableBinaryByteStream Stream;
36 : BinaryStreamWriter Writer;
37 : SymbolRecordMapping Mapping;
38 : Optional<SymbolKind> CurrentSymbol;
39 :
40 1224 : Error writeRecordPrefix(SymbolKind Kind) {
41 : RecordPrefix Prefix;
42 : Prefix.RecordKind = Kind;
43 : Prefix.RecordLen = 0;
44 2448 : if (auto EC = Writer.writeObject(Prefix))
45 : return EC;
46 : return Error::success();
47 : }
48 :
49 : public:
50 : SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
51 :
52 : template <typename SymType>
53 1224 : static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
54 : CodeViewContainer Container) {
55 : CVSymbol Result;
56 1224 : Result.Type = static_cast<SymbolKind>(Sym.Kind);
57 1224 : SymbolSerializer Serializer(Storage, Container);
58 1224 : consumeError(Serializer.visitSymbolBegin(Result));
59 1224 : consumeError(Serializer.visitKnownRecord(Result, Sym));
60 2448 : consumeError(Serializer.visitSymbolEnd(Result));
61 1224 : return Result;
62 : }
63 224 :
64 : Error visitSymbolBegin(CVSymbol &Record) override;
65 : Error visitSymbolEnd(CVSymbol &Record) override;
66 224 :
67 224 : #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
68 224 : Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
69 224 : return visitKnownRecordImpl(CVR, Record); \
70 448 : }
71 224 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
72 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
73 95 :
74 : private:
75 : template <typename RecordKind>
76 95 : Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
77 95 : return Mapping.visitKnownRecord(CVR, Record);
78 95 : }
79 95 : };
80 190 :
81 95 : } // end namespace codeview
82 : } // end namespace llvm
83 89 :
84 : #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
|