brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · bd2c60e Raw
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