<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="text-align:left; direction:ltr;">
<div>On Mon, 2019-10-28 at 16:14 -0700, David Blaikie wrote:</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div dir="ltr">
<div dir="ltr"><br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Oct 15, 2019 at 4:12 AM David Stenberg via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
Author: dstenb<br>
Date: Tue Oct 15 04:14:35 2019<br>
New Revision: 374879<br>
<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=f57ce99a-a9f6cb4c-f57ca901-0cc47ad93dcc-b8e3ba007c93d8e9&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%3Frev%3D374879%26view%3Drev" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=374879&view=rev</a><br>
Log:<br>
[DebugInfo] Add interface for pre-calculating the size of emitted DWARF<br>
<br>
Summary:<br>
DWARF's DW_OP_entry_value operation has two operands; the first is a<br>
ULEB128 operand that specifies the size of the second operand, which is<br>
a DWARF block. This means that we need to be able to pre-calculate and<br>
emit the size of DWARF expressions before emitting them. There is<br>
currently no interface for doing this in DwarfExpression, so this patch<br>
introduces that.<br>
<br>
When implementing this I initially thought about running through<br>
DwarfExpression's emission two times; first with a temporary buffer to<br>
emit the expression, in order to being able to calculate the size of<br>
that emitted data. However, DwarfExpression is a quite complex state<br>
machine, so I decided against that, as it seemed like the two runs could<br>
get out of sync, resulting in incorrect size operands. Therefore I have<br>
implemented this in a way that we only have to run DwarfExpression once.<br>
The idea is to emit DWARF to a temporary buffer, for which it is<br>
possible to query the size. The data in the temporary buffer can then be<br>
emitted to DwarfExpression's main output.<br>
<br>
In the case of DIEDwarfExpression, a temporary DIE is used. The values<br>
are all allocated using the same BumpPtrAllocator as for all other DIEs,<br>
and the values are then transferred to the real value list.<br>
</blockquote>
<div><br>
"temporary" and "BumpPtrAllocator" are a bit antithetical - this produces a sort of reachable memory leak? Should that be revisited/maybe a different allocation scheme used?<br>
 </div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>Hi!</div>
<div><br>
</div>
<div>When we are done with emitting to the temporary DIE, we'll invoke commitTemporaryBuffer(), which will move the nodes to the DIE which we'll later on emit:</div>
<div><br>
</div>
<div>void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }</div>
<div><br>
</div>
<div>void takeValues(DIEValueList &Other) { List.takeNodes(Other.List); }</div>
<div><br>
</div>
<div>  void takeNodes(IntrusiveBackList<T> &Other) {                                                                                                                                                                                                                                                                                </div>
<div>    for (auto &N : Other) {                                                                                                                                                                                                                                                                                                    </div>
<div>      N.Next.setPointerAndInt(&N, true);                                                                                                                                                                                                                                                                                       </div>
<div>      push_back(N);                                                                                                                                                                                                                                                                                                            </div>
<div>    }                                                                                                                                                                                                                                                                                                                          </div>
<div>    Other.Last = nullptr;                                                                                                                                                                                                                                                                                                      </div>
<div>  }                                                                                                                                                                                                                                                                                                                            </div>
<div></div>
<div><br>
</div>
<div>So this shouldn't be a memory leak, as long as commitTemporaryBuffer() is invoked before destroying the DwarfExpression object holding the TmpDIE. As a safeguard, perhaps there should be an assert in DIEDwarfExpression's destructor that verifies that TmpDIE
 is empty, to ensure that that has been done?</div>
<div><br>
</div>
<div>Best regards,</div>
<div>David</div>
<div><br>
</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div dir="ltr">
<div class="gmail_quote">
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
In the case<br>
of DebugLocDwarfExpression, the temporary buffer is implemented using a<br>
BufferByteStreamer which emits to a buffer in the DwarfExpression<br>
object.<br>
<br>
Reviewers: aprantl, vsk, NikolaPrica, djtodoro<br>
<br>
Reviewed By: aprantl<br>
<br>
Subscribers: hiraditya, llvm-commits<br>
<br>
Tags: #debug-info, #llvm<br>
<br>
Differential Revision: <a href="https://protect2.fireeye.com/v1/url?k=bfcbb09e-e3419248-bfcbf005-0cc47ad93dcc-60f30bf3fa8ba6ae&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=https%3A%2F%2Freviews.llvm.org%2FD67768" rel="noreferrer" target="_blank">
https://reviews.llvm.org/D67768</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/CodeGen/DIE.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/DIE.h<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=4a017520-168b57f6-4a0135bb-0cc47ad93dcc-39cd3824bb0bbde2&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fllvm%2Ftrunk%2Finclude%2Fllvm%2FCodeGen%2FDIE.h%3Frev%3D374879%26r1%3D374878%26r2%3D374879%26view%3Ddiff" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DIE.h?rev=374879&r1=374878&r2=374879&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/DIE.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/DIE.h Tue Oct 15 04:14:35 2019<br>
@@ -550,6 +550,14 @@ public:<br>
     return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);<br>
   }<br>
<br>
+  void takeNodes(IntrusiveBackList<T> &Other) {<br>
+    for (auto &N : Other) {<br>
+      N.Next.setPointerAndInt(&N, true);<br>
+      push_back(N);<br>
+    }<br>
+    Other.Last = nullptr;<br>
+  }<br>
+<br>
   class const_iterator;<br>
   class iterator<br>
       : public iterator_facade_base<iterator, std::forward_iterator_tag, T> {<br>
@@ -685,6 +693,10 @@ public:<br>
     return addValue(Alloc, DIEValue(Attribute, Form, std::forward<T>(Value)));<br>
   }<br>
<br>
+  /// Take ownership of the nodes in \p Other, and append them to the back of<br>
+  /// the list.<br>
+  void takeValues(DIEValueList &Other) { List.takeNodes(Other.List); }<br>
+<br>
   value_range values() {<br>
     return make_range(value_iterator(List.begin()), value_iterator(List.end()));<br>
   }<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=9d68e784-c1e2c552-9d68a71f-0cc47ad93dcc-1b05a4bd189f993b&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fllvm%2Ftrunk%2Flib%2FCodeGen%2FAsmPrinter%2FByteStreamer.h%3Frev%3D374879%26r1%3D374878%26r2%3D374879%26view%3Ddiff" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h?rev=374879&r1=374878&r2=374879&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h Tue Oct 15 04:14:35 2019<br>
@@ -75,16 +75,16 @@ private:<br>
   SmallVectorImpl<char> &Buffer;<br>
   std::vector<std::string> &Comments;<br>
<br>
+public:<br>
   /// Only verbose textual output needs comments.  This will be set to<br>
   /// true for that case, and false otherwise.  If false, comments passed in to<br>
   /// the emit methods will be ignored.<br>
-  bool GenerateComments;<br>
+  const bool GenerateComments;<br>
<br>
-public:<br>
   BufferByteStreamer(SmallVectorImpl<char> &Buffer,<br>
-                     std::vector<std::string> &Comments,<br>
-                     bool GenerateComments)<br>
-  : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {}<br>
+                     std::vector<std::string> &Comments, bool GenerateComments)<br>
+      : Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {<br>
+  }<br>
   void EmitInt8(uint8_t Byte, const Twine &Comment) override {<br>
     Buffer.push_back(Byte);<br>
     if (GenerateComments)<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=3160b174-6dea93a2-3160f1ef-0cc47ad93dcc-ad90754e59304e20&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fllvm%2Ftrunk%2Flib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp%3Frev%3D374879%26r1%3D374878%26r2%3D374879%26view%3Ddiff" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=374879&r1=374878&r2=374879&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Oct 15 04:14:35 2019<br>
@@ -170,26 +170,26 @@ static const char *const DbgTimerDescrip<br>
 static constexpr unsigned ULEB128PadSize = 4;<br>
<br>
 void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {<br>
-  BS.EmitInt8(<br>
+  getActiveStreamer().EmitInt8(<br>
       Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op)<br>
                   : dwarf::OperationEncodingString(Op));<br>
 }<br>
<br>
 void DebugLocDwarfExpression::emitSigned(int64_t Value) {<br>
-  BS.EmitSLEB128(Value, Twine(Value));<br>
+  getActiveStreamer().EmitSLEB128(Value, Twine(Value));<br>
 }<br>
<br>
 void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {<br>
-  BS.EmitULEB128(Value, Twine(Value));<br>
+  getActiveStreamer().EmitULEB128(Value, Twine(Value));<br>
 }<br>
<br>
 void DebugLocDwarfExpression::emitData1(uint8_t Value) {<br>
-  BS.EmitInt8(Value, Twine(Value));<br>
+  getActiveStreamer().EmitInt8(Value, Twine(Value));<br>
 }<br>
<br>
 void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {<br>
   assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit");<br>
-  BS.EmitULEB128(Idx, Twine(Idx), ULEB128PadSize);<br>
+  getActiveStreamer().EmitULEB128(Idx, Twine(Idx), ULEB128PadSize);<br>
 }<br>
<br>
 bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,<br>
@@ -198,6 +198,32 @@ bool DebugLocDwarfExpression::isFrameReg<br>
   return false;<br>
 }<br>
<br>
+void DebugLocDwarfExpression::enableTemporaryBuffer() {<br>
+  assert(!IsBuffering && "Already buffering?");<br>
+  if (!TmpBuf)<br>
+    TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);<br>
+  IsBuffering = true;<br>
+}<br>
+<br>
+void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }<br>
+<br>
+unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {<br>
+  return TmpBuf ? TmpBuf->Bytes.size() : 0;<br>
+}<br>
+<br>
+void DebugLocDwarfExpression::commitTemporaryBuffer() {<br>
+  if (!TmpBuf)<br>
+    return;<br>
+  for (auto Byte : enumerate(TmpBuf->Bytes)) {<br>
+    const char *Comment = (Byte.index() < TmpBuf->Comments.size())<br>
+                              ? TmpBuf->Comments[Byte.index()].c_str()<br>
+                              : "";<br>
+    OutBS.EmitInt8(Byte.value(), Comment);<br>
+  }<br>
+  TmpBuf->Bytes.clear();<br>
+  TmpBuf->Comments.clear();<br>
+}<br>
+<br>
 const DIType *DbgVariable::getType() const {<br>
   return getVariable()->getType();<br>
 }<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=37440186-6bce2350-3744411d-0cc47ad93dcc-c232fd6cba537a4a&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fllvm%2Ftrunk%2Flib%2FCodeGen%2FAsmPrinter%2FDwarfExpression.h%3Frev%3D374879%26r1%3D374878%26r2%3D374879%26view%3Ddiff" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=374879&r1=374878&r2=374879&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Tue Oct 15 04:14:35 2019<br>
@@ -13,6 +13,7 @@<br>
 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H<br>
 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H<br>
<br>
+#include "ByteStreamer.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/None.h"<br>
 #include "llvm/ADT/Optional.h"<br>
@@ -26,7 +27,6 @@ namespace llvm {<br>
<br>
 class AsmPrinter;<br>
 class APInt;<br>
-class ByteStreamer;<br>
 class DwarfCompileUnit;<br>
 class DIELoc;<br>
 class TargetRegisterInfo;<br>
@@ -95,6 +95,13 @@ public:<br>
 /// Base class containing the logic for constructing DWARF expressions<br>
 /// independently of whether they are emitted into a DIE or into a .debug_loc<br>
 /// entry.<br>
+///<br>
+/// Some DWARF operations, e.g. DW_OP_entry_value, need to calculate the size<br>
+/// of a succeeding DWARF block before the latter is emitted to the output.<br>
+/// To handle such cases, data can conditionally be emitted to a temporary<br>
+/// buffer, which can later on be committed to the main output. The size of the<br>
+/// temporary buffer is queryable, allowing for the size of the data to be<br>
+/// emitted before the data is committed.<br>
 class DwarfExpression {<br>
 protected:<br>
   /// Holds information about all subregisters comprising a register location.<br>
@@ -178,6 +185,22 @@ protected:<br>
<br>
   virtual void emitBaseTypeRef(uint64_t Idx) = 0;<br>
<br>
+  /// Start emitting data to the temporary buffer. The data stored in the<br>
+  /// temporary buffer can be committed to the main output using<br>
+  /// commitTemporaryBuffer().<br>
+  virtual void enableTemporaryBuffer() = 0;<br>
+<br>
+  /// Disable emission to the temporary buffer. This does not commit data<br>
+  /// in the temporary buffer to the main output.<br>
+  virtual void disableTemporaryBuffer() = 0;<br>
+<br>
+  /// Return the emitted size, in number of bytes, for the data stored in the<br>
+  /// temporary buffer.<br>
+  virtual unsigned getTemporaryBufferSize() = 0;<br>
+<br>
+  /// Commit the data stored in the temporary buffer to the main output.<br>
+  virtual void commitTemporaryBuffer() = 0;<br>
+<br>
   /// Emit a normalized unsigned constant.<br>
   void emitConstu(uint64_t Value);<br>
<br>
@@ -308,31 +331,62 @@ public:<br>
<br>
 /// DwarfExpression implementation for .debug_loc entries.<br>
 class DebugLocDwarfExpression final : public DwarfExpression {<br>
-  ByteStreamer &BS;<br>
+<br>
+  struct TempBuffer {<br>
+    SmallString<32> Bytes;<br>
+    std::vector<std::string> Comments;<br>
+    BufferByteStreamer BS;<br>
+<br>
+    TempBuffer(bool GenerateComments) : BS(Bytes, Comments, GenerateComments) {}<br>
+  };<br>
+<br>
+  std::unique_ptr<TempBuffer> TmpBuf;<br>
+  BufferByteStreamer &OutBS;<br>
+  bool IsBuffering = false;<br>
+<br>
+  /// Return the byte streamer that currently is being emitted to.<br>
+  ByteStreamer &getActiveStreamer() { return IsBuffering ? TmpBuf->BS : OutBS; }<br>
<br>
   void emitOp(uint8_t Op, const char *Comment = nullptr) override;<br>
   void emitSigned(int64_t Value) override;<br>
   void emitUnsigned(uint64_t Value) override;<br>
   void emitData1(uint8_t Value) override;<br>
   void emitBaseTypeRef(uint64_t Idx) override;<br>
+<br>
+  void enableTemporaryBuffer() override;<br>
+  void disableTemporaryBuffer() override;<br>
+  unsigned getTemporaryBufferSize() override;<br>
+  void commitTemporaryBuffer() override;<br>
+<br>
   bool isFrameRegister(const TargetRegisterInfo &TRI,<br>
                        unsigned MachineReg) override;<br>
-<br>
 public:<br>
-  DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS, DwarfCompileUnit &CU)<br>
-      : DwarfExpression(DwarfVersion, CU), BS(BS) {}<br>
+  DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS,<br>
+                          DwarfCompileUnit &CU)<br>
+      : DwarfExpression(DwarfVersion, CU), OutBS(BS) {}<br>
 };<br>
<br>
 /// DwarfExpression implementation for singular DW_AT_location.<br>
 class DIEDwarfExpression final : public DwarfExpression {<br>
-const AsmPrinter &AP;<br>
-  DIELoc &DIE;<br>
+  const AsmPrinter &AP;<br>
+  DIELoc &OutDIE;<br>
+  DIELoc TmpDIE;<br>
+  bool IsBuffering = false;<br>
+<br>
+  /// Return the DIE that currently is being emitted to.<br>
+  DIELoc &getActiveDIE() { return IsBuffering ? TmpDIE : OutDIE; }<br>
<br>
   void emitOp(uint8_t Op, const char *Comment = nullptr) override;<br>
   void emitSigned(int64_t Value) override;<br>
   void emitUnsigned(uint64_t Value) override;<br>
   void emitData1(uint8_t Value) override;<br>
   void emitBaseTypeRef(uint64_t Idx) override;<br>
+<br>
+  void enableTemporaryBuffer() override;<br>
+  void disableTemporaryBuffer() override;<br>
+  unsigned getTemporaryBufferSize() override;<br>
+  void commitTemporaryBuffer() override;<br>
+<br>
   bool isFrameRegister(const TargetRegisterInfo &TRI,<br>
                        unsigned MachineReg) override;<br>
 public:<br>
@@ -340,7 +394,7 @@ public:<br>
<br>
   DIELoc *finalize() {<br>
     DwarfExpression::finalize();<br>
-    return &DIE;<br>
+    return &OutDIE;<br>
   }<br>
 };<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp<br>
URL: <a href="https://protect2.fireeye.com/v1/url?k=d376da64-8ffcf8b2-d3769aff-0cc47ad93dcc-bf5cccb498eac569&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fllvm%2Ftrunk%2Flib%2FCodeGen%2FAsmPrinter%2FDwarfUnit.cpp%3Frev%3D374879%26r1%3D374878%26r2%3D374879%26view%3Ddiff" rel="noreferrer" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=374879&r1=374878&r2=374879&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Oct 15 04:14:35 2019<br>
@@ -47,31 +47,42 @@ using namespace llvm;<br>
 #define DEBUG_TYPE "dwarfdebug"<br>
<br>
 DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,<br>
-                                       DwarfCompileUnit &CU,<br>
-                                       DIELoc &DIE)<br>
-    : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP),<br>
-      DIE(DIE) {}<br>
+                                       DwarfCompileUnit &CU, DIELoc &DIE)<br>
+    : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP), OutDIE(DIE) {}<br>
<br>
 void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {<br>
-  CU.addUInt(DIE, dwarf::DW_FORM_data1, Op);<br>
+  CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op);<br>
 }<br>
<br>
 void DIEDwarfExpression::emitSigned(int64_t Value) {<br>
-  CU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);<br>
+  CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value);<br>
 }<br>
<br>
 void DIEDwarfExpression::emitUnsigned(uint64_t Value) {<br>
-  CU.addUInt(DIE, dwarf::DW_FORM_udata, Value);<br>
+  CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value);<br>
 }<br>
<br>
 void DIEDwarfExpression::emitData1(uint8_t Value) {<br>
-  CU.addUInt(DIE, dwarf::DW_FORM_data1, Value);<br>
+  CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value);<br>
 }<br>
<br>
 void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {<br>
-  CU.addBaseTypeRef(DIE, Idx);<br>
+  CU.addBaseTypeRef(getActiveDIE(), Idx);<br>
 }<br>
<br>
+void DIEDwarfExpression::enableTemporaryBuffer() {<br>
+  assert(!IsBuffering && "Already buffering?");<br>
+  IsBuffering = true;<br>
+}<br>
+<br>
+void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }<br>
+<br>
+unsigned DIEDwarfExpression::getTemporaryBufferSize() {<br>
+  return TmpDIE.ComputeSize(&AP);<br>
+}<br>
+<br>
+void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }<br>
+<br>
 bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,<br>
                                          unsigned MachineReg) {<br>
   return MachineReg == TRI.getFrameRegister(*AP.MF);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://protect2.fireeye.com/v1/url?k=0a9f1ec6-56153c10-0a9f5e5d-0cc47ad93dcc-a712edad1cf16b56&q=1&e=c65dc9d3-d927-42f6-8d8c-01594b6010c8&u=https%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fllvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote>
</div>
</div>
</blockquote>
</body>
</html>