aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DwarfExpression.h
blob: 985d52c277fdfe57418aea8403ab742a6d1ad01a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing dwarf compile unit.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H

#include "llvm/IR/DebugInfo.h"
#include "llvm/Support/DataTypes.h"

namespace llvm {

class AsmPrinter;
class ByteStreamer;
class TargetRegisterInfo;
class DwarfUnit;
class DIELoc;

/// Base class containing the logic for constructing DWARF expressions
/// independently of whether they are emitted into a DIE or into a .debug_loc
/// entry.
class DwarfExpression {
protected:
  // Various convenience accessors that extract things out of AsmPrinter.
  const TargetRegisterInfo &TRI;
  unsigned DwarfVersion;

public:
  DwarfExpression(const TargetRegisterInfo &TRI,
                  unsigned DwarfVersion)
    : TRI(TRI), DwarfVersion(DwarfVersion) {}
  virtual ~DwarfExpression() {}

  /// Output a dwarf operand and an optional assembler comment.
  virtual void EmitOp(uint8_t Op, const char *Comment = nullptr) = 0;
  /// Emit a raw signed value.
  virtual void EmitSigned(int64_t Value) = 0;
  /// Emit a raw unsigned value.
  virtual void EmitUnsigned(uint64_t Value) = 0;
  /// Return whether the given machine register is the frame register in the
  /// current function.
  virtual bool isFrameRegister(unsigned MachineReg) = 0;

  /// Emit a dwarf register operation.
  void AddReg(int DwarfReg, const char *Comment = nullptr);
  /// Emit an (double-)indirect dwarf register operation.
  void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false);

  /// Emit a dwarf register operation for describing
  /// - a small value occupying only part of a register or
  /// - a register representing only part of a value.
  void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
  /// Emit a shift-right dwarf expression.
  void AddShr(unsigned ShiftBy);

  /// Emit an indirect dwarf register operation for the given machine register.
  /// \return false if no DWARF register exists for MachineReg.
  bool AddMachineRegIndirect(unsigned MachineReg, int Offset = 0);

  /// \brief Emit a partial DWARF register operation.
  /// \param MachineReg        the register
  /// \param PieceSizeInBits   size and
  /// \param PieceOffsetInBits offset of the piece in bits, if this is one
  ///                          piece of an aggregate value.
  ///
  /// If size and offset is zero an operation for the entire
  /// register is emitted: Some targets do not provide a DWARF
  /// register number for every register.  If this is the case, this
  /// function will attempt to emit a DWARF register by emitting a
  /// piece of a super-register or by piecing together multiple
  /// subregisters that alias the register.
  ///
  /// \return false if no DWARF register exists for MachineReg.
  bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0,
                          unsigned PieceOffsetInBits = 0);

  /// Emit a signed constant.
  void AddSignedConstant(int Value);
  /// Emit an unsigned constant.
  void AddUnsignedConstant(unsigned Value);

  /// Emit an entire DIExpression on top of a machine register location.
  /// \param PieceOffsetInBits If this is one piece out of a fragmented
  /// location, this is the offset of the piece inside the entire variable.
  /// \return false if no DWARF register exists for MachineReg.
  bool AddMachineRegExpression(DIExpression Expr, unsigned MachineReg,
                               unsigned PieceOffsetInBits = 0);
  /// Emit a the operations remaining the DIExpressionIterator I.
  /// \param PieceOffsetInBits If this is one piece out of a fragmented
  /// location, this is the offset of the piece inside the entire variable.
  void AddExpression(DIExpression::iterator I, DIExpression::iterator E,
                     unsigned PieceOffsetInBits = 0);
};

/// DwarfExpression implementation for .debug_loc entries.
class DebugLocDwarfExpression : public DwarfExpression {
  ByteStreamer &BS;

public:
  DebugLocDwarfExpression(const TargetRegisterInfo &TRI,
                          unsigned DwarfVersion, ByteStreamer &BS)
    : DwarfExpression(TRI, DwarfVersion), BS(BS) {}

  void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
  void EmitSigned(int64_t Value) override;
  void EmitUnsigned(uint64_t Value) override;
  bool isFrameRegister(unsigned MachineReg) override;
};

/// DwarfExpression implementation for singular DW_AT_location.
class DIEDwarfExpression : public DwarfExpression {
const AsmPrinter ≈
  DwarfUnit &DU;
  DIELoc ¨

public:
  DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
  void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
  void EmitSigned(int64_t Value) override;
  void EmitUnsigned(uint64_t Value) override;
  bool isFrameRegister(unsigned MachineReg) override;
};
}

#endif