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