]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
Merge llvm, clang, lld and lldb trunk r300890, and update build glue.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / CodeGen / AsmPrinter / DwarfExpression.h
1 //===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for writing dwarf compile unit.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
16
17 #include "llvm/IR/DebugInfo.h"
18 #include "llvm/Support/DataTypes.h"
19
20 namespace llvm {
21
22 class AsmPrinter;
23 class ByteStreamer;
24 class TargetRegisterInfo;
25 class DwarfUnit;
26 class DIELoc;
27
28 /// Holds a DIExpression and keeps track of how many operands have been consumed
29 /// so far.
30 class DIExpressionCursor {
31   DIExpression::expr_op_iterator Start, End;
32 public:
33   DIExpressionCursor(const DIExpression *Expr) {
34     if (!Expr) {
35       assert(Start == End);
36       return;
37     }
38     Start = Expr->expr_op_begin();
39     End = Expr->expr_op_end();
40   }
41
42   DIExpressionCursor(ArrayRef<uint64_t> Expr)
43       : Start(Expr.begin()), End(Expr.end()) {}
44
45   /// Consume one operation.
46   Optional<DIExpression::ExprOperand> take() {
47     if (Start == End)
48       return None;
49     return *(Start++);
50   }
51
52   /// Consume N operations.
53   void consume(unsigned N) { std::advance(Start, N); }
54
55   /// Return the current operation.
56   Optional<DIExpression::ExprOperand> peek() const {
57     if (Start == End)
58       return None;
59     return *(Start);
60   }
61
62   /// Return the next operation.
63   Optional<DIExpression::ExprOperand> peekNext() const {
64     if (Start == End)
65       return None;
66
67     auto Next = Start.getNext();
68     if (Next == End)
69       return None;
70
71     return *Next;
72   }
73   /// Determine whether there are any operations left in this expression.
74   operator bool() const { return Start != End; }
75   DIExpression::expr_op_iterator begin() const { return Start; }
76   DIExpression::expr_op_iterator end() const { return End; }
77
78   /// Retrieve the fragment information, if any.
79   Optional<DIExpression::FragmentInfo> getFragmentInfo() const {
80     return DIExpression::getFragmentInfo(Start, End);
81   }
82 };
83
84 /// Base class containing the logic for constructing DWARF expressions
85 /// independently of whether they are emitted into a DIE or into a .debug_loc
86 /// entry.
87 class DwarfExpression {
88 protected:
89   /// Holds information about all subregisters comprising a register location.
90   struct Register {
91     int DwarfRegNo;
92     unsigned Size;
93     const char *Comment;
94   };
95
96   /// The register location, if any.
97   SmallVector<Register, 2> DwarfRegs;
98
99   /// Current Fragment Offset in Bits.
100   uint64_t OffsetInBits = 0;
101   unsigned DwarfVersion;
102
103   /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister. 
104   unsigned SubRegisterSizeInBits = 0;
105   unsigned SubRegisterOffsetInBits = 0;
106
107   /// The kind of location description being produced.
108   enum { Unknown = 0, Register, Memory, Implicit } LocationKind = Unknown;
109
110   /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
111   /// to represent a subregister.
112   void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
113     SubRegisterSizeInBits = SizeInBits;
114     SubRegisterOffsetInBits = OffsetInBits;
115   }
116
117   /// Add masking operations to stencil out a subregister.
118   void maskSubRegister();
119
120   /// Output a dwarf operand and an optional assembler comment.
121   virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0;
122   /// Emit a raw signed value.
123   virtual void emitSigned(int64_t Value) = 0;
124   /// Emit a raw unsigned value.
125   virtual void emitUnsigned(uint64_t Value) = 0;
126   /// Return whether the given machine register is the frame register in the
127   /// current function.
128   virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
129
130   /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
131   /// register location description.
132   void addReg(int DwarfReg, const char *Comment = nullptr);
133   /// Emit a DW_OP_breg operation.
134   void addBReg(int DwarfReg, int Offset);
135   /// Emit DW_OP_fbreg <Offset>.
136   void addFBReg(int Offset);
137
138   /// Emit a partial DWARF register operation.
139   ///
140   /// \param MachineReg           The register number.
141   /// \param MaxSize              If the register must be composed from
142   ///                             sub-registers this is an upper bound
143   ///                             for how many bits the emitted DW_OP_piece
144   ///                             may cover.
145   ///
146   /// If size and offset is zero an operation for the entire register is
147   /// emitted: Some targets do not provide a DWARF register number for every
148   /// register.  If this is the case, this function will attempt to emit a DWARF
149   /// register by emitting a fragment of a super-register or by piecing together
150   /// multiple subregisters that alias the register.
151   ///
152   /// \return false if no DWARF register exists for MachineReg.
153   bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
154                      unsigned MaxSize = ~1U);
155
156
157   /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
158   /// \param OffsetInBits    This is an optional offset into the location that
159   /// is at the top of the DWARF stack.
160   void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
161
162   /// Emit a shift-right dwarf operation.
163   void addShr(unsigned ShiftBy);
164   /// Emit a bitwise and dwarf operation.
165   void addAnd(unsigned Mask);
166
167   /// Emit a DW_OP_stack_value, if supported.
168   ///
169   /// The proper way to describe a constant value is DW_OP_constu <const>,
170   /// DW_OP_stack_value.  Unfortunately, DW_OP_stack_value was not available
171   /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
172   /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
173   /// <const> actually describes a value at a constant addess, not a constant
174   /// value.  However, in the past there was no better way to describe a
175   /// constant value, so the producers and consumers started to rely on
176   /// heuristics to disambiguate the value vs. location status of the
177   /// expression.  See PR21176 for more details.
178   void addStackValue();
179
180   ~DwarfExpression() = default;
181 public:
182   DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
183
184   /// This needs to be called last to commit any pending changes.
185   void finalize();
186
187   /// Emit a signed constant.
188   void addSignedConstant(int64_t Value);
189   /// Emit an unsigned constant.
190   void addUnsignedConstant(uint64_t Value);
191   /// Emit an unsigned constant.
192   void addUnsignedConstant(const APInt &Value);
193
194   /// Lock this down to become a memory location description.
195   void setMemoryLocationKind() {
196     assert(LocationKind == Unknown);
197     LocationKind = Memory;
198   }
199
200   /// Emit a machine register location. As an optimization this may also consume
201   /// the prefix of a DwarfExpression if a more efficient representation for
202   /// combining the register location and the first operation exists.
203   ///
204   /// \param FragmentOffsetInBits     If this is one fragment out of a
205   /// fragmented
206   ///                                 location, this is the offset of the
207   ///                                 fragment inside the entire variable.
208   /// \return                         false if no DWARF register exists
209   ///                                 for MachineReg.
210   bool addMachineRegExpression(const TargetRegisterInfo &TRI,
211                                DIExpressionCursor &Expr, unsigned MachineReg,
212                                unsigned FragmentOffsetInBits = 0);
213   /// Emit all remaining operations in the DIExpressionCursor.
214   ///
215   /// \param FragmentOffsetInBits     If this is one fragment out of multiple
216   ///                                 locations, this is the offset of the
217   ///                                 fragment inside the entire variable.
218   void addExpression(DIExpressionCursor &&Expr,
219                      unsigned FragmentOffsetInBits = 0);
220
221   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
222   /// the fragment described by \c Expr.
223   void addFragmentOffset(const DIExpression *Expr);
224 };
225
226 /// DwarfExpression implementation for .debug_loc entries.
227 class DebugLocDwarfExpression final : public DwarfExpression {
228   ByteStreamer &BS;
229
230   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
231   void emitSigned(int64_t Value) override;
232   void emitUnsigned(uint64_t Value) override;
233   bool isFrameRegister(const TargetRegisterInfo &TRI,
234                        unsigned MachineReg) override;
235 public:
236   DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
237       : DwarfExpression(DwarfVersion), BS(BS) {}
238 };
239
240 /// DwarfExpression implementation for singular DW_AT_location.
241 class DIEDwarfExpression final : public DwarfExpression {
242 const AsmPrinter &AP;
243   DwarfUnit &DU;
244   DIELoc &DIE;
245
246   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
247   void emitSigned(int64_t Value) override;
248   void emitUnsigned(uint64_t Value) override;
249   bool isFrameRegister(const TargetRegisterInfo &TRI,
250                        unsigned MachineReg) override;
251 public:
252   DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
253   DIELoc *finalize() {
254     DwarfExpression::finalize();
255     return &DIE;
256   }
257 };
258 }
259
260 #endif