146 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains a class that can take bytes that would normally be10// streamed via the AsmPrinter.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H15#define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H16 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 = "",35 unsigned PadTo = 0) = 0;36 virtual unsigned emitDIERef(const DIE &D) = 0;37};38 39class APByteStreamer final : public ByteStreamer {40private:41 AsmPrinter &AP;42 43public:44 APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}45 void emitInt8(uint8_t Byte, const Twine &Comment) override {46 AP.OutStreamer->AddComment(Comment);47 AP.emitInt8(Byte);48 }49 void emitSLEB128(uint64_t DWord, const Twine &Comment) override {50 AP.OutStreamer->AddComment(Comment);51 AP.emitSLEB128(DWord);52 }53 void emitULEB128(uint64_t DWord, const Twine &Comment,54 unsigned PadTo) override {55 AP.OutStreamer->AddComment(Comment);56 AP.emitULEB128(DWord, nullptr, PadTo);57 }58 unsigned emitDIERef(const DIE &D) override {59 uint64_t Offset = D.getOffset();60 static constexpr unsigned ULEB128PadSize = 4;61 assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");62 emitULEB128(Offset, "", ULEB128PadSize);63 // Return how many comments to skip in DwarfDebug::emitDebugLocEntry to keep64 // comments aligned with debug loc entries.65 return ULEB128PadSize;66 }67};68 69class HashingByteStreamer final : public ByteStreamer {70 private:71 DIEHash &Hash;72 public:73 HashingByteStreamer(DIEHash &H) : Hash(H) {}74 void emitInt8(uint8_t Byte, const Twine &Comment) override {75 Hash.update(Byte);76 }77 void emitSLEB128(uint64_t DWord, const Twine &Comment) override {78 Hash.addSLEB128(DWord);79 }80 void emitULEB128(uint64_t DWord, const Twine &Comment,81 unsigned PadTo) override {82 Hash.addULEB128(DWord);83 }84 unsigned emitDIERef(const DIE &D) override {85 Hash.hashRawTypeReference(D);86 return 0; // Only used together with the APByteStreamer.87 }88};89 90class BufferByteStreamer final : public ByteStreamer {91private:92 SmallVectorImpl<char> &Buffer;93 std::vector<std::string> &Comments;94 95public:96 /// Only verbose textual output needs comments. This will be set to97 /// true for that case, and false otherwise. If false, comments passed in to98 /// the emit methods will be ignored.99 const bool GenerateComments;100 101 BufferByteStreamer(SmallVectorImpl<char> &Buffer,102 std::vector<std::string> &Comments, bool GenerateComments)103 : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {104 }105 void emitInt8(uint8_t Byte, const Twine &Comment) override {106 Buffer.push_back(Byte);107 if (GenerateComments)108 Comments.push_back(Comment.str());109 }110 void emitSLEB128(uint64_t DWord, const Twine &Comment) override {111 raw_svector_ostream OSE(Buffer);112 unsigned Length = encodeSLEB128(DWord, OSE);113 if (GenerateComments) {114 Comments.push_back(Comment.str());115 // Add some empty comments to keep the Buffer and Comments vectors aligned116 // with each other.117 for (size_t i = 1; i < Length; ++i)118 Comments.push_back("");119 120 }121 }122 void emitULEB128(uint64_t DWord, const Twine &Comment,123 unsigned PadTo) override {124 raw_svector_ostream OSE(Buffer);125 unsigned Length = encodeULEB128(DWord, OSE, PadTo);126 if (GenerateComments) {127 Comments.push_back(Comment.str());128 // Add some empty comments to keep the Buffer and Comments vectors aligned129 // with each other.130 for (size_t i = 1; i < Length; ++i)131 Comments.push_back("");132 }133 }134 unsigned emitDIERef(const DIE &D) override {135 uint64_t Offset = D.getOffset();136 static constexpr unsigned ULEB128PadSize = 4;137 assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");138 emitULEB128(Offset, "", ULEB128PadSize);139 return 0; // Only used together with the APByteStreamer.140 }141};142 143}144 145#endif146