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
//===-- LVScope.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 LVScope class, which is used to describe a debug
10
// information scope.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
15
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
16
 
17
#include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
18
#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
19
#include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
20
#include "llvm/Object/ObjectFile.h"
21
#include <list>
22
#include <map>
23
#include <set>
24
 
25
namespace llvm {
26
namespace logicalview {
27
 
28
// Name address, Code size.
29
using LVNameInfo = std::pair<LVAddress, uint64_t>;
30
using LVPublicNames = std::map<LVScope *, LVNameInfo>;
31
using LVPublicAddresses = std::map<LVAddress, LVNameInfo>;
32
 
33
class LVRange;
34
 
35
enum class LVScopeKind {
36
  IsAggregate,
37
  IsArray,
38
  IsBlock,
39
  IsCallSite,
40
  IsCatchBlock,
41
  IsClass,
42
  IsCompileUnit,
43
  IsEntryPoint,
44
  IsEnumeration,
45
  IsFunction,
46
  IsFunctionType,
47
  IsInlinedFunction,
48
  IsLabel,
49
  IsLexicalBlock,
50
  IsMember,
51
  IsNamespace,
52
  IsRoot,
53
  IsStructure,
54
  IsSubprogram,
55
  IsTemplate,
56
  IsTemplateAlias,
57
  IsTemplatePack,
58
  IsTryBlock,
59
  IsUnion,
60
  LastEntry
61
};
62
using LVScopeKindSet = std::set<LVScopeKind>;
63
using LVScopeDispatch = std::map<LVScopeKind, LVScopeGetFunction>;
64
using LVScopeRequest = std::vector<LVScopeGetFunction>;
65
 
66
using LVOffsetList = std::list<LVOffset>;
67
using LVOffsetElementMap = std::map<LVOffset, LVElement *>;
68
using LVOffsetLinesMap = std::map<LVOffset, LVLines *>;
69
using LVOffsetLocationsMap = std::map<LVOffset, LVLocations *>;
70
using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>;
71
using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsetList *>;
72
 
73
// Class to represent a DWARF Scope.
74
class LVScope : public LVElement {
75
  enum class Property {
76
    HasDiscriminator,
77
    CanHaveRanges,
78
    CanHaveLines,
79
    HasGlobals,
80
    HasLocals,
81
    HasLines,
82
    HasScopes,
83
    HasSymbols,
84
    HasTypes,
85
    IsComdat,
86
    HasComdatScopes, // Compile Unit has comdat functions.
87
    HasRanges,
88
    AddedMissing, // Added missing referenced symbols.
89
    LastEntry
90
  };
91
 
92
  // Typed bitvector with kinds and properties for this scope.
93
  LVProperties<LVScopeKind> Kinds;
94
  LVProperties<Property> Properties;
95
  static LVScopeDispatch Dispatch;
96
 
97
  // Coverage factor in units (bytes).
98
  unsigned CoverageFactor = 0;
99
 
100
  // Calculate coverage factor.
101
  void calculateCoverage() {
102
    float CoveragePercentage = 0;
103
    LVLocation::calculateCoverage(Ranges, CoverageFactor, CoveragePercentage);
104
  }
105
 
106
  // Decide if the scope will be printed, using some conditions given by:
107
  // only-globals, only-locals, a-pattern.
108
  bool resolvePrinting() const;
109
 
110
  // Find the current scope in the given 'Targets'.
111
  LVScope *findIn(const LVScopes *Targets) const;
112
 
113
  // Traverse the scope parent tree, executing the given callback function
114
  // on each scope.
115
  void traverseParents(LVScopeGetFunction GetFunction,
116
                       LVScopeSetFunction SetFunction);
117
 
118
protected:
119
  // Types, Symbols, Scopes, Lines, Locations in this scope.
120
  LVAutoTypes *Types = nullptr;
121
  LVAutoSymbols *Symbols = nullptr;
122
  LVAutoScopes *Scopes = nullptr;
123
  LVAutoLines *Lines = nullptr;
124
  LVAutoLocations *Ranges = nullptr;
125
 
126
  // Vector of elements (types, scopes and symbols).
127
  // It is the union of (*Types, *Symbols and *Scopes) to be used for
128
  // the following reasons:
129
  // - Preserve the order the logical elements are read in.
130
  // - To have a single container with all the logical elements, when
131
  //   the traversal does not require any specific element kind.
132
  LVElements *Children = nullptr;
133
 
134
  // Resolve the template parameters/arguments relationship.
135
  void resolveTemplate();
136
  void printEncodedArgs(raw_ostream &OS, bool Full) const;
137
 
138
  void printActiveRanges(raw_ostream &OS, bool Full = true) const;
139
  virtual void printSizes(raw_ostream &OS) const {}
140
  virtual void printSummary(raw_ostream &OS) const {}
141
 
142
  // Encoded template arguments.
143
  virtual StringRef getEncodedArgs() const { return StringRef(); }
144
  virtual void setEncodedArgs(StringRef EncodedArgs) {}
145
 
146
public:
147
  LVScope() : LVElement(LVSubclassID::LV_SCOPE) {
148
    setIsScope();
149
    setIncludeInPrint();
150
  }
151
  LVScope(const LVScope &) = delete;
152
  LVScope &operator=(const LVScope &) = delete;
153
  virtual ~LVScope();
154
 
155
  static bool classof(const LVElement *Element) {
156
    return Element->getSubclassID() == LVSubclassID::LV_SCOPE;
157
  }
158
 
159
  KIND(LVScopeKind, IsAggregate);
160
  KIND(LVScopeKind, IsArray);
161
  KIND_2(LVScopeKind, IsBlock, CanHaveRanges, CanHaveLines);
162
  KIND_1(LVScopeKind, IsCallSite, IsFunction);
163
  KIND_1(LVScopeKind, IsCatchBlock, IsBlock);
164
  KIND_1(LVScopeKind, IsClass, IsAggregate);
165
  KIND_3(LVScopeKind, IsCompileUnit, CanHaveRanges, CanHaveLines,
166
         TransformName);
167
  KIND_1(LVScopeKind, IsEntryPoint, IsFunction);
168
  KIND(LVScopeKind, IsEnumeration);
169
  KIND_2(LVScopeKind, IsFunction, CanHaveRanges, CanHaveLines);
170
  KIND_1(LVScopeKind, IsFunctionType, IsFunction);
171
  KIND_2(LVScopeKind, IsInlinedFunction, IsFunction, IsInlined);
172
  KIND_1(LVScopeKind, IsLabel, IsFunction);
173
  KIND_1(LVScopeKind, IsLexicalBlock, IsBlock);
174
  KIND(LVScopeKind, IsMember);
175
  KIND(LVScopeKind, IsNamespace);
176
  KIND_1(LVScopeKind, IsRoot, TransformName);
177
  KIND_1(LVScopeKind, IsStructure, IsAggregate);
178
  KIND_1(LVScopeKind, IsSubprogram, IsFunction);
179
  KIND(LVScopeKind, IsTemplate);
180
  KIND(LVScopeKind, IsTemplateAlias);
181
  KIND(LVScopeKind, IsTemplatePack);
182
  KIND_1(LVScopeKind, IsTryBlock, IsBlock);
183
  KIND_1(LVScopeKind, IsUnion, IsAggregate);
184
 
185
  PROPERTY(Property, HasDiscriminator);
186
  PROPERTY(Property, CanHaveRanges);
187
  PROPERTY(Property, CanHaveLines);
188
  PROPERTY(Property, HasGlobals);
189
  PROPERTY(Property, HasLocals);
190
  PROPERTY(Property, HasLines);
191
  PROPERTY(Property, HasScopes);
192
  PROPERTY(Property, HasSymbols);
193
  PROPERTY(Property, HasTypes);
194
  PROPERTY(Property, IsComdat);
195
  PROPERTY(Property, HasComdatScopes);
196
  PROPERTY(Property, HasRanges);
197
  PROPERTY(Property, AddedMissing);
198
 
199
  bool isCompileUnit() const override { return getIsCompileUnit(); }
200
  bool isRoot() const override { return getIsRoot(); }
201
 
202
  const char *kind() const override;
203
 
204
  // Get the specific children.
205
  const LVLines *getLines() const { return Lines; }
206
  const LVLocations *getRanges() const { return Ranges; }
207
  const LVScopes *getScopes() const { return Scopes; }
208
  const LVSymbols *getSymbols() const { return Symbols; }
209
  const LVTypes *getTypes() const { return Types; }
210
  const LVElements *getChildren() const { return Children; }
211
 
212
  void addElement(LVElement *Element);
213
  void addElement(LVLine *Line);
214
  void addElement(LVScope *Scope);
215
  void addElement(LVSymbol *Symbol);
216
  void addElement(LVType *Type);
217
  void addObject(LVLocation *Location);
218
  void addObject(LVAddress LowerAddress, LVAddress UpperAddress);
219
  void addToChildren(LVElement *Element);
220
 
221
  // Add the missing elements from the given 'Reference', which is the
222
  // scope associated with any DW_AT_specification, DW_AT_abstract_origin.
223
  void addMissingElements(LVScope *Reference);
224
 
225
  // Traverse the scope parent tree and the children, executing the given
226
  // callback function on each element.
227
  void traverseParentsAndChildren(LVObjectGetFunction GetFunction,
228
                                  LVObjectSetFunction SetFunction);
229
 
230
  // Get the size of specific children.
231
  size_t lineCount() const { return Lines ? Lines->size() : 0; }
232
  size_t rangeCount() const { return Ranges ? Ranges->size() : 0; }
233
  size_t scopeCount() const { return Scopes ? Scopes->size() : 0; }
234
  size_t symbolCount() const { return Symbols ? Symbols->size() : 0; }
235
  size_t typeCount() const { return Types ? Types->size() : 0; }
236
 
237
  // Find containing parent for the given address.
238
  LVScope *outermostParent(LVAddress Address);
239
 
240
  // Get all the locations associated with symbols.
241
  void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation,
242
                    bool RecordInvalid = false);
243
  void getRanges(LVLocations &LocationList, LVValidLocation ValidLocation,
244
                 bool RecordInvalid = false);
245
  void getRanges(LVRange &RangeList);
246
 
247
  unsigned getCoverageFactor() const { return CoverageFactor; }
248
 
249
  Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
250
                bool Full = true) const override;
251
  // Sort the logical elements using the criteria specified by the
252
  // command line option '--output-sort'.
253
  void sort();
254
 
255
  // Get template parameter types.
256
  bool getTemplateParameterTypes(LVTypes &Params);
257
 
258
  // DW_AT_specification, DW_AT_abstract_origin, DW_AT_extension.
259
  virtual LVScope *getReference() const { return nullptr; }
260
 
261
  LVScope *getCompileUnitParent() const override {
262
    return LVElement::getCompileUnitParent();
263
  }
264
 
265
  // Follow a chain of references given by DW_AT_abstract_origin and/or
266
  // DW_AT_specification and update the scope name.
267
  StringRef resolveReferencesChain();
268
 
269
  bool removeElement(LVElement *Element) override;
270
  void updateLevel(LVScope *Parent, bool Moved) override;
271
 
272
  void resolve() override;
273
  void resolveName() override;
274
  void resolveReferences() override;
275
 
276
  // Return the chain of parents as a string.
277
  void getQualifiedName(std::string &QualifiedName) const;
278
  // Encode the template arguments.
279
  void encodeTemplateArguments(std::string &Name) const;
280
  void encodeTemplateArguments(std::string &Name, const LVTypes *Types) const;
281
 
282
  void resolveElements();
283
 
284
  // Iterate through the 'References' set and check that all its elements
285
  // are present in the 'Targets' set. For a missing element, mark its
286
  // parents as missing.
287
  static void markMissingParents(const LVScopes *References,
288
                                 const LVScopes *Targets,
289
                                 bool TraverseChildren);
290
 
291
  // Checks if the current scope is contained within the target scope.
292
  // Depending on the result, the callback may be performed.
293
  virtual void markMissingParents(const LVScope *Target, bool TraverseChildren);
294
 
295
  // Returns true if the current scope and the given 'Scope' have the
296
  // same number of children.
297
  virtual bool equalNumberOfChildren(const LVScope *Scope) const;
298
 
299
  // Returns true if current scope is logically equal to the given 'Scope'.
300
  virtual bool equals(const LVScope *Scope) const;
301
 
302
  // Returns true if the given 'References' are logically equal to the
303
  // given 'Targets'.
304
  static bool equals(const LVScopes *References, const LVScopes *Targets);
305
 
306
  // For the given 'Scopes' returns a scope that is logically equal
307
  // to the current scope; otherwise 'nullptr'.
308
  virtual LVScope *findEqualScope(const LVScopes *Scopes) const;
309
 
310
  // Report the current scope as missing or added during comparison.
311
  void report(LVComparePass Pass) override;
312
 
313
  static LVScopeDispatch &getDispatch() { return Dispatch; }
314
 
315
  void print(raw_ostream &OS, bool Full = true) const override;
316
  void printExtra(raw_ostream &OS, bool Full = true) const override;
317
  virtual void printWarnings(raw_ostream &OS, bool Full = true) const {}
318
  virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {}
319
 
320
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
321
  void dump() const override { print(dbgs()); }
322
#endif
323
};
324
 
325
// Class to represent a DWARF Union/Structure/Class.
326
class LVScopeAggregate final : public LVScope {
327
  LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
328
  size_t EncodedArgsIndex = 0;  // Template encoded arguments.
329
 
330
public:
331
  LVScopeAggregate() : LVScope() {}
332
  LVScopeAggregate(const LVScopeAggregate &) = delete;
333
  LVScopeAggregate &operator=(const LVScopeAggregate &) = delete;
334
  ~LVScopeAggregate() = default;
335
 
336
  // DW_AT_specification, DW_AT_abstract_origin.
337
  LVScope *getReference() const override { return Reference; }
338
  void setReference(LVScope *Scope) override {
339
    Reference = Scope;
340
    setHasReference();
341
  }
342
  void setReference(LVElement *Element) override {
343
    setReference(static_cast<LVScope *>(Element));
344
  }
345
 
346
  StringRef getEncodedArgs() const override {
347
    return getStringPool().getString(EncodedArgsIndex);
348
  }
349
  void setEncodedArgs(StringRef EncodedArgs) override {
350
    EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
351
  }
352
 
353
  // Returns true if current scope is logically equal to the given 'Scope'.
354
  bool equals(const LVScope *Scope) const override;
355
 
356
  // For the given 'Scopes' returns a scope that is logically equal
357
  // to the current scope; otherwise 'nullptr'.
358
  LVScope *findEqualScope(const LVScopes *Scopes) const override;
359
 
360
  void printExtra(raw_ostream &OS, bool Full = true) const override;
361
};
362
 
363
// Class to represent a DWARF Template alias.
364
class LVScopeAlias final : public LVScope {
365
public:
366
  LVScopeAlias() : LVScope() {
367
    setIsTemplateAlias();
368
    setIsTemplate();
369
  }
370
  LVScopeAlias(const LVScopeAlias &) = delete;
371
  LVScopeAlias &operator=(const LVScopeAlias &) = delete;
372
  ~LVScopeAlias() = default;
373
 
374
  // Returns true if current scope is logically equal to the given 'Scope'.
375
  bool equals(const LVScope *Scope) const override;
376
 
377
  void printExtra(raw_ostream &OS, bool Full = true) const override;
378
};
379
 
380
// Class to represent a DWARF array (DW_TAG_array_type).
381
class LVScopeArray final : public LVScope {
382
public:
383
  LVScopeArray() : LVScope() { setIsArray(); }
384
  LVScopeArray(const LVScopeArray &) = delete;
385
  LVScopeArray &operator=(const LVScopeArray &) = delete;
386
  ~LVScopeArray() = default;
387
 
388
  void resolveExtra() override;
389
 
390
  // Returns true if current scope is logically equal to the given 'Scope'.
391
  bool equals(const LVScope *Scope) const override;
392
 
393
  void printExtra(raw_ostream &OS, bool Full = true) const override;
394
};
395
 
396
// Class to represent a DWARF Compilation Unit (CU).
397
class LVScopeCompileUnit final : public LVScope {
398
  // Names (files and directories) used by the Compile Unit.
399
  std::vector<size_t> Filenames;
400
 
401
  // As the .debug_pubnames section has been removed in DWARF5, we have a
402
  // similar functionality, which is used by the decoded functions. We use
403
  // the low-pc and high-pc for those scopes that are marked as public, in
404
  // order to support DWARF and CodeView.
405
  LVPublicNames PublicNames;
406
 
407
  // Toolchain producer.
408
  size_t ProducerIndex = 0;
409
 
410
  // Compilation directory name.
411
  size_t CompilationDirectoryIndex = 0;
412
 
413
  // Keep record of elements. They are needed at the compilation unit level
414
  // to print the summary at the end of the printing.
415
  LVCounter Allocated;
416
  LVCounter Found;
417
  LVCounter Printed;
418
 
419
  // Elements that match a given command line pattern.
420
  LVElements MatchedElements;
421
  LVScopes MatchedScopes;
422
 
423
  // It records the mapping between logical lines representing a debug line
424
  // entry and its address in the text section. It is used to find a line
425
  // giving its exact or closest address. To support comdat functions, all
426
  // addresses for the same section are recorded in the same map.
427
  using LVAddressToLine = std::map<LVAddress, LVLine *>;
428
  LVDoubleMap<LVSectionIndex, LVAddress, LVLine *> SectionMappings;
429
 
430
  // DWARF Tags (Tag, Element list).
431
  LVTagOffsetsMap DebugTags;
432
 
433
  // Offsets associated with objects being flagged as having invalid data
434
  // (ranges, locations, lines zero or coverages).
435
  LVOffsetElementMap WarningOffsets;
436
 
437
  // Symbols with invalid locations. (Symbol, Location List).
438
  LVOffsetLocationsMap InvalidLocations;
439
 
440
  // Symbols with invalid coverage values.
441
  LVOffsetSymbolMap InvalidCoverages;
442
 
443
  // Scopes with invalid ranges (Scope, Range list).
444
  LVOffsetLocationsMap InvalidRanges;
445
 
446
  // Scopes with lines zero (Scope, Line list).
447
  LVOffsetLinesMap LinesZero;
448
 
449
  // Record scopes contribution in bytes to the debug information.
450
  using LVSizesMap = std::map<const LVScope *, LVOffset>;
451
  LVSizesMap Sizes;
452
  LVOffset CUContributionSize = 0;
453
 
454
  // Helper function to add an invalid location/range.
455
  void addInvalidLocationOrRange(LVLocation *Location, LVElement *Element,
456
                                 LVOffsetLocationsMap *Map) {
457
    LVOffset Offset = Element->getOffset();
458
    addInvalidOffset(Offset, Element);
459
    addItem<LVOffsetLocationsMap, LVLocations, LVOffset, LVLocation *>(
460
        Map, Offset, Location);
461
  }
462
 
463
  // Record scope sizes indexed by lexical level.
464
  // Setting an initial size that will cover a very deep nested scopes.
465
  const size_t TotalInitialSize = 8;
466
  using LVTotalsEntry = std::pair<unsigned, float>;
467
  SmallVector<LVTotalsEntry> Totals;
468
  // Maximum seen lexical level. It is used to control how many entries
469
  // in the 'Totals' vector are valid values.
470
  LVLevel MaxSeenLevel = 0;
471
 
472
  // Get the line located at the given address.
473
  LVLine *lineLowerBound(LVAddress Address, LVScope *Scope) const;
474
  LVLine *lineUpperBound(LVAddress Address, LVScope *Scope) const;
475
 
476
  void printScopeSize(const LVScope *Scope, raw_ostream &OS);
477
  void printScopeSize(const LVScope *Scope, raw_ostream &OS) const {
478
    (const_cast<LVScopeCompileUnit *>(this))->printScopeSize(Scope, OS);
479
  }
480
  void printTotals(raw_ostream &OS) const;
481
 
482
protected:
483
  void printSizes(raw_ostream &OS) const override;
484
  void printSummary(raw_ostream &OS) const override;
485
 
486
public:
487
  LVScopeCompileUnit() : LVScope(), Totals(TotalInitialSize, {0, 0.0}) {
488
    setIsCompileUnit();
489
  }
490
  LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
491
  LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
492
  ~LVScopeCompileUnit() {
493
    deleteList<LVTagOffsetsMap>(DebugTags);
494
    deleteList<LVOffsetLocationsMap>(InvalidLocations);
495
    deleteList<LVOffsetLocationsMap>(InvalidRanges);
496
    deleteList<LVOffsetLinesMap>(LinesZero);
497
  }
498
 
499
  LVScope *getCompileUnitParent() const override {
500
    return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));
501
  }
502
 
503
  // Add line to address mapping.
504
  void addMapping(LVLine *Line, LVSectionIndex SectionIndex);
505
  LVLineRange lineRange(LVLocation *Location) const;
506
 
507
  LVNameInfo NameNone = {UINT64_MAX, 0};
508
  void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC) {
509
    PublicNames.emplace(std::piecewise_construct, std::forward_as_tuple(Scope),
510
                        std::forward_as_tuple(LowPC, HighPC - LowPC));
511
  }
512
  const LVNameInfo &findPublicName(LVScope *Scope) {
513
    LVPublicNames::iterator Iter = PublicNames.find(Scope);
514
    return (Iter != PublicNames.end()) ? Iter->second : NameNone;
515
  }
516
  const LVPublicNames &getPublicNames() const { return PublicNames; }
517
 
518
  // The base address of the scope for any of the debugging information
519
  // entries listed, is given by either the DW_AT_low_pc attribute or the
520
  // first address in the first range entry in the list of ranges given by
521
  // the DW_AT_ranges attribute.
522
  LVAddress getBaseAddress() const {
523
    return Ranges ? Ranges->front()->getLowerAddress() : 0;
524
  }
525
 
526
  StringRef getCompilationDirectory() const {
527
    return getStringPool().getString(CompilationDirectoryIndex);
528
  }
529
  void setCompilationDirectory(StringRef CompilationDirectory) {
530
    CompilationDirectoryIndex = getStringPool().getIndex(CompilationDirectory);
531
  }
532
 
533
  StringRef getFilename(size_t Index) const;
534
  void addFilename(StringRef Name) {
535
    Filenames.push_back(getStringPool().getIndex(Name));
536
  }
537
 
538
  StringRef getProducer() const override {
539
    return getStringPool().getString(ProducerIndex);
540
  }
541
  void setProducer(StringRef ProducerName) override {
542
    ProducerIndex = getStringPool().getIndex(ProducerName);
543
  }
544
 
545
  // Record DWARF tags.
546
  void addDebugTag(dwarf::Tag Target, LVOffset Offset);
547
  // Record elements with invalid offsets.
548
  void addInvalidOffset(LVOffset Offset, LVElement *Element);
549
  // Record symbols with invalid coverage values.
550
  void addInvalidCoverage(LVSymbol *Symbol);
551
  // Record symbols with invalid locations.
552
  void addInvalidLocation(LVLocation *Location);
553
  // Record scopes with invalid ranges.
554
  void addInvalidRange(LVLocation *Location);
555
  // Record line zero.
556
  void addLineZero(LVLine *Line);
557
 
558
  const LVTagOffsetsMap &getDebugTags() const { return DebugTags; }
559
  const LVOffsetElementMap &getWarningOffsets() const { return WarningOffsets; }
560
  const LVOffsetLocationsMap &getInvalidLocations() const {
561
    return InvalidLocations;
562
  }
563
  const LVOffsetSymbolMap &getInvalidCoverages() const {
564
    return InvalidCoverages;
565
  }
566
  const LVOffsetLocationsMap &getInvalidRanges() const { return InvalidRanges; }
567
  const LVOffsetLinesMap &getLinesZero() const { return LinesZero; }
568
 
569
  // Process ranges, locations and calculate coverage.
570
  void processRangeLocationCoverage(
571
      LVValidLocation ValidLocation = &LVLocation::validateRanges);
572
 
573
  // Add matched element.
574
  void addMatched(LVElement *Element) { MatchedElements.push_back(Element); }
575
  void addMatched(LVScope *Scope) { MatchedScopes.push_back(Scope); }
576
  void propagatePatternMatch();
577
 
578
  const LVElements &getMatchedElements() const { return MatchedElements; }
579
  const LVScopes &getMatchedScopes() const { return MatchedScopes; }
580
 
581
  void printLocalNames(raw_ostream &OS, bool Full = true) const;
582
  void printSummary(raw_ostream &OS, const LVCounter &Counter,
583
                    const char *Header) const;
584
 
585
  void incrementPrintedLines();
586
  void incrementPrintedScopes();
587
  void incrementPrintedSymbols();
588
  void incrementPrintedTypes();
589
 
590
  // Values are used by '--summary' option (allocated).
591
  void increment(LVLine *Line);
592
  void increment(LVScope *Scope);
593
  void increment(LVSymbol *Symbol);
594
  void increment(LVType *Type);
595
 
596
  // A new element has been added to the scopes tree. Take the following steps:
597
  // Increase the added element counters, for printing summary.
598
  // During comparison notify the Reader of the new element.
599
  void addedElement(LVLine *Line);
600
  void addedElement(LVScope *Scope);
601
  void addedElement(LVSymbol *Symbol);
602
  void addedElement(LVType *Type);
603
 
604
  void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper);
605
 
606
  // Returns true if current scope is logically equal to the given 'Scope'.
607
  bool equals(const LVScope *Scope) const override;
608
 
609
  void print(raw_ostream &OS, bool Full = true) const override;
610
  void printExtra(raw_ostream &OS, bool Full = true) const override;
611
  void printWarnings(raw_ostream &OS, bool Full = true) const override;
612
  void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) override;
613
};
614
 
615
// Class to represent a DWARF enumerator (DW_TAG_enumeration_type).
616
class LVScopeEnumeration final : public LVScope {
617
public:
618
  LVScopeEnumeration() : LVScope() { setIsEnumeration(); }
619
  LVScopeEnumeration(const LVScopeEnumeration &) = delete;
620
  LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
621
  ~LVScopeEnumeration() = default;
622
 
623
  // Returns true if current scope is logically equal to the given 'Scope'.
624
  bool equals(const LVScope *Scope) const override;
625
 
626
  void printExtra(raw_ostream &OS, bool Full = true) const override;
627
};
628
 
629
// Class to represent a DWARF formal parameter pack
630
// (DW_TAG_GNU_formal_parameter_pack).
631
class LVScopeFormalPack final : public LVScope {
632
public:
633
  LVScopeFormalPack() : LVScope() { setIsTemplatePack(); }
634
  LVScopeFormalPack(const LVScopeFormalPack &) = delete;
635
  LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
636
  ~LVScopeFormalPack() = default;
637
 
638
  // Returns true if current scope is logically equal to the given 'Scope'.
639
  bool equals(const LVScope *Scope) const override;
640
 
641
  void printExtra(raw_ostream &OS, bool Full = true) const override;
642
};
643
 
644
// Class to represent a DWARF Function.
645
class LVScopeFunction : public LVScope {
646
  LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
647
  size_t LinkageNameIndex = 0;  // Function DW_AT_linkage_name attribute.
648
  size_t EncodedArgsIndex = 0;  // Template encoded arguments.
649
 
650
public:
651
  LVScopeFunction() : LVScope() {}
652
  LVScopeFunction(const LVScopeFunction &) = delete;
653
  LVScopeFunction &operator=(const LVScopeFunction &) = delete;
654
  virtual ~LVScopeFunction() = default;
655
 
656
  // DW_AT_specification, DW_AT_abstract_origin.
657
  LVScope *getReference() const override { return Reference; }
658
  void setReference(LVScope *Scope) override {
659
    Reference = Scope;
660
    setHasReference();
661
  }
662
  void setReference(LVElement *Element) override {
663
    setReference(static_cast<LVScope *>(Element));
664
  }
665
 
666
  StringRef getEncodedArgs() const override {
667
    return getStringPool().getString(EncodedArgsIndex);
668
  }
669
  void setEncodedArgs(StringRef EncodedArgs) override {
670
    EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
671
  }
672
 
673
  void setLinkageName(StringRef LinkageName) override {
674
    LinkageNameIndex = getStringPool().getIndex(LinkageName);
675
  }
676
  StringRef getLinkageName() const override {
677
    return getStringPool().getString(LinkageNameIndex);
678
  }
679
  size_t getLinkageNameIndex() const override { return LinkageNameIndex; }
680
 
681
  void setName(StringRef ObjectName) override;
682
 
683
  void resolveExtra() override;
684
  void resolveReferences() override;
685
 
686
  // Returns true if current scope is logically equal to the given 'Scope'.
687
  bool equals(const LVScope *Scope) const override;
688
 
689
  // For the given 'Scopes' returns a scope that is logically equal
690
  // to the current scope; otherwise 'nullptr'.
691
  LVScope *findEqualScope(const LVScopes *Scopes) const override;
692
 
693
  void printExtra(raw_ostream &OS, bool Full = true) const override;
694
};
695
 
696
// Class to represent a DWARF inlined function.
697
class LVScopeFunctionInlined final : public LVScopeFunction {
698
  size_t CallFilenameIndex = 0;
699
  uint32_t CallLineNumber = 0;
700
  uint32_t Discriminator = 0;
701
 
702
public:
703
  LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); }
704
  LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete;
705
  LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete;
706
  ~LVScopeFunctionInlined() = default;
707
 
708
  uint32_t getDiscriminator() const override { return Discriminator; }
709
  void setDiscriminator(uint32_t Value) override {
710
    Discriminator = Value;
711
    setHasDiscriminator();
712
  }
713
 
714
  uint32_t getCallLineNumber() const override { return CallLineNumber; }
715
  void setCallLineNumber(uint32_t Number) override { CallLineNumber = Number; }
716
  size_t getCallFilenameIndex() const override { return CallFilenameIndex; }
717
  void setCallFilenameIndex(size_t Index) override {
718
    CallFilenameIndex = Index;
719
  }
720
 
721
  // Line number for display; in the case of Inlined Functions, we use the
722
  // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
723
  std::string lineNumberAsString(bool ShowZero = false) const override {
724
    return lineAsString(getCallLineNumber(), getDiscriminator(), ShowZero);
725
  }
726
 
727
  void resolveExtra() override;
728
 
729
  // Returns true if current scope is logically equal to the given 'Scope'.
730
  bool equals(const LVScope *Scope) const override;
731
 
732
  // For the given 'Scopes' returns a scope that is logically equal
733
  // to the current scope; otherwise 'nullptr'.
734
  LVScope *findEqualScope(const LVScopes *Scopes) const override;
735
 
736
  void printExtra(raw_ostream &OS, bool Full = true) const override;
737
};
738
 
739
// Class to represent a DWARF subroutine type.
740
class LVScopeFunctionType final : public LVScopeFunction {
741
public:
742
  LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); }
743
  LVScopeFunctionType(const LVScopeFunctionType &) = delete;
744
  LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete;
745
  ~LVScopeFunctionType() = default;
746
 
747
  void resolveExtra() override;
748
};
749
 
750
// Class to represent a DWARF Namespace.
751
class LVScopeNamespace final : public LVScope {
752
  LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute.
753
 
754
public:
755
  LVScopeNamespace() : LVScope() { setIsNamespace(); }
756
  LVScopeNamespace(const LVScopeNamespace &) = delete;
757
  LVScopeNamespace &operator=(const LVScopeNamespace &) = delete;
758
  ~LVScopeNamespace() = default;
759
 
760
  // Access DW_AT_extension reference.
761
  LVScope *getReference() const override { return Reference; }
762
  void setReference(LVScope *Scope) override {
763
    Reference = Scope;
764
    setHasReference();
765
  }
766
  void setReference(LVElement *Element) override {
767
    setReference(static_cast<LVScope *>(Element));
768
  }
769
 
770
  // Returns true if current scope is logically equal to the given 'Scope'.
771
  bool equals(const LVScope *Scope) const override;
772
 
773
  // For the given 'Scopes' returns a scope that is logically equal
774
  // to the current scope; otherwise 'nullptr'.
775
  LVScope *findEqualScope(const LVScopes *Scopes) const override;
776
 
777
  void printExtra(raw_ostream &OS, bool Full = true) const override;
778
};
779
 
780
// Class to represent the binary file being analyzed.
781
class LVScopeRoot final : public LVScope {
782
  size_t FileFormatNameIndex = 0;
783
 
784
public:
785
  LVScopeRoot() : LVScope() { setIsRoot(); }
786
  LVScopeRoot(const LVScopeRoot &) = delete;
787
  LVScopeRoot &operator=(const LVScopeRoot &) = delete;
788
  ~LVScopeRoot() = default;
789
 
790
  StringRef getFileFormatName() const {
791
    return getStringPool().getString(FileFormatNameIndex);
792
  }
793
  void setFileFormatName(StringRef FileFormatName) {
794
    FileFormatNameIndex = getStringPool().getIndex(FileFormatName);
795
  }
796
 
797
  // Process the collected location, ranges and calculate coverage.
798
  void processRangeInformation();
799
 
800
  // Returns true if current scope is logically equal to the given 'Scope'.
801
  bool equals(const LVScope *Scope) const override;
802
 
803
  void print(raw_ostream &OS, bool Full = true) const override;
804
  void printExtra(raw_ostream &OS, bool Full = true) const override;
805
  Error doPrintMatches(bool Split, raw_ostream &OS,
806
                       bool UseMatchedElements) const;
807
};
808
 
809
// Class to represent a DWARF template parameter pack
810
// (DW_TAG_GNU_template_parameter_pack).
811
class LVScopeTemplatePack final : public LVScope {
812
public:
813
  LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); }
814
  LVScopeTemplatePack(const LVScopeTemplatePack &) = delete;
815
  LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
816
  ~LVScopeTemplatePack() = default;
817
 
818
  // Returns true if current scope is logically equal to the given 'Scope'.
819
  bool equals(const LVScope *Scope) const override;
820
 
821
  void printExtra(raw_ostream &OS, bool Full = true) const override;
822
};
823
 
824
} // end namespace logicalview
825
} // end namespace llvm
826
 
827
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H