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 168bcb0991SDimitry Andric #include "ByteStreamer.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 200b57cec5SDimitry Andric #include <cassert> 210b57cec5SDimitry Andric #include <cstdint> 220b57cec5SDimitry Andric #include <iterator> 23*bdd1243dSDimitry Andric #include <optional> 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace llvm { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric class AsmPrinter; 280b57cec5SDimitry Andric class APInt; 290b57cec5SDimitry Andric class DwarfCompileUnit; 300b57cec5SDimitry Andric class DIELoc; 310b57cec5SDimitry Andric class TargetRegisterInfo; 325ffd83dbSDimitry Andric class MachineLocation; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric /// Base class containing the logic for constructing DWARF expressions 350b57cec5SDimitry Andric /// independently of whether they are emitted into a DIE or into a .debug_loc 360b57cec5SDimitry Andric /// entry. 378bcb0991SDimitry Andric /// 388bcb0991SDimitry Andric /// Some DWARF operations, e.g. DW_OP_entry_value, need to calculate the size 398bcb0991SDimitry Andric /// of a succeeding DWARF block before the latter is emitted to the output. 408bcb0991SDimitry Andric /// To handle such cases, data can conditionally be emitted to a temporary 418bcb0991SDimitry Andric /// buffer, which can later on be committed to the main output. The size of the 428bcb0991SDimitry Andric /// temporary buffer is queryable, allowing for the size of the data to be 438bcb0991SDimitry Andric /// emitted before the data is committed. 440b57cec5SDimitry Andric class DwarfExpression { 450b57cec5SDimitry Andric protected: 460b57cec5SDimitry Andric /// Holds information about all subregisters comprising a register location. 470b57cec5SDimitry Andric struct Register { 480b57cec5SDimitry Andric int DwarfRegNo; 495ffd83dbSDimitry Andric unsigned SubRegSize; 500b57cec5SDimitry Andric const char *Comment; 515ffd83dbSDimitry Andric 525ffd83dbSDimitry Andric /// Create a full register, no extra DW_OP_piece operators necessary. createRegisterRegister535ffd83dbSDimitry Andric static Register createRegister(int RegNo, const char *Comment) { 545ffd83dbSDimitry Andric return {RegNo, 0, Comment}; 555ffd83dbSDimitry Andric } 565ffd83dbSDimitry Andric 575ffd83dbSDimitry Andric /// Create a subregister that needs a DW_OP_piece operator with SizeInBits. createSubRegisterRegister585ffd83dbSDimitry Andric static Register createSubRegister(int RegNo, unsigned SizeInBits, 595ffd83dbSDimitry Andric const char *Comment) { 605ffd83dbSDimitry Andric return {RegNo, SizeInBits, Comment}; 615ffd83dbSDimitry Andric } 625ffd83dbSDimitry Andric isSubRegisterRegister635ffd83dbSDimitry Andric bool isSubRegister() const { return SubRegSize; } 640b57cec5SDimitry Andric }; 650b57cec5SDimitry Andric 668bcb0991SDimitry Andric /// Whether we are currently emitting an entry value operation. 678bcb0991SDimitry Andric bool IsEmittingEntryValue = false; 688bcb0991SDimitry Andric 690b57cec5SDimitry Andric DwarfCompileUnit &CU; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// The register location, if any. 720b57cec5SDimitry Andric SmallVector<Register, 2> DwarfRegs; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric /// Current Fragment Offset in Bits. 750b57cec5SDimitry Andric uint64_t OffsetInBits = 0; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister. 780b57cec5SDimitry Andric unsigned SubRegisterSizeInBits : 16; 790b57cec5SDimitry Andric unsigned SubRegisterOffsetInBits : 16; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// The kind of location description being produced. 820b57cec5SDimitry Andric enum { Unknown = 0, Register, Memory, Implicit }; 830b57cec5SDimitry Andric 845ffd83dbSDimitry Andric /// Additional location flags which may be combined with any location kind. 855ffd83dbSDimitry Andric /// Currently, entry values are not supported for the Memory location kind. 865ffd83dbSDimitry Andric enum { EntryValue = 1 << 0, Indirect = 1 << 1, CallSiteParamValue = 1 << 2 }; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric unsigned LocationKind : 3; 89fe6060f1SDimitry Andric unsigned SavedLocationKind : 3; 905ffd83dbSDimitry Andric unsigned LocationFlags : 3; 910b57cec5SDimitry Andric unsigned DwarfVersion : 4; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric public: 945ffd83dbSDimitry Andric /// Set the location (\p Loc) and \ref DIExpression (\p DIExpr) to describe. 955ffd83dbSDimitry Andric void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr); 960b57cec5SDimitry Andric isUnknownLocation()975ffd83dbSDimitry Andric bool isUnknownLocation() const { return LocationKind == Unknown; } 980b57cec5SDimitry Andric isMemoryLocation()995ffd83dbSDimitry Andric bool isMemoryLocation() const { return LocationKind == Memory; } 1000b57cec5SDimitry Andric isRegisterLocation()1015ffd83dbSDimitry Andric bool isRegisterLocation() const { return LocationKind == Register; } 1020b57cec5SDimitry Andric isImplicitLocation()1035ffd83dbSDimitry Andric bool isImplicitLocation() const { return LocationKind == Implicit; } 1040b57cec5SDimitry Andric isEntryValue()1055ffd83dbSDimitry Andric bool isEntryValue() const { return LocationFlags & EntryValue; } 1065ffd83dbSDimitry Andric isIndirect()1075ffd83dbSDimitry Andric bool isIndirect() const { return LocationFlags & Indirect; } 1085ffd83dbSDimitry Andric isParameterValue()1095ffd83dbSDimitry Andric bool isParameterValue() { return LocationFlags & CallSiteParamValue; } 1108bcb0991SDimitry Andric 111*bdd1243dSDimitry Andric std::optional<uint8_t> TagOffset; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric protected: 1140b57cec5SDimitry Andric /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed 1150b57cec5SDimitry Andric /// to represent a subregister. setSubRegisterPiece(unsigned SizeInBits,unsigned OffsetInBits)1160b57cec5SDimitry Andric void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) { 1170b57cec5SDimitry Andric assert(SizeInBits < 65536 && OffsetInBits < 65536); 1180b57cec5SDimitry Andric SubRegisterSizeInBits = SizeInBits; 1190b57cec5SDimitry Andric SubRegisterOffsetInBits = OffsetInBits; 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric /// Add masking operations to stencil out a subregister. 1230b57cec5SDimitry Andric void maskSubRegister(); 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// Output a dwarf operand and an optional assembler comment. 1260b57cec5SDimitry Andric virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// Emit a raw signed value. 1290b57cec5SDimitry Andric virtual void emitSigned(int64_t Value) = 0; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// Emit a raw unsigned value. 1320b57cec5SDimitry Andric virtual void emitUnsigned(uint64_t Value) = 0; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric virtual void emitData1(uint8_t Value) = 0; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric virtual void emitBaseTypeRef(uint64_t Idx) = 0; 1370b57cec5SDimitry Andric 1388bcb0991SDimitry Andric /// Start emitting data to the temporary buffer. The data stored in the 1398bcb0991SDimitry Andric /// temporary buffer can be committed to the main output using 1408bcb0991SDimitry Andric /// commitTemporaryBuffer(). 1418bcb0991SDimitry Andric virtual void enableTemporaryBuffer() = 0; 1428bcb0991SDimitry Andric 1438bcb0991SDimitry Andric /// Disable emission to the temporary buffer. This does not commit data 1448bcb0991SDimitry Andric /// in the temporary buffer to the main output. 1458bcb0991SDimitry Andric virtual void disableTemporaryBuffer() = 0; 1468bcb0991SDimitry Andric 1478bcb0991SDimitry Andric /// Return the emitted size, in number of bytes, for the data stored in the 1488bcb0991SDimitry Andric /// temporary buffer. 1498bcb0991SDimitry Andric virtual unsigned getTemporaryBufferSize() = 0; 1508bcb0991SDimitry Andric 1518bcb0991SDimitry Andric /// Commit the data stored in the temporary buffer to the main output. 1528bcb0991SDimitry Andric virtual void commitTemporaryBuffer() = 0; 1538bcb0991SDimitry Andric 1540b57cec5SDimitry Andric /// Emit a normalized unsigned constant. 1550b57cec5SDimitry Andric void emitConstu(uint64_t Value); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric /// Return whether the given machine register is the frame register in the 1580b57cec5SDimitry Andric /// current function. 1595ffd83dbSDimitry Andric virtual bool isFrameRegister(const TargetRegisterInfo &TRI, 160e8d8bef9SDimitry Andric llvm::Register MachineReg) = 0; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF 1630b57cec5SDimitry Andric /// register location description. 1640b57cec5SDimitry Andric void addReg(int DwarfReg, const char *Comment = nullptr); 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric /// Emit a DW_OP_breg operation. 1670b57cec5SDimitry Andric void addBReg(int DwarfReg, int Offset); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric /// Emit DW_OP_fbreg <Offset>. 1700b57cec5SDimitry Andric void addFBReg(int Offset); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric /// Emit a partial DWARF register operation. 1730b57cec5SDimitry Andric /// 1740b57cec5SDimitry Andric /// \param MachineReg The register number. 1750b57cec5SDimitry Andric /// \param MaxSize If the register must be composed from 1760b57cec5SDimitry Andric /// sub-registers this is an upper bound 1770b57cec5SDimitry Andric /// for how many bits the emitted DW_OP_piece 1780b57cec5SDimitry Andric /// may cover. 1790b57cec5SDimitry Andric /// 1800b57cec5SDimitry Andric /// If size and offset is zero an operation for the entire register is 1810b57cec5SDimitry Andric /// emitted: Some targets do not provide a DWARF register number for every 1820b57cec5SDimitry Andric /// register. If this is the case, this function will attempt to emit a DWARF 1830b57cec5SDimitry Andric /// register by emitting a fragment of a super-register or by piecing together 1840b57cec5SDimitry Andric /// multiple subregisters that alias the register. 1850b57cec5SDimitry Andric /// 1860b57cec5SDimitry Andric /// \return false if no DWARF register exists for MachineReg. 187e8d8bef9SDimitry Andric bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, 1880b57cec5SDimitry Andric unsigned MaxSize = ~1U); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment. 1910b57cec5SDimitry Andric /// \param OffsetInBits This is an optional offset into the location that 1920b57cec5SDimitry Andric /// is at the top of the DWARF stack. 1930b57cec5SDimitry Andric void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric /// Emit a shift-right dwarf operation. 1960b57cec5SDimitry Andric void addShr(unsigned ShiftBy); 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric /// Emit a bitwise and dwarf operation. 1990b57cec5SDimitry Andric void addAnd(unsigned Mask); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric /// Emit a DW_OP_stack_value, if supported. 2020b57cec5SDimitry Andric /// 2030b57cec5SDimitry Andric /// The proper way to describe a constant value is DW_OP_constu <const>, 2040b57cec5SDimitry Andric /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available 2050b57cec5SDimitry Andric /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for 2060b57cec5SDimitry Andric /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const 2070b57cec5SDimitry Andric /// <const> actually describes a value at a constant address, not a constant 2080b57cec5SDimitry Andric /// value. However, in the past there was no better way to describe a 2090b57cec5SDimitry Andric /// constant value, so the producers and consumers started to rely on 2100b57cec5SDimitry Andric /// heuristics to disambiguate the value vs. location status of the 2110b57cec5SDimitry Andric /// expression. See PR21176 for more details. 2120b57cec5SDimitry Andric void addStackValue(); 2130b57cec5SDimitry Andric 2148bcb0991SDimitry Andric /// Finalize an entry value by emitting its size operand, and committing the 2158bcb0991SDimitry Andric /// DWARF block which has been emitted to the temporary buffer. 2168bcb0991SDimitry Andric void finalizeEntryValue(); 2178bcb0991SDimitry Andric 2185ffd83dbSDimitry Andric /// Cancel the emission of an entry value. 2195ffd83dbSDimitry Andric void cancelEntryValue(); 2205ffd83dbSDimitry Andric 2210b57cec5SDimitry Andric ~DwarfExpression() = default; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric public: DwarfExpression(unsigned DwarfVersion,DwarfCompileUnit & CU)2240b57cec5SDimitry Andric DwarfExpression(unsigned DwarfVersion, DwarfCompileUnit &CU) 2250b57cec5SDimitry Andric : CU(CU), SubRegisterSizeInBits(0), SubRegisterOffsetInBits(0), 226fe6060f1SDimitry Andric LocationKind(Unknown), SavedLocationKind(Unknown), 227fe6060f1SDimitry Andric LocationFlags(Unknown), DwarfVersion(DwarfVersion) {} 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// This needs to be called last to commit any pending changes. 2300b57cec5SDimitry Andric void finalize(); 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /// Emit a signed constant. 2330b57cec5SDimitry Andric void addSignedConstant(int64_t Value); 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric /// Emit an unsigned constant. 2360b57cec5SDimitry Andric void addUnsignedConstant(uint64_t Value); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// Emit an unsigned constant. 2390b57cec5SDimitry Andric void addUnsignedConstant(const APInt &Value); 2400b57cec5SDimitry Andric 241e8d8bef9SDimitry Andric /// Emit an floating point constant. 242e8d8bef9SDimitry Andric void addConstantFP(const APFloat &Value, const AsmPrinter &AP); 243e8d8bef9SDimitry Andric 2440b57cec5SDimitry Andric /// Lock this down to become a memory location description. setMemoryLocationKind()2450b57cec5SDimitry Andric void setMemoryLocationKind() { 2460b57cec5SDimitry Andric assert(isUnknownLocation()); 2470b57cec5SDimitry Andric LocationKind = Memory; 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric /// Lock this down to become an entry value location. 2515ffd83dbSDimitry Andric void setEntryValueFlags(const MachineLocation &Loc); 2520b57cec5SDimitry Andric 2538bcb0991SDimitry Andric /// Lock this down to become a call site parameter location. setCallSiteParamValueFlag()2545ffd83dbSDimitry Andric void setCallSiteParamValueFlag() { LocationFlags |= CallSiteParamValue; } 2558bcb0991SDimitry Andric 2560b57cec5SDimitry Andric /// Emit a machine register location. As an optimization this may also consume 2570b57cec5SDimitry Andric /// the prefix of a DwarfExpression if a more efficient representation for 2580b57cec5SDimitry Andric /// combining the register location and the first operation exists. 2590b57cec5SDimitry Andric /// 2600b57cec5SDimitry Andric /// \param FragmentOffsetInBits If this is one fragment out of a 2610b57cec5SDimitry Andric /// fragmented 2620b57cec5SDimitry Andric /// location, this is the offset of the 2630b57cec5SDimitry Andric /// fragment inside the entire variable. 2640b57cec5SDimitry Andric /// \return false if no DWARF register exists 2650b57cec5SDimitry Andric /// for MachineReg. 2660b57cec5SDimitry Andric bool addMachineRegExpression(const TargetRegisterInfo &TRI, 267e8d8bef9SDimitry Andric DIExpressionCursor &Expr, 268e8d8bef9SDimitry Andric llvm::Register MachineReg, 2690b57cec5SDimitry Andric unsigned FragmentOffsetInBits = 0); 2700b57cec5SDimitry Andric 2718bcb0991SDimitry Andric /// Begin emission of an entry value dwarf operation. The entry value's 2728bcb0991SDimitry Andric /// first operand is the size of the DWARF block (its second operand), 2738bcb0991SDimitry Andric /// which needs to be calculated at time of emission, so we don't emit 2748bcb0991SDimitry Andric /// any operands here. 2758bcb0991SDimitry Andric void beginEntryValueExpression(DIExpressionCursor &ExprCursor); 2760b57cec5SDimitry Andric 2775ffd83dbSDimitry Andric /// Return the index of a base type with the given properties and 2785ffd83dbSDimitry Andric /// create one if necessary. 2795ffd83dbSDimitry Andric unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding); 2805ffd83dbSDimitry Andric 2819738bc28SDimitry Andric /// Emit all remaining operations in the DIExpressionCursor. The 2829738bc28SDimitry Andric /// cursor must not contain any DW_OP_LLVM_arg operations. 2839738bc28SDimitry Andric void addExpression(DIExpressionCursor &&Expr); 2849738bc28SDimitry Andric 2850b57cec5SDimitry Andric /// Emit all remaining operations in the DIExpressionCursor. 2869738bc28SDimitry Andric /// DW_OP_LLVM_arg operations are resolved by calling (\p InsertArg). 2879738bc28SDimitry Andric // 2889738bc28SDimitry Andric /// \return false if any call to (\p InsertArg) returns false. 2899738bc28SDimitry Andric bool addExpression( 2909738bc28SDimitry Andric DIExpressionCursor &&Expr, 291fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to 2940b57cec5SDimitry Andric /// the fragment described by \c Expr. 2950b57cec5SDimitry Andric void addFragmentOffset(const DIExpression *Expr); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric void emitLegacySExt(unsigned FromBits); 2980b57cec5SDimitry Andric void emitLegacyZExt(unsigned FromBits); 299480093f4SDimitry Andric 300480093f4SDimitry Andric /// Emit location information expressed via WebAssembly location + offset 301480093f4SDimitry Andric /// The Index is an identifier for locals, globals or operand stack. 3025ffd83dbSDimitry Andric void addWasmLocation(unsigned Index, uint64_t Offset); 3030b57cec5SDimitry Andric }; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric /// DwarfExpression implementation for .debug_loc entries. 3060b57cec5SDimitry Andric class DebugLocDwarfExpression final : public DwarfExpression { 3078bcb0991SDimitry Andric 3088bcb0991SDimitry Andric struct TempBuffer { 3098bcb0991SDimitry Andric SmallString<32> Bytes; 3108bcb0991SDimitry Andric std::vector<std::string> Comments; 3118bcb0991SDimitry Andric BufferByteStreamer BS; 3128bcb0991SDimitry Andric TempBufferTempBuffer3138bcb0991SDimitry Andric TempBuffer(bool GenerateComments) : BS(Bytes, Comments, GenerateComments) {} 3148bcb0991SDimitry Andric }; 3158bcb0991SDimitry Andric 3168bcb0991SDimitry Andric std::unique_ptr<TempBuffer> TmpBuf; 3178bcb0991SDimitry Andric BufferByteStreamer &OutBS; 3188bcb0991SDimitry Andric bool IsBuffering = false; 3198bcb0991SDimitry Andric 3208bcb0991SDimitry Andric /// Return the byte streamer that currently is being emitted to. getActiveStreamer()3218bcb0991SDimitry Andric ByteStreamer &getActiveStreamer() { return IsBuffering ? TmpBuf->BS : OutBS; } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric void emitOp(uint8_t Op, const char *Comment = nullptr) override; 3240b57cec5SDimitry Andric void emitSigned(int64_t Value) override; 3250b57cec5SDimitry Andric void emitUnsigned(uint64_t Value) override; 3260b57cec5SDimitry Andric void emitData1(uint8_t Value) override; 3270b57cec5SDimitry Andric void emitBaseTypeRef(uint64_t Idx) override; 3288bcb0991SDimitry Andric 3298bcb0991SDimitry Andric void enableTemporaryBuffer() override; 3308bcb0991SDimitry Andric void disableTemporaryBuffer() override; 3318bcb0991SDimitry Andric unsigned getTemporaryBufferSize() override; 3328bcb0991SDimitry Andric void commitTemporaryBuffer() override; 3338bcb0991SDimitry Andric 3340b57cec5SDimitry Andric bool isFrameRegister(const TargetRegisterInfo &TRI, 335e8d8bef9SDimitry Andric llvm::Register MachineReg) override; 3365ffd83dbSDimitry Andric 3370b57cec5SDimitry Andric public: DebugLocDwarfExpression(unsigned DwarfVersion,BufferByteStreamer & BS,DwarfCompileUnit & CU)3388bcb0991SDimitry Andric DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS, 3398bcb0991SDimitry Andric DwarfCompileUnit &CU) 3408bcb0991SDimitry Andric : DwarfExpression(DwarfVersion, CU), OutBS(BS) {} 3410b57cec5SDimitry Andric }; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric /// DwarfExpression implementation for singular DW_AT_location. 3440b57cec5SDimitry Andric class DIEDwarfExpression final : public DwarfExpression { 3450b57cec5SDimitry Andric const AsmPrinter &AP; 3468bcb0991SDimitry Andric DIELoc &OutDIE; 3478bcb0991SDimitry Andric DIELoc TmpDIE; 3488bcb0991SDimitry Andric bool IsBuffering = false; 3498bcb0991SDimitry Andric 3508bcb0991SDimitry Andric /// Return the DIE that currently is being emitted to. getActiveDIE()3518bcb0991SDimitry Andric DIELoc &getActiveDIE() { return IsBuffering ? TmpDIE : OutDIE; } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric void emitOp(uint8_t Op, const char *Comment = nullptr) override; 3540b57cec5SDimitry Andric void emitSigned(int64_t Value) override; 3550b57cec5SDimitry Andric void emitUnsigned(uint64_t Value) override; 3560b57cec5SDimitry Andric void emitData1(uint8_t Value) override; 3570b57cec5SDimitry Andric void emitBaseTypeRef(uint64_t Idx) override; 3588bcb0991SDimitry Andric 3598bcb0991SDimitry Andric void enableTemporaryBuffer() override; 3608bcb0991SDimitry Andric void disableTemporaryBuffer() override; 3618bcb0991SDimitry Andric unsigned getTemporaryBufferSize() override; 3628bcb0991SDimitry Andric void commitTemporaryBuffer() override; 3638bcb0991SDimitry Andric 3640b57cec5SDimitry Andric bool isFrameRegister(const TargetRegisterInfo &TRI, 365e8d8bef9SDimitry Andric llvm::Register MachineReg) override; 3665ffd83dbSDimitry Andric 3670b57cec5SDimitry Andric public: 3680b57cec5SDimitry Andric DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE); 3690b57cec5SDimitry Andric finalize()3700b57cec5SDimitry Andric DIELoc *finalize() { 3710b57cec5SDimitry Andric DwarfExpression::finalize(); 3728bcb0991SDimitry Andric return &OutDIE; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric }; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric } // end namespace llvm 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 379