187866Ssheldonh//===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- C++ -*-===// 287866Ssheldonh// 387866Ssheldonh// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 487866Ssheldonh// See https://llvm.org/LICENSE.txt for license information. 587866Ssheldonh// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 687866Ssheldonh// 787866Ssheldonh//===----------------------------------------------------------------------===// 887866Ssheldonh// 987866Ssheldonh// This file contains a class that can take bytes that would normally be 1087866Ssheldonh// streamed via the AsmPrinter. 1187866Ssheldonh// 1287866Ssheldonh//===----------------------------------------------------------------------===// 1387866Ssheldonh 1487866Ssheldonh#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H 1587866Ssheldonh#define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H 1687866Ssheldonh 1787866Ssheldonh#include "DIEHash.h" 1887866Ssheldonh#include "llvm/CodeGen/AsmPrinter.h" 1987866Ssheldonh#include "llvm/MC/MCStreamer.h" 2087866Ssheldonh#include "llvm/Support/LEB128.h" 2187866Ssheldonh#include <string> 2287866Ssheldonh 2387866Ssheldonhnamespace llvm { 2487866Ssheldonhclass ByteStreamer { 2587866Ssheldonh protected: 2687866Ssheldonh ~ByteStreamer() = default; 2787866Ssheldonh ByteStreamer(const ByteStreamer&) = default; 2887866Ssheldonh ByteStreamer() = default; 2987866Ssheldonh 3087866Ssheldonh public: 3187866Ssheldonh // For now we're just handling the calls we need for dwarf emission/hashing. 3287866Ssheldonh virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0; 33132752Skan virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0; 3487866Ssheldonh virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "", unsigned PadTo = 0) = 0; 3587866Ssheldonh}; 3687866Ssheldonh 3787866Ssheldonhclass APByteStreamer final : public ByteStreamer { 3887866Ssheldonhprivate: 3987866Ssheldonh AsmPrinter &AP; 4087866Ssheldonh 4187866Ssheldonhpublic: 4287866Ssheldonh APByteStreamer(AsmPrinter &Asm) : AP(Asm) {} 4387866Ssheldonh void EmitInt8(uint8_t Byte, const Twine &Comment) override { 4487866Ssheldonh AP.OutStreamer->AddComment(Comment); 4587866Ssheldonh AP.emitInt8(Byte); 4687866Ssheldonh } 4787866Ssheldonh void EmitSLEB128(uint64_t DWord, const Twine &Comment) override { 4887866Ssheldonh AP.OutStreamer->AddComment(Comment); 4987866Ssheldonh AP.EmitSLEB128(DWord); 5087866Ssheldonh } 5187866Ssheldonh void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override { 5287866Ssheldonh AP.OutStreamer->AddComment(Comment); 5387866Ssheldonh AP.EmitULEB128(DWord); 5487866Ssheldonh } 5587866Ssheldonh}; 5687866Ssheldonh 5787866Ssheldonhclass HashingByteStreamer final : public ByteStreamer { 5887866Ssheldonh private: 5987866Ssheldonh DIEHash &Hash; 6087866Ssheldonh public: 6187866Ssheldonh HashingByteStreamer(DIEHash &H) : Hash(H) {} 6287866Ssheldonh void EmitInt8(uint8_t Byte, const Twine &Comment) override { 6387866Ssheldonh Hash.update(Byte); 6487866Ssheldonh } 6587866Ssheldonh void EmitSLEB128(uint64_t DWord, const Twine &Comment) override { 6687866Ssheldonh Hash.addSLEB128(DWord); 6787866Ssheldonh } 6887866Ssheldonh void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override { 6987866Ssheldonh Hash.addULEB128(DWord); 7087866Ssheldonh } 7187866Ssheldonh}; 7287866Ssheldonh 7387866Ssheldonhclass BufferByteStreamer final : public ByteStreamer { 7487866Ssheldonhprivate: 75132752Skan SmallVectorImpl<char> &Buffer; 7687866Ssheldonh std::vector<std::string> &Comments; 7787866Ssheldonh 7887866Ssheldonhpublic: 7987866Ssheldonh /// Only verbose textual output needs comments. This will be set to 8087866Ssheldonh /// true for that case, and false otherwise. If false, comments passed in to 8187866Ssheldonh /// 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