Home | History | Annotate | Line # | Download | only in AsmPrinter
      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-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file contains a class that can take bytes that would normally be
     10 // streamed via the AsmPrinter.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
     15 #define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
     16 
     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 
     23 namespace llvm {
     24 class 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 };
     37 
     38 class APByteStreamer final : public ByteStreamer {
     39 private:
     40   AsmPrinter &AP;
     41 
     42 public:
     43   APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}
     44   void emitInt8(uint8_t Byte, const Twine &Comment) override {
     45     AP.OutStreamer->AddComment(Comment);
     46     AP.emitInt8(Byte);
     47   }
     48   void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
     49     AP.OutStreamer->AddComment(Comment);
     50     AP.emitSLEB128(DWord);
     51   }
     52   void emitULEB128(uint64_t DWord, const Twine &Comment,
     53                    unsigned PadTo) override {
     54     AP.OutStreamer->AddComment(Comment);
     55     AP.emitULEB128(DWord, nullptr, PadTo);
     56   }
     57 };
     58 
     59 class HashingByteStreamer final : public ByteStreamer {
     60  private:
     61   DIEHash &Hash;
     62  public:
     63  HashingByteStreamer(DIEHash &H) : Hash(H) {}
     64   void emitInt8(uint8_t Byte, const Twine &Comment) override {
     65     Hash.update(Byte);
     66   }
     67   void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
     68     Hash.addSLEB128(DWord);
     69   }
     70   void emitULEB128(uint64_t DWord, const Twine &Comment,
     71                    unsigned PadTo) override {
     72     Hash.addULEB128(DWord);
     73   }
     74 };
     75 
     76 class BufferByteStreamer final : public ByteStreamer {
     77 private:
     78   SmallVectorImpl<char> &Buffer;
     79   std::vector<std::string> &Comments;
     80 
     81 public:
     82   /// Only verbose textual output needs comments.  This will be set to
     83   /// true for that case, and false otherwise.  If false, comments passed in to
     84   /// the emit methods will be ignored.
     85   const bool GenerateComments;
     86 
     87   BufferByteStreamer(SmallVectorImpl<char> &Buffer,
     88                      std::vector<std::string> &Comments, bool GenerateComments)
     89       : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {
     90   }
     91   void emitInt8(uint8_t Byte, const Twine &Comment) override {
     92     Buffer.push_back(Byte);
     93     if (GenerateComments)
     94       Comments.push_back(Comment.str());
     95   }
     96   void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
     97     raw_svector_ostream OSE(Buffer);
     98     unsigned Length = encodeSLEB128(DWord, OSE);
     99     if (GenerateComments) {
    100       Comments.push_back(Comment.str());
    101       // Add some empty comments to keep the Buffer and Comments vectors aligned
    102       // with each other.
    103       for (size_t i = 1; i < Length; ++i)
    104         Comments.push_back("");
    105 
    106     }
    107   }
    108   void emitULEB128(uint64_t DWord, const Twine &Comment,
    109                    unsigned PadTo) override {
    110     raw_svector_ostream OSE(Buffer);
    111     unsigned Length = encodeULEB128(DWord, OSE, PadTo);
    112     if (GenerateComments) {
    113       Comments.push_back(Comment.str());
    114       // Add some empty comments to keep the Buffer and Comments vectors aligned
    115       // with each other.
    116       for (size_t i = 1; i < Length; ++i)
    117         Comments.push_back("");
    118 
    119     }
    120   }
    121 };
    122 
    123 }
    124 
    125 #endif
    126