SymbolSerializer.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===- SymbolSerializer.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. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
  9. #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
  10. #include "llvm/ADT/Optional.h"
  11. #include "llvm/DebugInfo/CodeView/CodeView.h"
  12. #include "llvm/DebugInfo/CodeView/RecordSerialization.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/Support/Allocator.h"
  17. #include "llvm/Support/BinaryByteStream.h"
  18. #include "llvm/Support/BinaryStreamWriter.h"
  19. #include "llvm/Support/Error.h"
  20. #include <cstdint>
  21. namespace llvm {
  22. namespace codeview {
  23. class SymbolSerializer : public SymbolVisitorCallbacks {
  24. BumpPtrAllocator &Storage;
  25. // Since this is a fixed size buffer, use a stack allocated buffer. This
  26. // yields measurable performance increase over the repeated heap allocations
  27. // when serializing many independent records via writeOneSymbol.
  28. std::array<uint8_t, MaxRecordLength> RecordBuffer;
  29. MutableBinaryByteStream Stream;
  30. BinaryStreamWriter Writer;
  31. SymbolRecordMapping Mapping;
  32. Optional<SymbolKind> CurrentSymbol;
  33. Error writeRecordPrefix(SymbolKind Kind) {
  34. RecordPrefix Prefix;
  35. Prefix.RecordKind = Kind;
  36. Prefix.RecordLen = 0;
  37. if (auto EC = Writer.writeObject(Prefix))
  38. return EC;
  39. return Error::success();
  40. }
  41. public:
  42. SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
  43. template <typename SymType>
  44. static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
  45. CodeViewContainer Container) {
  46. RecordPrefix Prefix{uint16_t(Sym.Kind)};
  47. CVSymbol Result(&Prefix, sizeof(Prefix));
  48. SymbolSerializer Serializer(Storage, Container);
  49. consumeError(Serializer.visitSymbolBegin(Result));
  50. consumeError(Serializer.visitKnownRecord(Result, Sym));
  51. consumeError(Serializer.visitSymbolEnd(Result));
  52. return Result;
  53. }
  54. Error visitSymbolBegin(CVSymbol &Record) override;
  55. Error visitSymbolEnd(CVSymbol &Record) override;
  56. #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
  57. Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
  58. return visitKnownRecordImpl(CVR, Record); \
  59. }
  60. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  61. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  62. private:
  63. template <typename RecordKind>
  64. Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
  65. return Mapping.visitKnownRecord(CVR, Record);
  66. }
  67. };
  68. } // end namespace codeview
  69. } // end namespace llvm
  70. #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H