1 //===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a class that can take bytes that would normally be
10 // streamed via the AsmPrinter.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
18 #include "llvm/CodeGen/AsmPrinter.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/Support/LEB128.h"
26 ~ByteStreamer() = default;
27 ByteStreamer(const ByteStreamer
&) = default;
28 ByteStreamer() = default;
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;
39 class APByteStreamer final
: public ByteStreamer
{
44 APByteStreamer(AsmPrinter
&Asm
) : AP(Asm
) {}
45 void emitInt8(uint8_t Byte
, const Twine
&Comment
) override
{
46 AP
.OutStreamer
->AddComment(Comment
);
49 void emitSLEB128(uint64_t DWord
, const Twine
&Comment
) override
{
50 AP
.OutStreamer
->AddComment(Comment
);
51 AP
.emitSLEB128(DWord
);
53 void emitULEB128(uint64_t DWord
, const Twine
&Comment
,
54 unsigned PadTo
) override
{
55 AP
.OutStreamer
->AddComment(Comment
);
56 AP
.emitULEB128(DWord
, nullptr, PadTo
);
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 keep
64 // comments aligned with debug loc entries.
65 return ULEB128PadSize
;
69 class HashingByteStreamer final
: public ByteStreamer
{
73 HashingByteStreamer(DIEHash
&H
) : Hash(H
) {}
74 void emitInt8(uint8_t Byte
, const Twine
&Comment
) override
{
77 void emitSLEB128(uint64_t DWord
, const Twine
&Comment
) override
{
78 Hash
.addSLEB128(DWord
);
80 void emitULEB128(uint64_t DWord
, const Twine
&Comment
,
81 unsigned PadTo
) override
{
82 Hash
.addULEB128(DWord
);
84 unsigned emitDIERef(const DIE
&D
) override
{
85 Hash
.hashRawTypeReference(D
);
86 return 0; // Only used together with the APByteStreamer.
90 class BufferByteStreamer final
: public ByteStreamer
{
92 SmallVectorImpl
<char> &Buffer
;
93 std::vector
<std::string
> &Comments
;
96 /// Only verbose textual output needs comments. This will be set to
97 /// true for that case, and false otherwise. If false, comments passed in to
98 /// the emit methods will be ignored.
99 const bool GenerateComments
;
101 BufferByteStreamer(SmallVectorImpl
<char> &Buffer
,
102 std::vector
<std::string
> &Comments
, bool GenerateComments
)
103 : Buffer(Buffer
), Comments(Comments
), GenerateComments(GenerateComments
) {
105 void emitInt8(uint8_t Byte
, const Twine
&Comment
) override
{
106 Buffer
.push_back(Byte
);
107 if (GenerateComments
)
108 Comments
.push_back(Comment
.str());
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 aligned
117 for (size_t i
= 1; i
< Length
; ++i
)
118 Comments
.push_back("");
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 aligned
130 for (size_t i
= 1; i
< Length
; ++i
)
131 Comments
.push_back("");
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.