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
828