ByteStreamer.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- 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. //
  9. // This file contains a class that can take bytes that would normally be
  10. // streamed via the AsmPrinter.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
  14. #define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
  15. #include "DIEHash.h"
  16. #include "llvm/CodeGen/AsmPrinter.h"
  17. #include "llvm/MC/MCStreamer.h"
  18. #include "llvm/Support/LEB128.h"
  19. #include <string>
  20. namespace llvm {
  21. class ByteStreamer {
  22. protected:
  23. ~ByteStreamer() = default;
  24. ByteStreamer(const ByteStreamer&) = default;
  25. ByteStreamer() = default;
  26. public:
  27. // For now we're just handling the calls we need for dwarf emission/hashing.
  28. virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
  29. virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
  30. virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "", unsigned PadTo = 0) = 0;
  31. };
  32. class APByteStreamer final : public ByteStreamer {
  33. private:
  34. AsmPrinter &AP;
  35. public:
  36. APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}
  37. void EmitInt8(uint8_t Byte, const Twine &Comment) override {
  38. AP.OutStreamer->AddComment(Comment);
  39. AP.emitInt8(Byte);
  40. }
  41. void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
  42. AP.OutStreamer->AddComment(Comment);
  43. AP.EmitSLEB128(DWord);
  44. }
  45. void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
  46. AP.OutStreamer->AddComment(Comment);
  47. AP.EmitULEB128(DWord);
  48. }
  49. };
  50. class HashingByteStreamer final : public ByteStreamer {
  51. private:
  52. DIEHash &Hash;
  53. public:
  54. HashingByteStreamer(DIEHash &H) : Hash(H) {}
  55. void EmitInt8(uint8_t Byte, const Twine &Comment) override {
  56. Hash.update(Byte);
  57. }
  58. void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
  59. Hash.addSLEB128(DWord);
  60. }
  61. void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
  62. Hash.addULEB128(DWord);
  63. }
  64. };
  65. class BufferByteStreamer final : public ByteStreamer {
  66. private:
  67. SmallVectorImpl<char> &Buffer;
  68. SmallVectorImpl<std::string> &Comments;
  69. /// Only verbose textual output needs comments. This will be set to
  70. /// true for that case, and false otherwise. If false, comments passed in to
  71. /// the emit methods will be ignored.
  72. bool GenerateComments;
  73. public:
  74. BufferByteStreamer(SmallVectorImpl<char> &Buffer,
  75. SmallVectorImpl<std::string> &Comments,
  76. bool GenerateComments)
  77. : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {}
  78. void EmitInt8(uint8_t Byte, const Twine &Comment) override {
  79. Buffer.push_back(Byte);
  80. if (GenerateComments)
  81. Comments.push_back(Comment.str());
  82. }
  83. void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
  84. raw_svector_ostream OSE(Buffer);
  85. unsigned Length = encodeSLEB128(DWord, OSE);
  86. if (GenerateComments) {
  87. Comments.push_back(Comment.str());
  88. // Add some empty comments to keep the Buffer and Comments vectors aligned
  89. // with each other.
  90. for (size_t i = 1; i < Length; ++i)
  91. Comments.push_back("");
  92. }
  93. }
  94. void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
  95. raw_svector_ostream OSE(Buffer);
  96. unsigned Length = encodeULEB128(DWord, OSE, PadTo);
  97. if (GenerateComments) {
  98. Comments.push_back(Comment.str());
  99. // Add some empty comments to keep the Buffer and Comments vectors aligned
  100. // with each other.
  101. for (size_t i = 1; i < Length; ++i)
  102. Comments.push_back("");
  103. }
  104. }
  105. };
  106. }
  107. #endif