xref: /aosp_15_r20/external/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains support for writing dwarf compile unit.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h"
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker namespace llvm {
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker class AsmPrinter;
23*9880d681SAndroid Build Coastguard Worker class ByteStreamer;
24*9880d681SAndroid Build Coastguard Worker class TargetRegisterInfo;
25*9880d681SAndroid Build Coastguard Worker class DwarfUnit;
26*9880d681SAndroid Build Coastguard Worker class DIELoc;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker /// Base class containing the logic for constructing DWARF expressions
29*9880d681SAndroid Build Coastguard Worker /// independently of whether they are emitted into a DIE or into a .debug_loc
30*9880d681SAndroid Build Coastguard Worker /// entry.
31*9880d681SAndroid Build Coastguard Worker class DwarfExpression {
32*9880d681SAndroid Build Coastguard Worker protected:
33*9880d681SAndroid Build Coastguard Worker   // Various convenience accessors that extract things out of AsmPrinter.
34*9880d681SAndroid Build Coastguard Worker   unsigned DwarfVersion;
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker public:
DwarfExpression(unsigned DwarfVersion)37*9880d681SAndroid Build Coastguard Worker   DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
~DwarfExpression()38*9880d681SAndroid Build Coastguard Worker   virtual ~DwarfExpression() {}
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   /// Output a dwarf operand and an optional assembler comment.
41*9880d681SAndroid Build Coastguard Worker   virtual void EmitOp(uint8_t Op, const char *Comment = nullptr) = 0;
42*9880d681SAndroid Build Coastguard Worker   /// Emit a raw signed value.
43*9880d681SAndroid Build Coastguard Worker   virtual void EmitSigned(int64_t Value) = 0;
44*9880d681SAndroid Build Coastguard Worker   /// Emit a raw unsigned value.
45*9880d681SAndroid Build Coastguard Worker   virtual void EmitUnsigned(uint64_t Value) = 0;
46*9880d681SAndroid Build Coastguard Worker   /// Return whether the given machine register is the frame register in the
47*9880d681SAndroid Build Coastguard Worker   /// current function.
48*9880d681SAndroid Build Coastguard Worker   virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker   /// Emit a dwarf register operation.
51*9880d681SAndroid Build Coastguard Worker   void AddReg(int DwarfReg, const char *Comment = nullptr);
52*9880d681SAndroid Build Coastguard Worker   /// Emit an (double-)indirect dwarf register operation.
53*9880d681SAndroid Build Coastguard Worker   void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false);
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   /// Emit a dwarf register operation for describing
56*9880d681SAndroid Build Coastguard Worker   /// - a small value occupying only part of a register or
57*9880d681SAndroid Build Coastguard Worker   /// - a register representing only part of a value.
58*9880d681SAndroid Build Coastguard Worker   void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
59*9880d681SAndroid Build Coastguard Worker   /// Emit a shift-right dwarf expression.
60*9880d681SAndroid Build Coastguard Worker   void AddShr(unsigned ShiftBy);
61*9880d681SAndroid Build Coastguard Worker   /// Emit a DW_OP_stack_value, if supported.
62*9880d681SAndroid Build Coastguard Worker   ///
63*9880d681SAndroid Build Coastguard Worker   /// The proper way to describe a constant value is
64*9880d681SAndroid Build Coastguard Worker   /// DW_OP_constu <const>, DW_OP_stack_value.
65*9880d681SAndroid Build Coastguard Worker   /// Unfortunately, DW_OP_stack_value was not available until DWARF-4,
66*9880d681SAndroid Build Coastguard Worker   /// so we will continue to generate DW_OP_constu <const> for DWARF-2
67*9880d681SAndroid Build Coastguard Worker   /// and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
68*9880d681SAndroid Build Coastguard Worker   /// actually describes a value at a constant addess, not a constant value.
69*9880d681SAndroid Build Coastguard Worker   /// However, in the past there was no better way  to describe a constant
70*9880d681SAndroid Build Coastguard Worker   /// value, so the producers and consumers started to rely on heuristics
71*9880d681SAndroid Build Coastguard Worker   /// to disambiguate the value vs. location status of the expression.
72*9880d681SAndroid Build Coastguard Worker   /// See PR21176 for more details.
73*9880d681SAndroid Build Coastguard Worker   void AddStackValue();
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   /// Emit an indirect dwarf register operation for the given machine register.
76*9880d681SAndroid Build Coastguard Worker   /// \return false if no DWARF register exists for MachineReg.
77*9880d681SAndroid Build Coastguard Worker   bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg,
78*9880d681SAndroid Build Coastguard Worker                              int Offset = 0);
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   /// \brief Emit a partial DWARF register operation.
81*9880d681SAndroid Build Coastguard Worker   /// \param MachineReg        the register
82*9880d681SAndroid Build Coastguard Worker   /// \param PieceSizeInBits   size and
83*9880d681SAndroid Build Coastguard Worker   /// \param PieceOffsetInBits offset of the piece in bits, if this is one
84*9880d681SAndroid Build Coastguard Worker   ///                          piece of an aggregate value.
85*9880d681SAndroid Build Coastguard Worker   ///
86*9880d681SAndroid Build Coastguard Worker   /// If size and offset is zero an operation for the entire
87*9880d681SAndroid Build Coastguard Worker   /// register is emitted: Some targets do not provide a DWARF
88*9880d681SAndroid Build Coastguard Worker   /// register number for every register.  If this is the case, this
89*9880d681SAndroid Build Coastguard Worker   /// function will attempt to emit a DWARF register by emitting a
90*9880d681SAndroid Build Coastguard Worker   /// piece of a super-register or by piecing together multiple
91*9880d681SAndroid Build Coastguard Worker   /// subregisters that alias the register.
92*9880d681SAndroid Build Coastguard Worker   ///
93*9880d681SAndroid Build Coastguard Worker   /// \return false if no DWARF register exists for MachineReg.
94*9880d681SAndroid Build Coastguard Worker   bool AddMachineRegPiece(const TargetRegisterInfo &TRI, unsigned MachineReg,
95*9880d681SAndroid Build Coastguard Worker                           unsigned PieceSizeInBits = 0,
96*9880d681SAndroid Build Coastguard Worker                           unsigned PieceOffsetInBits = 0);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   /// Emit a signed constant.
99*9880d681SAndroid Build Coastguard Worker   void AddSignedConstant(int64_t Value);
100*9880d681SAndroid Build Coastguard Worker   /// Emit an unsigned constant.
101*9880d681SAndroid Build Coastguard Worker   void AddUnsignedConstant(uint64_t Value);
102*9880d681SAndroid Build Coastguard Worker   /// Emit an unsigned constant.
103*9880d681SAndroid Build Coastguard Worker   void AddUnsignedConstant(const APInt &Value);
104*9880d681SAndroid Build Coastguard Worker 
105*9880d681SAndroid Build Coastguard Worker   /// \brief Emit an entire expression on top of a machine register location.
106*9880d681SAndroid Build Coastguard Worker   ///
107*9880d681SAndroid Build Coastguard Worker   /// \param PieceOffsetInBits If this is one piece out of a fragmented
108*9880d681SAndroid Build Coastguard Worker   /// location, this is the offset of the piece inside the entire variable.
109*9880d681SAndroid Build Coastguard Worker   /// \return false if no DWARF register exists for MachineReg.
110*9880d681SAndroid Build Coastguard Worker   bool AddMachineRegExpression(const TargetRegisterInfo &TRI,
111*9880d681SAndroid Build Coastguard Worker                                const DIExpression *Expr, unsigned MachineReg,
112*9880d681SAndroid Build Coastguard Worker                                unsigned PieceOffsetInBits = 0);
113*9880d681SAndroid Build Coastguard Worker   /// Emit a the operations remaining the DIExpressionIterator I.
114*9880d681SAndroid Build Coastguard Worker   /// \param PieceOffsetInBits If this is one piece out of a fragmented
115*9880d681SAndroid Build Coastguard Worker   /// location, this is the offset of the piece inside the entire variable.
116*9880d681SAndroid Build Coastguard Worker   void AddExpression(DIExpression::expr_op_iterator I,
117*9880d681SAndroid Build Coastguard Worker                      DIExpression::expr_op_iterator E,
118*9880d681SAndroid Build Coastguard Worker                      unsigned PieceOffsetInBits = 0);
119*9880d681SAndroid Build Coastguard Worker };
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker /// DwarfExpression implementation for .debug_loc entries.
122*9880d681SAndroid Build Coastguard Worker class DebugLocDwarfExpression : public DwarfExpression {
123*9880d681SAndroid Build Coastguard Worker   ByteStreamer &BS;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker public:
DebugLocDwarfExpression(unsigned DwarfVersion,ByteStreamer & BS)126*9880d681SAndroid Build Coastguard Worker   DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
127*9880d681SAndroid Build Coastguard Worker       : DwarfExpression(DwarfVersion), BS(BS) {}
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
130*9880d681SAndroid Build Coastguard Worker   void EmitSigned(int64_t Value) override;
131*9880d681SAndroid Build Coastguard Worker   void EmitUnsigned(uint64_t Value) override;
132*9880d681SAndroid Build Coastguard Worker   bool isFrameRegister(const TargetRegisterInfo &TRI,
133*9880d681SAndroid Build Coastguard Worker                        unsigned MachineReg) override;
134*9880d681SAndroid Build Coastguard Worker };
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker /// DwarfExpression implementation for singular DW_AT_location.
137*9880d681SAndroid Build Coastguard Worker class DIEDwarfExpression : public DwarfExpression {
138*9880d681SAndroid Build Coastguard Worker const AsmPrinter &AP;
139*9880d681SAndroid Build Coastguard Worker   DwarfUnit &DU;
140*9880d681SAndroid Build Coastguard Worker   DIELoc &DIE;
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker public:
143*9880d681SAndroid Build Coastguard Worker   DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
144*9880d681SAndroid Build Coastguard Worker   void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
145*9880d681SAndroid Build Coastguard Worker   void EmitSigned(int64_t Value) override;
146*9880d681SAndroid Build Coastguard Worker   void EmitUnsigned(uint64_t Value) override;
147*9880d681SAndroid Build Coastguard Worker   bool isFrameRegister(const TargetRegisterInfo &TRI,
148*9880d681SAndroid Build Coastguard Worker                        unsigned MachineReg) override;
149*9880d681SAndroid Build Coastguard Worker };
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker #endif
153