Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / include / llvm / DebugInfo / DWARF / DWARFExpression.h
blob8049094cc16fef251130cf45a94ee98386d53ece
1 //===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===//
2 //
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
6 //
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"
17 namespace llvm {
18 class DWARFUnit;
19 class MCRegisterInfo;
20 class raw_ostream;
22 class DWARFExpression {
23 public:
24 class iterator;
26 /// This class represents an Operation in the Expression. Each operation can
27 /// have up to 2 oprerands.
28 ///
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.
32 class Operation {
33 public:
34 /// Size and signedness of expression operations' operands.
35 enum Encoding : uint8_t {
36 Size1 = 0,
37 Size2 = 1,
38 Size4 = 2,
39 Size8 = 3,
40 SizeLEB = 4,
41 SizeAddr = 5,
42 SizeRefAddr = 6,
43 SizeBlock = 7, ///< Preceding operand contains block size
44 SignBit = 0x8,
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
55 Dwarf2 = 2,
56 Dwarf3,
57 Dwarf4
60 /// Description of the encoding of one expression Op.
61 struct Description {
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)
67 : Version(Version) {
68 Op[0] = Op1;
69 Op[1] = Op2;
73 private:
74 friend class DWARFExpression::iterator;
75 uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
76 Description Desc;
77 bool Error;
78 uint32_t EndOffset;
79 uint64_t Operands[2];
81 public:
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,
87 uint32_t Offset);
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.
94 class iterator
95 : public iterator_facade_base<iterator, std::forward_iterator_tag,
96 Operation> {
97 friend class DWARFExpression;
98 const DWARFExpression *Expr;
99 uint32_t Offset;
100 Operation Op;
101 iterator(const DWARFExpression *Expr, uint32_t Offset)
102 : Expr(Expr), Offset(Offset) {
103 Op.Error =
104 Offset >= Expr->Data.getData().size() ||
105 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
108 public:
109 class Operation &operator++() {
110 Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
111 Op.Error =
112 Offset >= Expr->Data.getData().size() ||
113 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
114 return Op;
117 class Operation &operator*() {
118 return Op;
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;
136 private:
137 DataExtractor Data;
138 uint16_t Version;
139 uint8_t AddressSize;
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);
152 #endif