Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
35271 views
//===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains a class that can take bytes that would normally be9// streamed via the AsmPrinter.10//11//===----------------------------------------------------------------------===//1213#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H14#define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H1516#include "DIEHash.h"17#include "llvm/CodeGen/AsmPrinter.h"18#include "llvm/MC/MCStreamer.h"19#include "llvm/Support/LEB128.h"20#include <string>2122namespace llvm {23class ByteStreamer {24protected:25~ByteStreamer() = default;26ByteStreamer(const ByteStreamer&) = default;27ByteStreamer() = default;2829public:30// For now we're just handling the calls we need for dwarf emission/hashing.31virtual void emitInt8(uint8_t Byte, const Twine &Comment = "") = 0;32virtual void emitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;33virtual void emitULEB128(uint64_t DWord, const Twine &Comment = "",34unsigned PadTo = 0) = 0;35virtual unsigned emitDIERef(const DIE &D) = 0;36};3738class APByteStreamer final : public ByteStreamer {39private:40AsmPrinter &AP;4142public:43APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}44void emitInt8(uint8_t Byte, const Twine &Comment) override {45AP.OutStreamer->AddComment(Comment);46AP.emitInt8(Byte);47}48void emitSLEB128(uint64_t DWord, const Twine &Comment) override {49AP.OutStreamer->AddComment(Comment);50AP.emitSLEB128(DWord);51}52void emitULEB128(uint64_t DWord, const Twine &Comment,53unsigned PadTo) override {54AP.OutStreamer->AddComment(Comment);55AP.emitULEB128(DWord, nullptr, PadTo);56}57unsigned emitDIERef(const DIE &D) override {58uint64_t Offset = D.getOffset();59static constexpr unsigned ULEB128PadSize = 4;60assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");61emitULEB128(Offset, "", ULEB128PadSize);62// Return how many comments to skip in DwarfDebug::emitDebugLocEntry to keep63// comments aligned with debug loc entries.64return ULEB128PadSize;65}66};6768class HashingByteStreamer final : public ByteStreamer {69private:70DIEHash &Hash;71public:72HashingByteStreamer(DIEHash &H) : Hash(H) {}73void emitInt8(uint8_t Byte, const Twine &Comment) override {74Hash.update(Byte);75}76void emitSLEB128(uint64_t DWord, const Twine &Comment) override {77Hash.addSLEB128(DWord);78}79void emitULEB128(uint64_t DWord, const Twine &Comment,80unsigned PadTo) override {81Hash.addULEB128(DWord);82}83unsigned emitDIERef(const DIE &D) override {84Hash.hashRawTypeReference(D);85return 0; // Only used together with the APByteStreamer.86}87};8889class BufferByteStreamer final : public ByteStreamer {90private:91SmallVectorImpl<char> &Buffer;92std::vector<std::string> &Comments;9394public:95/// Only verbose textual output needs comments. This will be set to96/// true for that case, and false otherwise. If false, comments passed in to97/// the emit methods will be ignored.98const bool GenerateComments;99100BufferByteStreamer(SmallVectorImpl<char> &Buffer,101std::vector<std::string> &Comments, bool GenerateComments)102: Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {103}104void emitInt8(uint8_t Byte, const Twine &Comment) override {105Buffer.push_back(Byte);106if (GenerateComments)107Comments.push_back(Comment.str());108}109void emitSLEB128(uint64_t DWord, const Twine &Comment) override {110raw_svector_ostream OSE(Buffer);111unsigned Length = encodeSLEB128(DWord, OSE);112if (GenerateComments) {113Comments.push_back(Comment.str());114// Add some empty comments to keep the Buffer and Comments vectors aligned115// with each other.116for (size_t i = 1; i < Length; ++i)117Comments.push_back("");118119}120}121void emitULEB128(uint64_t DWord, const Twine &Comment,122unsigned PadTo) override {123raw_svector_ostream OSE(Buffer);124unsigned Length = encodeULEB128(DWord, OSE, PadTo);125if (GenerateComments) {126Comments.push_back(Comment.str());127// Add some empty comments to keep the Buffer and Comments vectors aligned128// with each other.129for (size_t i = 1; i < Length; ++i)130Comments.push_back("");131}132}133unsigned emitDIERef(const DIE &D) override {134uint64_t Offset = D.getOffset();135static constexpr unsigned ULEB128PadSize = 4;136assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");137emitULEB128(Offset, "", ULEB128PadSize);138return 0; // Only used together with the APByteStreamer.139}140};141142}143144#endif145146147