blob: f4d8ab0c3c2ed25cccd49ad26cd6fd5685226a28 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
26namespace llvm {
27namespace codeview {
28
29class 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 Error writeRecordPrefix(SymbolKind Kind) {
41 RecordPrefix Prefix;
42 Prefix.RecordKind = Kind;
43 Prefix.RecordLen = 0;
44 if (auto EC = Writer.writeObject(Prefix))
45 return EC;
46 return Error::success();
47 }
48
49public:
50 SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
51
52 template <typename SymType>
53 static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
54 CodeViewContainer Container) {
55 CVSymbol Result;
56 Result.Type = static_cast<SymbolKind>(Sym.Kind);
57 SymbolSerializer Serializer(Storage, Container);
58 consumeError(Serializer.visitSymbolBegin(Result));
59 consumeError(Serializer.visitKnownRecord(Result, Sym));
60 consumeError(Serializer.visitSymbolEnd(Result));
61 return Result;
62 }
63
64 Error visitSymbolBegin(CVSymbol &Record) override;
65 Error visitSymbolEnd(CVSymbol &Record) override;
66
67#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
68 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
69 return visitKnownRecordImpl(CVR, Record); \
70 }
71#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
72#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
73
74private:
75 template <typename RecordKind>
76 Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
77 return Mapping.visitKnownRecord(CVR, Record);
78 }
79};
80
81} // end namespace codeview
82} // end namespace llvm
83
84#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H