Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/DIContext.h
Line
Count
Source (jump to first uncovered line)
1
//===- DIContext.h ----------------------------------------------*- 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
// This file defines DIContext, an abstract data structure that holds
10
// debug information data.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_DEBUGINFO_DICONTEXT_H
15
#define LLVM_DEBUGINFO_DICONTEXT_H
16
17
#include "llvm/ADT/SmallVector.h"
18
#include "llvm/Object/ObjectFile.h"
19
#include "llvm/Support/raw_ostream.h"
20
#include <cassert>
21
#include <cstdint>
22
#include <memory>
23
#include <string>
24
#include <tuple>
25
#include <utility>
26
27
namespace llvm {
28
29
/// A format-neutral container for source line information.
30
struct DILineInfo {
31
  std::string FileName;
32
  std::string FunctionName;
33
  Optional<StringRef> Source;
34
  uint32_t Line = 0;
35
  uint32_t Column = 0;
36
  uint32_t StartLine = 0;
37
38
  // DWARF-specific.
39
  uint32_t Discriminator = 0;
40
41
6.78k
  DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
42
43
  bool operator==(const DILineInfo &RHS) const {
44
    return Line == RHS.Line && Column == RHS.Column &&
45
           FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
46
           StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
47
  }
48
49
  bool operator!=(const DILineInfo &RHS) const {
50
    return !(*this == RHS);
51
  }
52
53
0
  bool operator<(const DILineInfo &RHS) const {
54
0
    return std::tie(FileName, FunctionName, Line, Column, StartLine,
55
0
                    Discriminator) <
56
0
           std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
57
0
                    RHS.StartLine, RHS.Discriminator);
58
0
  }
59
60
  explicit operator bool() const { return *this != DILineInfo(); }
61
62
  void dump(raw_ostream &OS) {
63
    OS << "Line info: ";
64
    if (FileName != "<invalid>")
65
      OS << "file '" << FileName << "', ";
66
    if (FunctionName != "<invalid>")
67
      OS << "function '" << FunctionName << "', ";
68
    OS << "line " << Line << ", ";
69
    OS << "column " << Column << ", ";
70
    OS << "start line " << StartLine << '\n';
71
  }
72
};
73
74
using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
75
76
/// A format-neutral container for inlined code description.
77
class DIInliningInfo {
78
  SmallVector<DILineInfo, 4> Frames;
79
80
public:
81
175
  DIInliningInfo() = default;
82
83
  const DILineInfo & getFrame(unsigned Index) const {
84
    assert(Index < Frames.size());
85
    return Frames[Index];
86
  }
87
88
  DILineInfo *getMutableFrame(unsigned Index) {
89
    assert(Index < Frames.size());
90
    return &Frames[Index];
91
  }
92
93
  uint32_t getNumberOfFrames() const {
94
    return Frames.size();
95
  }
96
97
272
  void addFrame(const DILineInfo &Frame) {
98
272
    Frames.push_back(Frame);
99
272
  }
100
101
0
  void resize(unsigned i) {
102
0
    Frames.resize(i);
103
0
  }
104
};
105
106
/// Container for description of a global variable.
107
struct DIGlobal {
108
  std::string Name;
109
  uint64_t Start = 0;
110
  uint64_t Size = 0;
111
112
  DIGlobal() : Name("<invalid>") {}
113
};
114
115
struct DILocal {
116
  std::string FunctionName;
117
  std::string Name;
118
  std::string DeclFile;
119
  uint64_t DeclLine = 0;
120
  Optional<int64_t> FrameOffset;
121
  Optional<uint64_t> Size;
122
  Optional<uint64_t> TagOffset;
123
};
124
125
/// A DINameKind is passed to name search methods to specify a
126
/// preference regarding the type of name resolution the caller wants.
127
enum class DINameKind { None, ShortName, LinkageName };
128
129
/// Controls which fields of DILineInfo container should be filled
130
/// with data.
131
struct DILineInfoSpecifier {
132
  enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
133
  using FunctionNameKind = DINameKind;
134
135
  FileLineInfoKind FLIKind;
136
  FunctionNameKind FNKind;
137
138
  DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
139
                      FunctionNameKind FNKind = FunctionNameKind::None)
140
      : FLIKind(FLIKind), FNKind(FNKind) {}
141
};
142
143
/// This is just a helper to programmatically construct DIDumpType.
144
enum DIDumpTypeCounter {
145
#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
146
  DIDT_ID_##ENUM_NAME,
147
#include "llvm/BinaryFormat/Dwarf.def"
148
#undef HANDLE_DWARF_SECTION
149
  DIDT_ID_UUID,
150
  DIDT_ID_Count
151
};
152
static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
153
154
/// Selects which debug sections get dumped.
155
enum DIDumpType : unsigned {
156
  DIDT_Null,
157
  DIDT_All             = ~0U,
158
#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
159
  DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
160
#include "llvm/BinaryFormat/Dwarf.def"
161
#undef HANDLE_DWARF_SECTION
162
  DIDT_UUID = 1 << DIDT_ID_UUID,
163
};
164
165
/// Container for dump options that control which debug information will be
166
/// dumped.
167
struct DIDumpOptions {
168
  unsigned DumpType = DIDT_All;
169
  unsigned ChildRecurseDepth = -1U;
170
  unsigned ParentRecurseDepth = -1U;
171
  uint16_t Version = 0; // DWARF version to assume when extracting.
172
  uint8_t AddrSize = 4; // Address byte size to assume when extracting.
173
  bool ShowAddresses = true;
174
  bool ShowChildren = false;
175
  bool ShowParents = false;
176
  bool ShowForm = false;
177
  bool SummarizeTypes = false;
178
  bool Verbose = false;
179
  bool DisplayRawContents = false;
180
181
  /// Return default option set for printing a single DIE without children.
182
0
  static DIDumpOptions getForSingleDIE() {
183
0
    DIDumpOptions Opts;
184
0
    Opts.ChildRecurseDepth = 0;
185
0
    Opts.ParentRecurseDepth = 0;
186
0
    return Opts;
187
0
  }
188
189
  /// Return the options with RecurseDepth set to 0 unless explicitly required.
190
83
  DIDumpOptions noImplicitRecursion() const {
191
83
    DIDumpOptions Opts = *this;
192
83
    if (ChildRecurseDepth == -1U && 
!ShowChildren77
)
193
71
      Opts.ChildRecurseDepth = 0;
194
83
    if (ParentRecurseDepth == -1U && 
!ShowParents82
)
195
78
      Opts.ParentRecurseDepth = 0;
196
83
    return Opts;
197
83
  }
198
};
199
200
class DIContext {
201
public:
202
  enum DIContextKind {
203
    CK_DWARF,
204
    CK_PDB
205
  };
206
207
1.67k
  DIContext(DIContextKind K) : Kind(K) {}
208
1.67k
  virtual ~DIContext() = default;
209
210
  DIContextKind getKind() const { return Kind; }
211
212
  virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
213
214
0
  virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
215
0
    // No verifier? Just say things went well.
216
0
    return true;
217
0
  }
218
219
  virtual DILineInfo getLineInfoForAddress(
220
      object::SectionedAddress Address,
221
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
222
  virtual DILineInfoTable getLineInfoForAddressRange(
223
      object::SectionedAddress Address, uint64_t Size,
224
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
225
  virtual DIInliningInfo getInliningInfoForAddress(
226
      object::SectionedAddress Address,
227
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
228
229
  virtual std::vector<DILocal>
230
  getLocalsForAddress(object::SectionedAddress Address) = 0;
231
232
private:
233
  const DIContextKind Kind;
234
};
235
236
/// An inferface for inquiring the load address of a loaded object file
237
/// to be used by the DIContext implementations when applying relocations
238
/// on the fly.
239
class LoadedObjectInfo {
240
protected:
241
  LoadedObjectInfo() = default;
242
  LoadedObjectInfo(const LoadedObjectInfo &) = default;
243
244
public:
245
  virtual ~LoadedObjectInfo() = default;
246
247
  /// Obtain the Load Address of a section by SectionRef.
248
  ///
249
  /// Calculate the address of the given section.
250
  /// The section need not be present in the local address space. The addresses
251
  /// need to be consistent with the addresses used to query the DIContext and
252
  /// the output of this function should be deterministic, i.e. repeated calls
253
  /// with the same Sec should give the same address.
254
0
  virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
255
0
    return 0;
256
0
  }
257
258
  /// If conveniently available, return the content of the given Section.
259
  ///
260
  /// When the section is available in the local address space, in relocated
261
  /// (loaded) form, e.g. because it was relocated by a JIT for execution, this
262
  /// function should provide the contents of said section in `Data`. If the
263
  /// loaded section is not available, or the cost of retrieving it would be
264
  /// prohibitive, this function should return false. In that case, relocations
265
  /// will be read from the local (unrelocated) object file and applied on the
266
  /// fly. Note that this method is used purely for optimzation purposes in the
267
  /// common case of JITting in the local address space, so returning false
268
  /// should always be correct.
269
  virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
270
                                        StringRef &Data) const {
271
    return false;
272
  }
273
274
  // FIXME: This is untested and unused anywhere in the LLVM project, it's
275
  // used/needed by Julia (an external project). It should have some coverage
276
  // (at least tests, but ideally example functionality).
277
  /// Obtain a copy of this LoadedObjectInfo.
278
  virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
279
};
280
281
template <typename Derived, typename Base = LoadedObjectInfo>
282
struct LoadedObjectInfoHelper : Base {
283
protected:
284
  LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
285
  LoadedObjectInfoHelper() = default;
286
287
public:
288
  template <typename... Ts>
289
  LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
290
291
  std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
292
    return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
293
  }
294
};
295
296
} // end namespace llvm
297
298
#endif // LLVM_DEBUGINFO_DICONTEXT_H