Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
Line
Count
Source (jump to first uncovered line)
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
332k
          : Version(Version) {
70
332k
        Op[0] = Op1;
71
332k
        Op[1] = Op2;
72
332k
      }
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
    uint32_t EndOffset;
81
    uint64_t Operands[2];
82
    uint32_t OperandEndOffsets[2];
83
84
  public:
85
3.31k
    Description &getDescription() { return Desc; }
86
7.22k
    uint8_t getCode() { return Opcode; }
87
8
    uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
88
1.29k
    uint32_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
89
4.56k
    uint32_t getEndOffset() { return EndOffset; }
90
    bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
91
                 uint32_t Offset);
92
5.65k
    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
    uint32_t Offset;
105
    Operation Op;
106
    iterator(const DWARFExpression *Expr, uint32_t Offset)
107
8.88k
        : Expr(Expr), Offset(Offset) {
108
8.88k
      Op.Error =
109
8.88k
          Offset >= Expr->Data.getData().size() ||
110
8.88k
          
!Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset)4.44k
;
111
8.88k
    }
112
113
  public:
114
5.18k
    class Operation &operator++() {
115
5.18k
      Offset = Op.isError() ? 
Expr->Data.getData().size()0
: Op.EndOffset;
116
5.18k
      Op.Error =
117
5.18k
          Offset >= Expr->Data.getData().size() ||
118
5.18k
          
!Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset)1.02k
;
119
5.18k
      return Op;
120
5.18k
    }
121
122
5.46k
    class Operation &operator*() {
123
5.46k
      return Op;
124
5.46k
    }
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
4.28k
      : Data(Data), Version(Version), AddressSize(AddressSize) {
132
4.28k
    assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
133
4.28k
  }
134
135
4.44k
  iterator begin() const { return iterator(this, 0); }
136
4.44k
  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
9.62k
                       const DWARFExpression::iterator &RHS) {
151
9.62k
  return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
152
9.62k
}
153
154
inline bool operator!=(const DWARFExpression::iterator &LHS,
155
9.62k
                       const DWARFExpression::iterator &RHS) {
156
9.62k
  return !(LHS == RHS);
157
9.62k
}
158
}
159
#endif