]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / DebugInfo / DWARF / DWARFExpression.h
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 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_DWARFEXPRESSION_H
10 #define LLVM_DEBUGINFO_DWARFEXPRESSION_H
11
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"
16
17 namespace llvm {
18 class DWARFUnit;
19 class MCRegisterInfo;
20 class raw_ostream;
21
22 class DWARFExpression {
23 public:
24   class iterator;
25
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       BaseTypeRef = 8,
45       SignBit = 0x80,
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.
52     };
53
54     enum DwarfVersion : uint8_t {
55       DwarfNA, ///< Serves as a marker for unused entries
56       Dwarf2 = 2,
57       Dwarf3,
58       Dwarf4,
59       Dwarf5
60     };
61
62     /// Description of the encoding of one expression Op.
63     struct Description {
64       DwarfVersion Version; ///< Dwarf version where the Op was introduced.
65       Encoding Op[2];       ///< Encoding for Op operands, or SizeNA.
66
67       Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA,
68                   Encoding Op2 = SizeNA)
69           : Version(Version) {
70         Op[0] = Op1;
71         Op[1] = Op2;
72       }
73     };
74
75   private:
76     friend class DWARFExpression::iterator;
77     uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
78     Description Desc;
79     bool Error;
80     uint64_t EndOffset;
81     uint64_t Operands[2];
82     uint64_t OperandEndOffsets[2];
83
84   public:
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,
91                  uint64_t Offset);
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);
96   };
97
98   /// An iterator to go through the expression operations.
99   class iterator
100       : public iterator_facade_base<iterator, std::forward_iterator_tag,
101                                     Operation> {
102     friend class DWARFExpression;
103     const DWARFExpression *Expr;
104     uint64_t Offset;
105     Operation Op;
106     iterator(const DWARFExpression *Expr, uint64_t Offset)
107         : Expr(Expr), Offset(Offset) {
108       Op.Error =
109           Offset >= Expr->Data.getData().size() ||
110           !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
111     }
112
113   public:
114     class Operation &operator++() {
115       Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
116       Op.Error =
117           Offset >= Expr->Data.getData().size() ||
118           !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
119       return Op;
120     }
121
122     class Operation &operator*() {
123       return Op;
124     }
125
126     // Comparison operators are provided out of line.
127     friend bool operator==(const iterator &, const iterator &);
128   };
129
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);
133   }
134
135   iterator begin() const { return iterator(this, 0); }
136   iterator end() const { return iterator(this, Data.getData().size()); }
137
138   void print(raw_ostream &OS, const MCRegisterInfo *RegInfo, DWARFUnit *U,
139              bool IsEH = false) const;
140
141   bool verify(DWARFUnit *U);
142
143 private:
144   DataExtractor Data;
145   uint16_t Version;
146   uint8_t AddressSize;
147 };
148
149 inline bool operator==(const DWARFExpression::iterator &LHS,
150                        const DWARFExpression::iterator &RHS) {
151   return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
152 }
153
154 inline bool operator!=(const DWARFExpression::iterator &LHS,
155                        const DWARFExpression::iterator &RHS) {
156   return !(LHS == RHS);
157 }
158 }
159 #endif