10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains support for writing dwarf compile unit. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 150b57cec5SDimitry Andric 16*8bcb0991SDimitry Andric #include "ByteStreamer.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/None.h" 190b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 210b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 220b57cec5SDimitry Andric #include <cassert> 230b57cec5SDimitry Andric #include <cstdint> 240b57cec5SDimitry Andric #include <iterator> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class AsmPrinter; 290b57cec5SDimitry Andric class APInt; 300b57cec5SDimitry Andric class DwarfCompileUnit; 310b57cec5SDimitry Andric class DIELoc; 320b57cec5SDimitry Andric class TargetRegisterInfo; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric /// Holds a DIExpression and keeps track of how many operands have been consumed 350b57cec5SDimitry Andric /// so far. 360b57cec5SDimitry Andric class DIExpressionCursor { 370b57cec5SDimitry Andric DIExpression::expr_op_iterator Start, End; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric public: 400b57cec5SDimitry Andric DIExpressionCursor(const DIExpression *Expr) { 410b57cec5SDimitry Andric if (!Expr) { 420b57cec5SDimitry Andric assert(Start == End); 430b57cec5SDimitry Andric return; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric Start = Expr->expr_op_begin(); 460b57cec5SDimitry Andric End = Expr->expr_op_end(); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric DIExpressionCursor(ArrayRef<uint64_t> Expr) 500b57cec5SDimitry Andric : Start(Expr.begin()), End(Expr.end()) {} 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric DIExpressionCursor(const DIExpressionCursor &) = default; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric /// Consume one operation. 550b57cec5SDimitry Andric Optional<DIExpression::ExprOperand> take() { 560b57cec5SDimitry Andric if (Start == End) 570b57cec5SDimitry Andric return None; 580b57cec5SDimitry Andric return *(Start++); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric /// Consume N operations. 620b57cec5SDimitry Andric void consume(unsigned N) { std::advance(Start, N); } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /// Return the current operation. 650b57cec5SDimitry Andric Optional<DIExpression::ExprOperand> peek() const { 660b57cec5SDimitry Andric if (Start == End) 670b57cec5SDimitry Andric return None; 680b57cec5SDimitry Andric return *(Start); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// Return the next operation. 720b57cec5SDimitry Andric Optional<DIExpression::ExprOperand> peekNext() const { 730b57cec5SDimitry Andric if (Start == End) 740b57cec5SDimitry Andric return None; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric auto Next = Start.getNext(); 770b57cec5SDimitry Andric if (Next == End) 780b57cec5SDimitry Andric return None; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric return *Next; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric /// Determine whether there are any operations left in this expression. 840b57cec5SDimitry Andric operator bool() const { return Start != End; } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric DIExpression::expr_op_iterator begin() const { return Start; } 870b57cec5SDimitry Andric DIExpression::expr_op_iterator end() const { return End; } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// Retrieve the fragment information, if any. 900b57cec5SDimitry Andric Optional<DIExpression::FragmentInfo> getFragmentInfo() const { 910b57cec5SDimitry Andric return DIExpression::getFragmentInfo(Start, End); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric }; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// Base class containing the logic for constructing DWARF expressions 960b57cec5SDimitry Andric /// independently of whether they are emitted into a DIE or into a .debug_loc 970b57cec5SDimitry Andric /// entry. 98*8bcb0991SDimitry Andric /// 99*8bcb0991SDimitry Andric /// Some DWARF operations, e.g. DW_OP_entry_value, need to calculate the size 100*8bcb0991SDimitry Andric /// of a succeeding DWARF block before the latter is emitted to the output. 101*8bcb0991SDimitry Andric /// To handle such cases, data can conditionally be emitted to a temporary 102*8bcb0991SDimitry Andric /// buffer, which can later on be committed to the main output. The size of the 103*8bcb0991SDimitry Andric /// temporary buffer is queryable, allowing for the size of the data to be 104*8bcb0991SDimitry Andric /// emitted before the data is committed. 1050b57cec5SDimitry Andric class DwarfExpression { 1060b57cec5SDimitry Andric protected: 1070b57cec5SDimitry Andric /// Holds information about all subregisters comprising a register location. 1080b57cec5SDimitry Andric struct Register { 1090b57cec5SDimitry Andric int DwarfRegNo; 1100b57cec5SDimitry Andric unsigned Size; 1110b57cec5SDimitry Andric const char *Comment; 1120b57cec5SDimitry Andric }; 1130b57cec5SDimitry Andric 114*8bcb0991SDimitry Andric /// Whether we are currently emitting an entry value operation. 115*8bcb0991SDimitry Andric bool IsEmittingEntryValue = false; 116*8bcb0991SDimitry Andric 1170b57cec5SDimitry Andric DwarfCompileUnit &CU; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric /// The register location, if any. 1200b57cec5SDimitry Andric SmallVector<Register, 2> DwarfRegs; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric /// Current Fragment Offset in Bits. 1230b57cec5SDimitry Andric uint64_t OffsetInBits = 0; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister. 1260b57cec5SDimitry Andric unsigned SubRegisterSizeInBits : 16; 1270b57cec5SDimitry Andric unsigned SubRegisterOffsetInBits : 16; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric /// The kind of location description being produced. 1300b57cec5SDimitry Andric enum { Unknown = 0, Register, Memory, Implicit }; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric /// The flags of location description being produced. 133*8bcb0991SDimitry Andric enum { EntryValue = 1, CallSiteParamValue }; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric unsigned LocationKind : 3; 1360b57cec5SDimitry Andric unsigned LocationFlags : 2; 1370b57cec5SDimitry Andric unsigned DwarfVersion : 4; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric public: 1400b57cec5SDimitry Andric bool isUnknownLocation() const { 1410b57cec5SDimitry Andric return LocationKind == Unknown; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric bool isMemoryLocation() const { 1450b57cec5SDimitry Andric return LocationKind == Memory; 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric bool isRegisterLocation() const { 1490b57cec5SDimitry Andric return LocationKind == Register; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric bool isImplicitLocation() const { 1530b57cec5SDimitry Andric return LocationKind == Implicit; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric bool isEntryValue() const { 1570b57cec5SDimitry Andric return LocationFlags & EntryValue; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 160*8bcb0991SDimitry Andric bool isParameterValue() { 161*8bcb0991SDimitry Andric return LocationFlags & CallSiteParamValue; 162*8bcb0991SDimitry Andric } 163*8bcb0991SDimitry Andric 1640b57cec5SDimitry Andric Optional<uint8_t> TagOffset; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric protected: 1670b57cec5SDimitry Andric /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed 1680b57cec5SDimitry Andric /// to represent a subregister. 1690b57cec5SDimitry Andric void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) { 1700b57cec5SDimitry Andric assert(SizeInBits < 65536 && OffsetInBits < 65536); 1710b57cec5SDimitry Andric SubRegisterSizeInBits = SizeInBits; 1720b57cec5SDimitry Andric SubRegisterOffsetInBits = OffsetInBits; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// Add masking operations to stencil out a subregister. 1760b57cec5SDimitry Andric void maskSubRegister(); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric /// Output a dwarf operand and an optional assembler comment. 1790b57cec5SDimitry Andric virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /// Emit a raw signed value. 1820b57cec5SDimitry Andric virtual void emitSigned(int64_t Value) = 0; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Emit a raw unsigned value. 1850b57cec5SDimitry Andric virtual void emitUnsigned(uint64_t Value) = 0; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric virtual void emitData1(uint8_t Value) = 0; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric virtual void emitBaseTypeRef(uint64_t Idx) = 0; 1900b57cec5SDimitry Andric 191*8bcb0991SDimitry Andric /// Start emitting data to the temporary buffer. The data stored in the 192*8bcb0991SDimitry Andric /// temporary buffer can be committed to the main output using 193*8bcb0991SDimitry Andric /// commitTemporaryBuffer(). 194*8bcb0991SDimitry Andric virtual void enableTemporaryBuffer() = 0; 195*8bcb0991SDimitry Andric 196*8bcb0991SDimitry Andric /// Disable emission to the temporary buffer. This does not commit data 197*8bcb0991SDimitry Andric /// in the temporary buffer to the main output. 198*8bcb0991SDimitry Andric virtual void disableTemporaryBuffer() = 0; 199*8bcb0991SDimitry Andric 200*8bcb0991SDimitry Andric /// Return the emitted size, in number of bytes, for the data stored in the 201*8bcb0991SDimitry Andric /// temporary buffer. 202*8bcb0991SDimitry Andric virtual unsigned getTemporaryBufferSize() = 0; 203*8bcb0991SDimitry Andric 204*8bcb0991SDimitry Andric /// Commit the data stored in the temporary buffer to the main output. 205*8bcb0991SDimitry Andric virtual void commitTemporaryBuffer() = 0; 206*8bcb0991SDimitry Andric 2070b57cec5SDimitry Andric /// Emit a normalized unsigned constant. 2080b57cec5SDimitry Andric void emitConstu(uint64_t Value); 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// Return whether the given machine register is the frame register in the 2110b57cec5SDimitry Andric /// current function. 2120b57cec5SDimitry Andric virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF 2150b57cec5SDimitry Andric /// register location description. 2160b57cec5SDimitry Andric void addReg(int DwarfReg, const char *Comment = nullptr); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric /// Emit a DW_OP_breg operation. 2190b57cec5SDimitry Andric void addBReg(int DwarfReg, int Offset); 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric /// Emit DW_OP_fbreg <Offset>. 2220b57cec5SDimitry Andric void addFBReg(int Offset); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric /// Emit a partial DWARF register operation. 2250b57cec5SDimitry Andric /// 2260b57cec5SDimitry Andric /// \param MachineReg The register number. 2270b57cec5SDimitry Andric /// \param MaxSize If the register must be composed from 2280b57cec5SDimitry Andric /// sub-registers this is an upper bound 2290b57cec5SDimitry Andric /// for how many bits the emitted DW_OP_piece 2300b57cec5SDimitry Andric /// may cover. 2310b57cec5SDimitry Andric /// 2320b57cec5SDimitry Andric /// If size and offset is zero an operation for the entire register is 2330b57cec5SDimitry Andric /// emitted: Some targets do not provide a DWARF register number for every 2340b57cec5SDimitry Andric /// register. If this is the case, this function will attempt to emit a DWARF 2350b57cec5SDimitry Andric /// register by emitting a fragment of a super-register or by piecing together 2360b57cec5SDimitry Andric /// multiple subregisters that alias the register. 2370b57cec5SDimitry Andric /// 2380b57cec5SDimitry Andric /// \return false if no DWARF register exists for MachineReg. 2390b57cec5SDimitry Andric bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, 2400b57cec5SDimitry Andric unsigned MaxSize = ~1U); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment. 2430b57cec5SDimitry Andric /// \param OffsetInBits This is an optional offset into the location that 2440b57cec5SDimitry Andric /// is at the top of the DWARF stack. 2450b57cec5SDimitry Andric void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0); 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric /// Emit a shift-right dwarf operation. 2480b57cec5SDimitry Andric void addShr(unsigned ShiftBy); 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric /// Emit a bitwise and dwarf operation. 2510b57cec5SDimitry Andric void addAnd(unsigned Mask); 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric /// Emit a DW_OP_stack_value, if supported. 2540b57cec5SDimitry Andric /// 2550b57cec5SDimitry Andric /// The proper way to describe a constant value is DW_OP_constu <const>, 2560b57cec5SDimitry Andric /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available 2570b57cec5SDimitry Andric /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for 2580b57cec5SDimitry Andric /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const 2590b57cec5SDimitry Andric /// <const> actually describes a value at a constant address, not a constant 2600b57cec5SDimitry Andric /// value. However, in the past there was no better way to describe a 2610b57cec5SDimitry Andric /// constant value, so the producers and consumers started to rely on 2620b57cec5SDimitry Andric /// heuristics to disambiguate the value vs. location status of the 2630b57cec5SDimitry Andric /// expression. See PR21176 for more details. 2640b57cec5SDimitry Andric void addStackValue(); 2650b57cec5SDimitry Andric 266*8bcb0991SDimitry Andric /// Finalize an entry value by emitting its size operand, and committing the 267*8bcb0991SDimitry Andric /// DWARF block which has been emitted to the temporary buffer. 268*8bcb0991SDimitry Andric void finalizeEntryValue(); 269*8bcb0991SDimitry Andric 2700b57cec5SDimitry Andric ~DwarfExpression() = default; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric public: 2730b57cec5SDimitry Andric DwarfExpression(unsigned DwarfVersion, DwarfCompileUnit &CU) 2740b57cec5SDimitry Andric : CU(CU), SubRegisterSizeInBits(0), SubRegisterOffsetInBits(0), 2750b57cec5SDimitry Andric LocationKind(Unknown), LocationFlags(Unknown), 2760b57cec5SDimitry Andric DwarfVersion(DwarfVersion) {} 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric /// This needs to be called last to commit any pending changes. 2790b57cec5SDimitry Andric void finalize(); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric /// Emit a signed constant. 2820b57cec5SDimitry Andric void addSignedConstant(int64_t Value); 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric /// Emit an unsigned constant. 2850b57cec5SDimitry Andric void addUnsignedConstant(uint64_t Value); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric /// Emit an unsigned constant. 2880b57cec5SDimitry Andric void addUnsignedConstant(const APInt &Value); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric /// Lock this down to become a memory location description. 2910b57cec5SDimitry Andric void setMemoryLocationKind() { 2920b57cec5SDimitry Andric assert(isUnknownLocation()); 2930b57cec5SDimitry Andric LocationKind = Memory; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric /// Lock this down to become an entry value location. 2970b57cec5SDimitry Andric void setEntryValueFlag() { 2980b57cec5SDimitry Andric LocationFlags |= EntryValue; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 301*8bcb0991SDimitry Andric /// Lock this down to become a call site parameter location. 302*8bcb0991SDimitry Andric void setCallSiteParamValueFlag() { 303*8bcb0991SDimitry Andric LocationFlags |= CallSiteParamValue; 304*8bcb0991SDimitry Andric } 305*8bcb0991SDimitry Andric 3060b57cec5SDimitry Andric /// Emit a machine register location. As an optimization this may also consume 3070b57cec5SDimitry Andric /// the prefix of a DwarfExpression if a more efficient representation for 3080b57cec5SDimitry Andric /// combining the register location and the first operation exists. 3090b57cec5SDimitry Andric /// 3100b57cec5SDimitry Andric /// \param FragmentOffsetInBits If this is one fragment out of a 3110b57cec5SDimitry Andric /// fragmented 3120b57cec5SDimitry Andric /// location, this is the offset of the 3130b57cec5SDimitry Andric /// fragment inside the entire variable. 3140b57cec5SDimitry Andric /// \return false if no DWARF register exists 3150b57cec5SDimitry Andric /// for MachineReg. 3160b57cec5SDimitry Andric bool addMachineRegExpression(const TargetRegisterInfo &TRI, 3170b57cec5SDimitry Andric DIExpressionCursor &Expr, unsigned MachineReg, 3180b57cec5SDimitry Andric unsigned FragmentOffsetInBits = 0); 3190b57cec5SDimitry Andric 320*8bcb0991SDimitry Andric /// Begin emission of an entry value dwarf operation. The entry value's 321*8bcb0991SDimitry Andric /// first operand is the size of the DWARF block (its second operand), 322*8bcb0991SDimitry Andric /// which needs to be calculated at time of emission, so we don't emit 323*8bcb0991SDimitry Andric /// any operands here. 324*8bcb0991SDimitry Andric void beginEntryValueExpression(DIExpressionCursor &ExprCursor); 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric /// Emit all remaining operations in the DIExpressionCursor. 3270b57cec5SDimitry Andric /// 3280b57cec5SDimitry Andric /// \param FragmentOffsetInBits If this is one fragment out of multiple 3290b57cec5SDimitry Andric /// locations, this is the offset of the 3300b57cec5SDimitry Andric /// fragment inside the entire variable. 3310b57cec5SDimitry Andric void addExpression(DIExpressionCursor &&Expr, 3320b57cec5SDimitry Andric unsigned FragmentOffsetInBits = 0); 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to 3350b57cec5SDimitry Andric /// the fragment described by \c Expr. 3360b57cec5SDimitry Andric void addFragmentOffset(const DIExpression *Expr); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric void emitLegacySExt(unsigned FromBits); 3390b57cec5SDimitry Andric void emitLegacyZExt(unsigned FromBits); 3400b57cec5SDimitry Andric }; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric /// DwarfExpression implementation for .debug_loc entries. 3430b57cec5SDimitry Andric class DebugLocDwarfExpression final : public DwarfExpression { 344*8bcb0991SDimitry Andric 345*8bcb0991SDimitry Andric struct TempBuffer { 346*8bcb0991SDimitry Andric SmallString<32> Bytes; 347*8bcb0991SDimitry Andric std::vector<std::string> Comments; 348*8bcb0991SDimitry Andric BufferByteStreamer BS; 349*8bcb0991SDimitry Andric 350*8bcb0991SDimitry Andric TempBuffer(bool GenerateComments) : BS(Bytes, Comments, GenerateComments) {} 351*8bcb0991SDimitry Andric }; 352*8bcb0991SDimitry Andric 353*8bcb0991SDimitry Andric std::unique_ptr<TempBuffer> TmpBuf; 354*8bcb0991SDimitry Andric BufferByteStreamer &OutBS; 355*8bcb0991SDimitry Andric bool IsBuffering = false; 356*8bcb0991SDimitry Andric 357*8bcb0991SDimitry Andric /// Return the byte streamer that currently is being emitted to. 358*8bcb0991SDimitry Andric ByteStreamer &getActiveStreamer() { return IsBuffering ? TmpBuf->BS : OutBS; } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric void emitOp(uint8_t Op, const char *Comment = nullptr) override; 3610b57cec5SDimitry Andric void emitSigned(int64_t Value) override; 3620b57cec5SDimitry Andric void emitUnsigned(uint64_t Value) override; 3630b57cec5SDimitry Andric void emitData1(uint8_t Value) override; 3640b57cec5SDimitry Andric void emitBaseTypeRef(uint64_t Idx) override; 365*8bcb0991SDimitry Andric 366*8bcb0991SDimitry Andric void enableTemporaryBuffer() override; 367*8bcb0991SDimitry Andric void disableTemporaryBuffer() override; 368*8bcb0991SDimitry Andric unsigned getTemporaryBufferSize() override; 369*8bcb0991SDimitry Andric void commitTemporaryBuffer() override; 370*8bcb0991SDimitry Andric 3710b57cec5SDimitry Andric bool isFrameRegister(const TargetRegisterInfo &TRI, 3720b57cec5SDimitry Andric unsigned MachineReg) override; 3730b57cec5SDimitry Andric public: 374*8bcb0991SDimitry Andric DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS, 375*8bcb0991SDimitry Andric DwarfCompileUnit &CU) 376*8bcb0991SDimitry Andric : DwarfExpression(DwarfVersion, CU), OutBS(BS) {} 3770b57cec5SDimitry Andric }; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric /// DwarfExpression implementation for singular DW_AT_location. 3800b57cec5SDimitry Andric class DIEDwarfExpression final : public DwarfExpression { 3810b57cec5SDimitry Andric const AsmPrinter &AP; 382*8bcb0991SDimitry Andric DIELoc &OutDIE; 383*8bcb0991SDimitry Andric DIELoc TmpDIE; 384*8bcb0991SDimitry Andric bool IsBuffering = false; 385*8bcb0991SDimitry Andric 386*8bcb0991SDimitry Andric /// Return the DIE that currently is being emitted to. 387*8bcb0991SDimitry Andric DIELoc &getActiveDIE() { return IsBuffering ? TmpDIE : OutDIE; } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric void emitOp(uint8_t Op, const char *Comment = nullptr) override; 3900b57cec5SDimitry Andric void emitSigned(int64_t Value) override; 3910b57cec5SDimitry Andric void emitUnsigned(uint64_t Value) override; 3920b57cec5SDimitry Andric void emitData1(uint8_t Value) override; 3930b57cec5SDimitry Andric void emitBaseTypeRef(uint64_t Idx) override; 394*8bcb0991SDimitry Andric 395*8bcb0991SDimitry Andric void enableTemporaryBuffer() override; 396*8bcb0991SDimitry Andric void disableTemporaryBuffer() override; 397*8bcb0991SDimitry Andric unsigned getTemporaryBufferSize() override; 398*8bcb0991SDimitry Andric void commitTemporaryBuffer() override; 399*8bcb0991SDimitry Andric 4000b57cec5SDimitry Andric bool isFrameRegister(const TargetRegisterInfo &TRI, 4010b57cec5SDimitry Andric unsigned MachineReg) override; 4020b57cec5SDimitry Andric public: 4030b57cec5SDimitry Andric DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric DIELoc *finalize() { 4060b57cec5SDimitry Andric DwarfExpression::finalize(); 407*8bcb0991SDimitry Andric return &OutDIE; 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric }; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric } // end namespace llvm 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 414