1 //===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_DWARFEXPRESSION_H
10 #define LLVM_DEBUGINFO_DWARFEXPRESSION_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/iterator.h"
14 #include "llvm/ADT/iterator_range.h"
15 #include "llvm/Support/DataExtractor.h"
22 class DWARFExpression
{
26 /// This class represents an Operation in the Expression. Each operation can
27 /// have up to 2 oprerands.
29 /// An Operation can be in Error state (check with isError()). This
30 /// means that it couldn't be decoded successfully and if it is the
31 /// case, all others fields contain undefined values.
34 /// Size and signedness of expression operations' operands.
35 enum Encoding
: uint8_t {
43 SizeBlock
= 7, ///< Preceding operand contains block size
45 SignedSize1
= SignBit
| Size1
,
46 SignedSize2
= SignBit
| Size2
,
47 SignedSize4
= SignBit
| Size4
,
48 SignedSize8
= SignBit
| Size8
,
49 SignedSizeLEB
= SignBit
| SizeLEB
,
50 SizeNA
= 0xFF ///< Unused operands get this encoding.
53 enum DwarfVersion
: uint8_t {
54 DwarfNA
, ///< Serves as a marker for unused entries
60 /// Description of the encoding of one expression Op.
62 DwarfVersion Version
; ///< Dwarf version where the Op was introduced.
63 Encoding Op
[2]; ///< Encoding for Op operands, or SizeNA.
65 Description(DwarfVersion Version
= DwarfNA
, Encoding Op1
= SizeNA
,
66 Encoding Op2
= SizeNA
)
74 friend class DWARFExpression::iterator
;
75 uint8_t Opcode
; ///< The Op Opcode, DW_OP_<something>.
82 Description
&getDescription() { return Desc
; }
83 uint8_t getCode() { return Opcode
; }
84 uint64_t getRawOperand(unsigned Idx
) { return Operands
[Idx
]; }
85 uint32_t getEndOffset() { return EndOffset
; }
86 bool extract(DataExtractor Data
, uint16_t Version
, uint8_t AddressSize
,
88 bool isError() { return Error
; }
89 bool print(raw_ostream
&OS
, const DWARFExpression
*U
,
90 const MCRegisterInfo
*RegInfo
, bool isEH
);
93 /// An iterator to go through the expression operations.
95 : public iterator_facade_base
<iterator
, std::forward_iterator_tag
,
97 friend class DWARFExpression
;
98 const DWARFExpression
*Expr
;
101 iterator(const DWARFExpression
*Expr
, uint32_t Offset
)
102 : Expr(Expr
), Offset(Offset
) {
104 Offset
>= Expr
->Data
.getData().size() ||
105 !Op
.extract(Expr
->Data
, Expr
->Version
, Expr
->AddressSize
, Offset
);
109 class Operation
&operator++() {
110 Offset
= Op
.isError() ? Expr
->Data
.getData().size() : Op
.EndOffset
;
112 Offset
>= Expr
->Data
.getData().size() ||
113 !Op
.extract(Expr
->Data
, Expr
->Version
, Expr
->AddressSize
, Offset
);
117 class Operation
&operator*() {
121 // Comparison operators are provided out of line.
122 friend bool operator==(const iterator
&, const iterator
&);
125 DWARFExpression(DataExtractor Data
, uint16_t Version
, uint8_t AddressSize
)
126 : Data(Data
), Version(Version
), AddressSize(AddressSize
) {
127 assert(AddressSize
== 8 || AddressSize
== 4);
130 iterator
begin() const { return iterator(this, 0); }
131 iterator
end() const { return iterator(this, Data
.getData().size()); }
133 void print(raw_ostream
&OS
, const MCRegisterInfo
*RegInfo
,
134 bool IsEH
= false) const;
142 inline bool operator==(const DWARFExpression::iterator
&LHS
,
143 const DWARFExpression::iterator
&RHS
) {
144 return LHS
.Expr
== RHS
.Expr
&& LHS
.Offset
== RHS
.Offset
;
147 inline bool operator!=(const DWARFExpression::iterator
&LHS
,
148 const DWARFExpression::iterator
&RHS
) {
149 return !(LHS
== RHS
);