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
46 SignedSize1
= SignBit
| Size1
,
47 SignedSize2
= SignBit
| Size2
,
48 SignedSize4
= SignBit
| Size4
,
49 SignedSize8
= SignBit
| Size8
,
50 SignedSizeLEB
= SignBit
| SizeLEB
,
51 SizeNA
= 0xFF ///< Unused operands get this encoding.
54 enum DwarfVersion
: uint8_t {
55 DwarfNA
, ///< Serves as a marker for unused entries
62 /// Description of the encoding of one expression Op.
64 DwarfVersion Version
; ///< Dwarf version where the Op was introduced.
65 Encoding Op
[2]; ///< Encoding for Op operands, or SizeNA.
67 Description(DwarfVersion Version
= DwarfNA
, Encoding Op1
= SizeNA
,
68 Encoding Op2
= SizeNA
)
76 friend class DWARFExpression::iterator
;
77 uint8_t Opcode
; ///< The Op Opcode, DW_OP_<something>.
82 uint64_t OperandEndOffsets
[2];
85 Description
&getDescription() { return Desc
; }
86 uint8_t getCode() { return Opcode
; }
87 uint64_t getRawOperand(unsigned Idx
) { return Operands
[Idx
]; }
88 uint64_t getOperandEndOffset(unsigned Idx
) { return OperandEndOffsets
[Idx
]; }
89 uint64_t getEndOffset() { return EndOffset
; }
90 bool extract(DataExtractor Data
, uint16_t Version
, uint8_t AddressSize
,
92 bool isError() { return Error
; }
93 bool print(raw_ostream
&OS
, const DWARFExpression
*Expr
,
94 const MCRegisterInfo
*RegInfo
, DWARFUnit
*U
, bool isEH
);
95 bool verify(DWARFUnit
*U
);
98 /// An iterator to go through the expression operations.
100 : public iterator_facade_base
<iterator
, std::forward_iterator_tag
,
102 friend class DWARFExpression
;
103 const DWARFExpression
*Expr
;
106 iterator(const DWARFExpression
*Expr
, uint64_t Offset
)
107 : Expr(Expr
), Offset(Offset
) {
109 Offset
>= Expr
->Data
.getData().size() ||
110 !Op
.extract(Expr
->Data
, Expr
->Version
, Expr
->AddressSize
, Offset
);
114 class Operation
&operator++() {
115 Offset
= Op
.isError() ? Expr
->Data
.getData().size() : Op
.EndOffset
;
117 Offset
>= Expr
->Data
.getData().size() ||
118 !Op
.extract(Expr
->Data
, Expr
->Version
, Expr
->AddressSize
, Offset
);
122 class Operation
&operator*() {
126 // Comparison operators are provided out of line.
127 friend bool operator==(const iterator
&, const iterator
&);
130 DWARFExpression(DataExtractor Data
, uint16_t Version
, uint8_t AddressSize
)
131 : Data(Data
), Version(Version
), AddressSize(AddressSize
) {
132 assert(AddressSize
== 8 || AddressSize
== 4 || AddressSize
== 2);
135 iterator
begin() const { return iterator(this, 0); }
136 iterator
end() const { return iterator(this, Data
.getData().size()); }
138 void print(raw_ostream
&OS
, const MCRegisterInfo
*RegInfo
, DWARFUnit
*U
,
139 bool IsEH
= false) const;
141 bool verify(DWARFUnit
*U
);
149 inline bool operator==(const DWARFExpression::iterator
&LHS
,
150 const DWARFExpression::iterator
&RHS
) {
151 return LHS
.Expr
== RHS
.Expr
&& LHS
.Offset
== RHS
.Offset
;
154 inline bool operator!=(const DWARFExpression::iterator
&LHS
,
155 const DWARFExpression::iterator
&RHS
) {
156 return !(LHS
== RHS
);