Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- LVObject.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 the LVObject class, which is used to describe a debug
10
// information object.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
15
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
16
 
17
#include "llvm/BinaryFormat/Dwarf.h"
18
#include "llvm/DebugInfo/CodeView/CodeView.h"
19
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
20
#include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
21
#include <limits>
22
#include <list>
23
#include <map>
24
#include <string>
25
 
26
namespace llvm {
27
namespace dwarf {
28
// Support for CodeView ModifierOptions::Unaligned.
29
constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
30
} // namespace dwarf
31
} // namespace llvm
32
 
33
namespace llvm {
34
namespace logicalview {
35
 
36
using LVSectionIndex = uint64_t;
37
using LVAddress = uint64_t;
38
using LVHalf = uint16_t;
39
using LVLevel = uint32_t;
40
using LVOffset = uint64_t;
41
using LVSigned = int64_t;
42
using LVUnsigned = uint64_t;
43
using LVSmall = uint8_t;
44
 
45
class LVElement;
46
class LVLine;
47
class LVLocation;
48
class LVLocationSymbol;
49
class LVObject;
50
class LVOperation;
51
class LVScope;
52
class LVSymbol;
53
class LVType;
54
 
55
class LVOptions;
56
class LVPatterns;
57
 
58
StringRef typeNone();
59
StringRef typeVoid();
60
StringRef typeInt();
61
StringRef typeUnknown();
62
StringRef emptyString();
63
 
64
using LVElementSetFunction = void (LVElement::*)();
65
using LVElementGetFunction = bool (LVElement::*)() const;
66
using LVLineSetFunction = void (LVLine::*)();
67
using LVLineGetFunction = bool (LVLine::*)() const;
68
using LVObjectSetFunction = void (LVObject::*)();
69
using LVObjectGetFunction = bool (LVObject::*)() const;
70
using LVScopeSetFunction = void (LVScope::*)();
71
using LVScopeGetFunction = bool (LVScope::*)() const;
72
using LVSymbolSetFunction = void (LVSymbol::*)();
73
using LVSymbolGetFunction = bool (LVSymbol::*)() const;
74
using LVTypeSetFunction = void (LVType::*)();
75
using LVTypeGetFunction = bool (LVType::*)() const;
76
 
77
// The LVScope class represents a logical scope and uses vectors to store its
78
// children, which are pointers to other allocated logical elements (types,
79
// symbols, lines, scopes, ranges). On destruction, we have to traverse each
80
// vector and destroy its elements. The other case is LVSymbol.
81
// These definitions are intended to be used by the LVScope and LVSymbol
82
// to support automatic vector cleanup.
83
using LVAutoLines = LVAutoSmallVector<LVLine *>;
84
using LVAutoLocations = LVAutoSmallVector<LVLocation *>;
85
using LVAutoOperations = LVAutoSmallVector<LVOperation *, 8>;
86
using LVAutoScopes = LVAutoSmallVector<LVScope *>;
87
using LVAutoSymbols = LVAutoSmallVector<LVSymbol *>;
88
using LVAutoTypes = LVAutoSmallVector<LVType *>;
89
 
90
// These definitions are intended to be used when the vector will be used
91
// just a container, with no automatic destruction.
92
using LVElements = SmallVector<LVElement *, 8>;
93
using LVLines = SmallVector<LVLine *, 8>;
94
using LVLocations = SmallVector<LVLocation *, 8>;
95
using LVOperations = SmallVector<LVOperation *, 8>;
96
using LVScopes = SmallVector<LVScope *, 8>;
97
using LVSymbols = SmallVector<LVSymbol *, 8>;
98
using LVTypes = SmallVector<LVType *, 8>;
99
 
100
using LVOffsets = SmallVector<LVOffset, 8>;
101
 
102
const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
103
 
104
enum class LVBinaryType { NONE, ELF, COFF };
105
enum class LVComparePass { Missing, Added };
106
 
107
// Validate functions.
108
using LVValidLocation = bool (LVLocation::*)();
109
 
110
// Keep counters of objects.
111
struct LVCounter {
112
  unsigned Lines = 0;
113
  unsigned Scopes = 0;
114
  unsigned Symbols = 0;
115
  unsigned Types = 0;
116
  void reset() {
117
    Lines = 0;
118
    Scopes = 0;
119
    Symbols = 0;
120
    Types = 0;
121
  }
122
};
123
 
124
class LVObject {
125
  enum class Property {
126
    IsLocation,          // Location.
127
    IsGlobalReference,   // This object is being referenced from another CU.
128
    IsGeneratedName,     // The Object name was generated.
129
    IsResolved,          // Object has been resolved.
130
    IsResolvedName,      // Object name has been resolved.
131
    IsDiscarded,         // Object has been stripped by the linker.
132
    IsOptimized,         // Object has been optimized by the compiler.
133
    IsAdded,             // Object has been 'added'.
134
    IsMatched,           // Object has been matched to a given pattern.
135
    IsMissing,           // Object is 'missing'.
136
    IsMissingLink,       // Object is indirectly 'missing'.
137
    IsInCompare,         // In 'compare' mode.
138
    IsFileFromReference, // File ID from specification.
139
    IsLineFromReference, // Line No from specification.
140
    HasMoved,            // The object was moved from 'target' to 'reference'.
141
    HasPattern,          // The object has a pattern.
142
    IsFinalized,         // CodeView object is finalized.
143
    IsReferenced,        // CodeView object being referenced.
144
    HasCodeViewLocation, // CodeView object with debug location.
145
    LastEntry
146
  };
147
  // Typed bitvector with properties for this object.
148
  LVProperties<Property> Properties;
149
 
150
  LVOffset Offset = 0;
151
  uint32_t LineNumber = 0;
152
  LVLevel ScopeLevel = 0;
153
  union {
154
    dwarf::Tag Tag;
155
    dwarf::Attribute Attr;
156
    LVSmall Opcode;
157
  } TagAttrOpcode = {dwarf::DW_TAG_null};
158
 
159
  // The parent of this object (nullptr if the root scope). For locations,
160
  // the parent is a symbol object; otherwise it is a scope object.
161
  union {
162
    LVElement *Element;
163
    LVScope *Scope;
164
    LVSymbol *Symbol;
165
  } Parent = {nullptr};
166
 
167
  // We do not support any object duplication, as they are created by parsing
168
  // the debug information. There is only the case where we need a very basic
169
  // object, to manipulate its offset, line number and scope level. Allow the
170
  // copy constructor to create that object; it is used to print a reference
171
  // to another object and in the case of templates, to print its encoded args.
172
  LVObject(const LVObject &Object) {
173
#ifndef NDEBUG
174
    incID();
175
#endif
176
    Properties = Object.Properties;
177
    Offset = Object.Offset;
178
    LineNumber = Object.LineNumber;
179
    ScopeLevel = Object.ScopeLevel;
180
    TagAttrOpcode = Object.TagAttrOpcode;
181
    Parent = Object.Parent;
182
  }
183
 
184
#ifndef NDEBUG
185
  // This is an internal ID used for debugging logical elements. It is used
186
  // for cases where an unique offset within the binary input file is not
187
  // available.
188
  static uint64_t GID;
189
  uint64_t ID = 0;
190
 
191
  void incID() {
192
    ++GID;
193
    ID = GID;
194
  }
195
#endif
196
 
197
protected:
198
  // Get a string representation for the given number and discriminator.
199
  std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
200
                           bool ShowZero) const;
201
 
202
  // Get a string representation for the given number.
203
  std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
204
 
205
  // Print the Filename or Pathname.
206
  // Empty implementation for those objects that do not have any user
207
  // source file references, such as debug locations.
208
  virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
209
 
210
public:
211
  LVObject() {
212
#ifndef NDEBUG
213
    incID();
214
#endif
215
  };
216
  LVObject &operator=(const LVObject &) = delete;
217
  virtual ~LVObject() = default;
218
 
219
  PROPERTY(Property, IsLocation);
220
  PROPERTY(Property, IsGlobalReference);
221
  PROPERTY(Property, IsGeneratedName);
222
  PROPERTY(Property, IsResolved);
223
  PROPERTY(Property, IsResolvedName);
224
  PROPERTY(Property, IsDiscarded);
225
  PROPERTY(Property, IsOptimized);
226
  PROPERTY(Property, IsAdded);
227
  PROPERTY(Property, IsMatched);
228
  PROPERTY(Property, IsMissing);
229
  PROPERTY(Property, IsMissingLink);
230
  PROPERTY(Property, IsInCompare);
231
  PROPERTY(Property, IsFileFromReference);
232
  PROPERTY(Property, IsLineFromReference);
233
  PROPERTY(Property, HasMoved);
234
  PROPERTY(Property, HasPattern);
235
  PROPERTY(Property, IsFinalized);
236
  PROPERTY(Property, IsReferenced);
237
  PROPERTY(Property, HasCodeViewLocation);
238
 
239
  // True if the scope has been named or typed or with line number.
240
  virtual bool isNamed() const { return false; }
241
  virtual bool isTyped() const { return false; }
242
  virtual bool isFiled() const { return false; }
243
  bool isLined() const { return LineNumber != 0; }
244
 
245
  // DWARF tag, attribute or expression opcode.
246
  dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
247
  void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
248
  dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
249
  void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
250
  LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
251
  void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
252
 
253
  // DIE offset.
254
  LVOffset getOffset() const { return Offset; }
255
  void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
256
 
257
  // Level where this object is located.
258
  LVLevel getLevel() const { return ScopeLevel; }
259
  void setLevel(LVLevel Level) { ScopeLevel = Level; }
260
 
261
  virtual StringRef getName() const { return StringRef(); }
262
  virtual void setName(StringRef ObjectName) {}
263
 
264
  LVElement *getParent() const {
265
    assert((!Parent.Element ||
266
            (Parent.Element && static_cast<LVElement *>(Parent.Element))) &&
267
           "Invalid element");
268
    return Parent.Element;
269
  }
270
  LVScope *getParentScope() const {
271
    assert((!Parent.Scope ||
272
            (Parent.Scope && static_cast<LVScope *>(Parent.Scope))) &&
273
           "Invalid scope");
274
    return Parent.Scope;
275
  }
276
  LVSymbol *getParentSymbol() const {
277
    assert((!Parent.Symbol ||
278
            (Parent.Symbol && static_cast<LVSymbol *>(Parent.Symbol))) &&
279
           "Invalid symbol");
280
    return Parent.Symbol;
281
  }
282
  void setParent(LVScope *Scope);
283
  void setParent(LVSymbol *Symbol);
284
  void resetParent() { Parent = {nullptr}; }
285
 
286
  virtual LVAddress getLowerAddress() const { return 0; }
287
  virtual void setLowerAddress(LVAddress Address) {}
288
  virtual LVAddress getUpperAddress() const { return 0; }
289
  virtual void setUpperAddress(LVAddress Address) {}
290
 
291
  uint32_t getLineNumber() const { return LineNumber; }
292
  void setLineNumber(uint32_t Number) { LineNumber = Number; }
293
 
294
  virtual const char *kind() const { return nullptr; }
295
 
296
  std::string indentAsString() const;
297
  std::string indentAsString(LVLevel Level) const;
298
 
299
  // String used as padding for printing objects with no line number.
300
  virtual std::string noLineAsString(bool ShowZero) const;
301
 
302
  // Line number for display; in the case of inlined functions, we use the
303
  // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
304
  virtual std::string lineNumberAsString(bool ShowZero = false) const {
305
    return lineAsString(getLineNumber(), 0, ShowZero);
306
  }
307
  std::string lineNumberAsStringStripped(bool ShowZero = false) const;
308
 
309
  // This function prints the logical view to an output stream.
310
  // Split: Prints the compilation unit view to a file.
311
  // Match: Prints the object only if it satisfies the patterns collected
312
  // from the command line. See the '--select' option.
313
  // Print: Print the object only if satisfies the conditions specified by
314
  // the different '--print' options.
315
  // Full: Prints full information for objects representing debug locations,
316
  // aggregated scopes, compile unit, functions and namespaces.
317
  virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
318
                        bool Full = true) const;
319
  void printAttributes(raw_ostream &OS, bool Full = true) const;
320
  void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
321
                       LVObject *Parent, StringRef Value,
322
                       bool UseQuotes = false, bool PrintRef = false) const;
323
 
324
  // Mark branch as missing (current element and parents).
325
  void markBranchAsMissing();
326
 
327
  // Prints the common information for an object (name, type, etc).
328
  virtual void print(raw_ostream &OS, bool Full = true) const;
329
  // Prints additional information for an object, depending on its kind
330
  // (class attributes, debug ranges, files, directories, etc).
331
  virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
332
 
333
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
334
  virtual void dump() const { print(dbgs()); }
335
#endif
336
 
337
  uint64_t getID() const {
338
    return
339
#ifndef NDEBUG
340
        ID;
341
#else
342
        0;
343
#endif
344
  }
345
};
346
 
347
} // end namespace logicalview
348
} // end namespace llvm
349
 
350
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H