1274955Ssvnmir//===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- C++ -*-===//
2274955Ssvnmir//
3274955Ssvnmir//                     The LLVM Compiler Infrastructure
4274955Ssvnmir//
5274955Ssvnmir// This file is distributed under the University of Illinois Open Source
6274955Ssvnmir// License. See LICENSE.TXT for details.
7274955Ssvnmir//
8274955Ssvnmir//===----------------------------------------------------------------------===//
9274955Ssvnmir//
10274955Ssvnmir// This file contains a class that can take bytes that would normally be
11274955Ssvnmir// streamed via the AsmPrinter.
12274955Ssvnmir//
13274955Ssvnmir//===----------------------------------------------------------------------===//
14274955Ssvnmir
15280031Sdim#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
16280031Sdim#define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
17274955Ssvnmir
18280031Sdim#include "DIEHash.h"
19274955Ssvnmir#include "llvm/ADT/ArrayRef.h"
20274955Ssvnmir#include "llvm/CodeGen/AsmPrinter.h"
21274955Ssvnmir#include "llvm/MC/MCStreamer.h"
22288943Sdim#include "llvm/Support/LEB128.h"
23288943Sdim#include <string>
24274955Ssvnmir
25274955Ssvnmirnamespace llvm {
26274955Ssvnmirclass ByteStreamer {
27296417Sdim protected:
28296417Sdim  ~ByteStreamer() = default;
29296417Sdim  ByteStreamer(const ByteStreamer&) = default;
30296417Sdim  ByteStreamer() = default;
31296417Sdim
32274955Ssvnmir public:
33274955Ssvnmir  // For now we're just handling the calls we need for dwarf emission/hashing.
34274955Ssvnmir  virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
35274955Ssvnmir  virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
36274955Ssvnmir  virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "") = 0;
37274955Ssvnmir};
38274955Ssvnmir
39296417Sdimclass APByteStreamer final : public ByteStreamer {
40274955Ssvnmirprivate:
41274955Ssvnmir  AsmPrinter &AP;
42274955Ssvnmir
43274955Ssvnmirpublic:
44274955Ssvnmir  APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}
45274955Ssvnmir  void EmitInt8(uint8_t Byte, const Twine &Comment) override {
46288943Sdim    AP.OutStreamer->AddComment(Comment);
47274955Ssvnmir    AP.EmitInt8(Byte);
48274955Ssvnmir  }
49274955Ssvnmir  void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
50288943Sdim    AP.OutStreamer->AddComment(Comment);
51274955Ssvnmir    AP.EmitSLEB128(DWord);
52274955Ssvnmir  }
53274955Ssvnmir  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
54288943Sdim    AP.OutStreamer->AddComment(Comment);
55274955Ssvnmir    AP.EmitULEB128(DWord);
56274955Ssvnmir  }
57274955Ssvnmir};
58274955Ssvnmir
59296417Sdimclass HashingByteStreamer final : public ByteStreamer {
60274955Ssvnmir private:
61274955Ssvnmir  DIEHash &Hash;
62274955Ssvnmir public:
63274955Ssvnmir HashingByteStreamer(DIEHash &H) : Hash(H) {}
64274955Ssvnmir  void EmitInt8(uint8_t Byte, const Twine &Comment) override {
65274955Ssvnmir    Hash.update(Byte);
66274955Ssvnmir  }
67274955Ssvnmir  void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
68274955Ssvnmir    Hash.addSLEB128(DWord);
69274955Ssvnmir  }
70274955Ssvnmir  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
71274955Ssvnmir    Hash.addULEB128(DWord);
72274955Ssvnmir  }
73274955Ssvnmir};
74288943Sdim
75296417Sdimclass BufferByteStreamer final : public ByteStreamer {
76288943Sdimprivate:
77288943Sdim  SmallVectorImpl<char> &Buffer;
78288943Sdim  SmallVectorImpl<std::string> &Comments;
79288943Sdim
80288943Sdim  /// \brief Only verbose textual output needs comments.  This will be set to
81288943Sdim  /// true for that case, and false otherwise.  If false, comments passed in to
82288943Sdim  /// the emit methods will be ignored.
83288943Sdim  bool GenerateComments;
84288943Sdim
85288943Sdimpublic:
86288943Sdim  BufferByteStreamer(SmallVectorImpl<char> &Buffer,
87288943Sdim                     SmallVectorImpl<std::string> &Comments,
88288943Sdim                     bool GenerateComments)
89288943Sdim  : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {}
90288943Sdim  void EmitInt8(uint8_t Byte, const Twine &Comment) override {
91288943Sdim    Buffer.push_back(Byte);
92288943Sdim    if (GenerateComments)
93288943Sdim      Comments.push_back(Comment.str());
94288943Sdim  }
95288943Sdim  void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
96288943Sdim    raw_svector_ostream OSE(Buffer);
97288943Sdim    encodeSLEB128(DWord, OSE);
98288943Sdim    if (GenerateComments)
99288943Sdim      Comments.push_back(Comment.str());
100288943Sdim  }
101288943Sdim  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
102288943Sdim    raw_svector_ostream OSE(Buffer);
103288943Sdim    encodeULEB128(DWord, OSE);
104288943Sdim    if (GenerateComments)
105288943Sdim      Comments.push_back(Comment.str());
106288943Sdim  }
107288943Sdim};
108288943Sdim
109274955Ssvnmir}
110274955Ssvnmir
111274955Ssvnmir#endif
112