• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
writeRecordPrefix(SymbolKind Kind)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 
49 public:
50   SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
51 
52   template <typename SymType>
writeOneSymbol(SymType & Sym,BumpPtrAllocator & Storage,CodeViewContainer Container)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 
74 private:
75   template <typename RecordKind>
visitKnownRecordImpl(CVSymbol & CVR,RecordKind & Record)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
85