xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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 LVOffsetElementMap = std::map<LVOffset, LVElement *>;
67 using LVOffsetLinesMap = std::map<LVOffset, LVLines>;
68 using LVOffsetLocationsMap = std::map<LVOffset, LVLocations>;
69 using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>;
70 using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsets>;
71 
72 // Class to represent a DWARF Scope.
73 class LVScope : public LVElement {
74   enum class Property {
75     HasDiscriminator,
76     CanHaveRanges,
77     CanHaveLines,
78     HasGlobals,
79     HasLocals,
80     HasLines,
81     HasScopes,
82     HasSymbols,
83     HasTypes,
84     IsComdat,
85     HasComdatScopes, // Compile Unit has comdat functions.
86     HasRanges,
87     AddedMissing, // Added missing referenced symbols.
88     LastEntry
89   };
90 
91   // Typed bitvector with kinds and properties for this scope.
92   LVProperties<LVScopeKind> Kinds;
93   LVProperties<Property> Properties;
94   static LVScopeDispatch Dispatch;
95 
96   // Coverage factor in units (bytes).
97   unsigned CoverageFactor = 0;
98 
99   // Calculate coverage factor.
calculateCoverage()100   void calculateCoverage() {
101     float CoveragePercentage = 0;
102     LVLocation::calculateCoverage(Ranges.get(), CoverageFactor,
103                                   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   std::unique_ptr<LVTypes> Types;
121   std::unique_ptr<LVSymbols> Symbols;
122   std::unique_ptr<LVScopes> Scopes;
123   std::unique_ptr<LVLines> Lines;
124   std::unique_ptr<LVLocations> Ranges;
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   std::unique_ptr<LVElements> Children;
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;
printSizes(raw_ostream & OS)139   virtual void printSizes(raw_ostream &OS) const {}
printSummary(raw_ostream & OS)140   virtual void printSummary(raw_ostream &OS) const {}
141 
142   // Encoded template arguments.
getEncodedArgs()143   virtual StringRef getEncodedArgs() const { return StringRef(); }
setEncodedArgs(StringRef EncodedArgs)144   virtual void setEncodedArgs(StringRef EncodedArgs) {}
145 
146 public:
LVScope()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() = default;
154 
classof(const LVElement * Element)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 
isCompileUnit()199   bool isCompileUnit() const override { return getIsCompileUnit(); }
isRoot()200   bool isRoot() const override { return getIsRoot(); }
201 
202   const char *kind() const override;
203 
204   // Get the specific children.
getLines()205   const LVLines *getLines() const { return Lines.get(); }
getRanges()206   const LVLocations *getRanges() const { return Ranges.get(); }
getScopes()207   const LVScopes *getScopes() const { return Scopes.get(); }
getSymbols()208   const LVSymbols *getSymbols() const { return Symbols.get(); }
getTypes()209   const LVTypes *getTypes() const { return Types.get(); }
getChildren()210   const LVElements *getChildren() const { return Children.get(); }
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.
lineCount()231   size_t lineCount() const { return Lines ? Lines->size() : 0; }
rangeCount()232   size_t rangeCount() const { return Ranges ? Ranges->size() : 0; }
scopeCount()233   size_t scopeCount() const { return Scopes ? Scopes->size() : 0; }
symbolCount()234   size_t symbolCount() const { return Symbols ? Symbols->size() : 0; }
typeCount()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 
getCoverageFactor()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.
getReference()259   virtual LVScope *getReference() const { return nullptr; }
260 
getCompileUnitParent()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 
getDispatch()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 {}
printMatchedElements(raw_ostream & OS,bool UseMatchedElements)318   virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {}
319 
320 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
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:
LVScopeAggregate()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.
getReference()337   LVScope *getReference() const override { return Reference; }
setReference(LVScope * Scope)338   void setReference(LVScope *Scope) override {
339     Reference = Scope;
340     setHasReference();
341   }
setReference(LVElement * Element)342   void setReference(LVElement *Element) override {
343     setReference(static_cast<LVScope *>(Element));
344   }
345 
getEncodedArgs()346   StringRef getEncodedArgs() const override {
347     return getStringPool().getString(EncodedArgsIndex);
348   }
setEncodedArgs(StringRef EncodedArgs)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:
LVScopeAlias()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:
LVScopeArray()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   // Used by the CodeView Reader.
414   codeview::CPUType CompilationCPUType = codeview::CPUType::X64;
415 
416   // Keep record of elements. They are needed at the compilation unit level
417   // to print the summary at the end of the printing.
418   LVCounter Allocated;
419   LVCounter Found;
420   LVCounter Printed;
421 
422   // Elements that match a given command line pattern.
423   LVElements MatchedElements;
424   LVScopes MatchedScopes;
425 
426   // It records the mapping between logical lines representing a debug line
427   // entry and its address in the text section. It is used to find a line
428   // giving its exact or closest address. To support comdat functions, all
429   // addresses for the same section are recorded in the same map.
430   using LVAddressToLine = std::map<LVAddress, LVLine *>;
431   LVDoubleMap<LVSectionIndex, LVAddress, LVLine *> SectionMappings;
432 
433   // DWARF Tags (Tag, Element list).
434   LVTagOffsetsMap DebugTags;
435 
436   // Offsets associated with objects being flagged as having invalid data
437   // (ranges, locations, lines zero or coverages).
438   LVOffsetElementMap WarningOffsets;
439 
440   // Symbols with invalid locations. (Symbol, Location List).
441   LVOffsetLocationsMap InvalidLocations;
442 
443   // Symbols with invalid coverage values.
444   LVOffsetSymbolMap InvalidCoverages;
445 
446   // Scopes with invalid ranges (Scope, Range list).
447   LVOffsetLocationsMap InvalidRanges;
448 
449   // Scopes with lines zero (Scope, Line list).
450   LVOffsetLinesMap LinesZero;
451 
452   // Record scopes contribution in bytes to the debug information.
453   using LVSizesMap = std::map<const LVScope *, LVOffset>;
454   LVSizesMap Sizes;
455   LVOffset CUContributionSize = 0;
456 
457   // Helper function to add an invalid location/range.
addInvalidLocationOrRange(LVLocation * Location,LVElement * Element,LVOffsetLocationsMap * Map)458   void addInvalidLocationOrRange(LVLocation *Location, LVElement *Element,
459                                  LVOffsetLocationsMap *Map) {
460     LVOffset Offset = Element->getOffset();
461     addInvalidOffset(Offset, Element);
462     addItem<LVOffsetLocationsMap, LVOffset, LVLocation *>(Map, Offset,
463                                                           Location);
464   }
465 
466   // Record scope sizes indexed by lexical level.
467   // Setting an initial size that will cover a very deep nested scopes.
468   const size_t TotalInitialSize = 8;
469   using LVTotalsEntry = std::pair<unsigned, float>;
470   SmallVector<LVTotalsEntry> Totals;
471   // Maximum seen lexical level. It is used to control how many entries
472   // in the 'Totals' vector are valid values.
473   LVLevel MaxSeenLevel = 0;
474 
475   // Get the line located at the given address.
476   LVLine *lineLowerBound(LVAddress Address, LVScope *Scope) const;
477   LVLine *lineUpperBound(LVAddress Address, LVScope *Scope) const;
478 
479   void printScopeSize(const LVScope *Scope, raw_ostream &OS);
printScopeSize(const LVScope * Scope,raw_ostream & OS)480   void printScopeSize(const LVScope *Scope, raw_ostream &OS) const {
481     (const_cast<LVScopeCompileUnit *>(this))->printScopeSize(Scope, OS);
482   }
483   void printTotals(raw_ostream &OS) const;
484 
485 protected:
486   void printSizes(raw_ostream &OS) const override;
487   void printSummary(raw_ostream &OS) const override;
488 
489 public:
LVScopeCompileUnit()490   LVScopeCompileUnit() : LVScope(), Totals(TotalInitialSize, {0, 0.0}) {
491     setIsCompileUnit();
492   }
493   LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
494   LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
495   ~LVScopeCompileUnit() = default;
496 
getCompileUnitParent()497   LVScope *getCompileUnitParent() const override {
498     return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));
499   }
500 
501   // Add line to address mapping.
502   void addMapping(LVLine *Line, LVSectionIndex SectionIndex);
503   LVLineRange lineRange(LVLocation *Location) const;
504 
505   LVNameInfo NameNone = {UINT64_MAX, 0};
addPublicName(LVScope * Scope,LVAddress LowPC,LVAddress HighPC)506   void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC) {
507     PublicNames.emplace(std::piecewise_construct, std::forward_as_tuple(Scope),
508                         std::forward_as_tuple(LowPC, HighPC - LowPC));
509   }
findPublicName(LVScope * Scope)510   const LVNameInfo &findPublicName(LVScope *Scope) {
511     LVPublicNames::iterator Iter = PublicNames.find(Scope);
512     return (Iter != PublicNames.end()) ? Iter->second : NameNone;
513   }
getPublicNames()514   const LVPublicNames &getPublicNames() const { return PublicNames; }
515 
516   // The base address of the scope for any of the debugging information
517   // entries listed, is given by either the DW_AT_low_pc attribute or the
518   // first address in the first range entry in the list of ranges given by
519   // the DW_AT_ranges attribute.
getBaseAddress()520   LVAddress getBaseAddress() const {
521     return Ranges ? Ranges->front()->getLowerAddress() : 0;
522   }
523 
getCompilationDirectory()524   StringRef getCompilationDirectory() const {
525     return getStringPool().getString(CompilationDirectoryIndex);
526   }
setCompilationDirectory(StringRef CompilationDirectory)527   void setCompilationDirectory(StringRef CompilationDirectory) {
528     CompilationDirectoryIndex = getStringPool().getIndex(CompilationDirectory);
529   }
530 
531   StringRef getFilename(size_t Index) const;
addFilename(StringRef Name)532   void addFilename(StringRef Name) {
533     Filenames.push_back(getStringPool().getIndex(Name));
534   }
535 
getProducer()536   StringRef getProducer() const override {
537     return getStringPool().getString(ProducerIndex);
538   }
setProducer(StringRef ProducerName)539   void setProducer(StringRef ProducerName) override {
540     ProducerIndex = getStringPool().getIndex(ProducerName);
541   }
542 
setCPUType(codeview::CPUType Type)543   void setCPUType(codeview::CPUType Type) { CompilationCPUType = Type; }
getCPUType()544   codeview::CPUType getCPUType() { return CompilationCPUType; }
545 
546   // Record DWARF tags.
547   void addDebugTag(dwarf::Tag Target, LVOffset Offset);
548   // Record elements with invalid offsets.
549   void addInvalidOffset(LVOffset Offset, LVElement *Element);
550   // Record symbols with invalid coverage values.
551   void addInvalidCoverage(LVSymbol *Symbol);
552   // Record symbols with invalid locations.
553   void addInvalidLocation(LVLocation *Location);
554   // Record scopes with invalid ranges.
555   void addInvalidRange(LVLocation *Location);
556   // Record line zero.
557   void addLineZero(LVLine *Line);
558 
getDebugTags()559   const LVTagOffsetsMap &getDebugTags() const { return DebugTags; }
getWarningOffsets()560   const LVOffsetElementMap &getWarningOffsets() const { return WarningOffsets; }
getInvalidLocations()561   const LVOffsetLocationsMap &getInvalidLocations() const {
562     return InvalidLocations;
563   }
getInvalidCoverages()564   const LVOffsetSymbolMap &getInvalidCoverages() const {
565     return InvalidCoverages;
566   }
getInvalidRanges()567   const LVOffsetLocationsMap &getInvalidRanges() const { return InvalidRanges; }
getLinesZero()568   const LVOffsetLinesMap &getLinesZero() const { return LinesZero; }
569 
570   // Process ranges, locations and calculate coverage.
571   void processRangeLocationCoverage(
572       LVValidLocation ValidLocation = &LVLocation::validateRanges);
573 
574   // Add matched element.
addMatched(LVElement * Element)575   void addMatched(LVElement *Element) { MatchedElements.push_back(Element); }
addMatched(LVScope * Scope)576   void addMatched(LVScope *Scope) { MatchedScopes.push_back(Scope); }
577   void propagatePatternMatch();
578 
getMatchedElements()579   const LVElements &getMatchedElements() const { return MatchedElements; }
getMatchedScopes()580   const LVScopes &getMatchedScopes() const { return MatchedScopes; }
581 
582   void printLocalNames(raw_ostream &OS, bool Full = true) const;
583   void printSummary(raw_ostream &OS, const LVCounter &Counter,
584                     const char *Header) const;
585 
586   void incrementPrintedLines();
587   void incrementPrintedScopes();
588   void incrementPrintedSymbols();
589   void incrementPrintedTypes();
590 
591   // Values are used by '--summary' option (allocated).
592   void increment(LVLine *Line);
593   void increment(LVScope *Scope);
594   void increment(LVSymbol *Symbol);
595   void increment(LVType *Type);
596 
597   // A new element has been added to the scopes tree. Take the following steps:
598   // Increase the added element counters, for printing summary.
599   // During comparison notify the Reader of the new element.
600   void addedElement(LVLine *Line);
601   void addedElement(LVScope *Scope);
602   void addedElement(LVSymbol *Symbol);
603   void addedElement(LVType *Type);
604 
605   void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper);
606 
607   // Returns true if current scope is logically equal to the given 'Scope'.
608   bool equals(const LVScope *Scope) const override;
609 
610   void print(raw_ostream &OS, bool Full = true) const override;
611   void printExtra(raw_ostream &OS, bool Full = true) const override;
612   void printWarnings(raw_ostream &OS, bool Full = true) const override;
613   void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) override;
614 };
615 
616 // Class to represent a DWARF enumerator (DW_TAG_enumeration_type).
617 class LVScopeEnumeration final : public LVScope {
618 public:
LVScopeEnumeration()619   LVScopeEnumeration() : LVScope() { setIsEnumeration(); }
620   LVScopeEnumeration(const LVScopeEnumeration &) = delete;
621   LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
622   ~LVScopeEnumeration() = default;
623 
624   // Returns true if current scope is logically equal to the given 'Scope'.
625   bool equals(const LVScope *Scope) const override;
626 
627   void printExtra(raw_ostream &OS, bool Full = true) const override;
628 };
629 
630 // Class to represent a DWARF formal parameter pack
631 // (DW_TAG_GNU_formal_parameter_pack).
632 class LVScopeFormalPack final : public LVScope {
633 public:
LVScopeFormalPack()634   LVScopeFormalPack() : LVScope() { setIsTemplatePack(); }
635   LVScopeFormalPack(const LVScopeFormalPack &) = delete;
636   LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
637   ~LVScopeFormalPack() = default;
638 
639   // Returns true if current scope is logically equal to the given 'Scope'.
640   bool equals(const LVScope *Scope) const override;
641 
642   void printExtra(raw_ostream &OS, bool Full = true) const override;
643 };
644 
645 // Class to represent a DWARF Function.
646 class LVScopeFunction : public LVScope {
647   LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
648   size_t LinkageNameIndex = 0;  // Function DW_AT_linkage_name attribute.
649   size_t EncodedArgsIndex = 0;  // Template encoded arguments.
650 
651 public:
LVScopeFunction()652   LVScopeFunction() : LVScope() {}
653   LVScopeFunction(const LVScopeFunction &) = delete;
654   LVScopeFunction &operator=(const LVScopeFunction &) = delete;
655   virtual ~LVScopeFunction() = default;
656 
657   // DW_AT_specification, DW_AT_abstract_origin.
getReference()658   LVScope *getReference() const override { return Reference; }
setReference(LVScope * Scope)659   void setReference(LVScope *Scope) override {
660     Reference = Scope;
661     setHasReference();
662   }
setReference(LVElement * Element)663   void setReference(LVElement *Element) override {
664     setReference(static_cast<LVScope *>(Element));
665   }
666 
getEncodedArgs()667   StringRef getEncodedArgs() const override {
668     return getStringPool().getString(EncodedArgsIndex);
669   }
setEncodedArgs(StringRef EncodedArgs)670   void setEncodedArgs(StringRef EncodedArgs) override {
671     EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
672   }
673 
setLinkageName(StringRef LinkageName)674   void setLinkageName(StringRef LinkageName) override {
675     LinkageNameIndex = getStringPool().getIndex(LinkageName);
676   }
getLinkageName()677   StringRef getLinkageName() const override {
678     return getStringPool().getString(LinkageNameIndex);
679   }
getLinkageNameIndex()680   size_t getLinkageNameIndex() const override { return LinkageNameIndex; }
681 
682   void setName(StringRef ObjectName) override;
683 
684   void resolveExtra() override;
685   void resolveReferences() override;
686 
687   // Returns true if current scope is logically equal to the given 'Scope'.
688   bool equals(const LVScope *Scope) const override;
689 
690   // For the given 'Scopes' returns a scope that is logically equal
691   // to the current scope; otherwise 'nullptr'.
692   LVScope *findEqualScope(const LVScopes *Scopes) const override;
693 
694   void printExtra(raw_ostream &OS, bool Full = true) const override;
695 };
696 
697 // Class to represent a DWARF inlined function.
698 class LVScopeFunctionInlined final : public LVScopeFunction {
699   size_t CallFilenameIndex = 0;
700   uint32_t CallLineNumber = 0;
701   uint32_t Discriminator = 0;
702 
703 public:
LVScopeFunctionInlined()704   LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); }
705   LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete;
706   LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete;
707   ~LVScopeFunctionInlined() = default;
708 
getDiscriminator()709   uint32_t getDiscriminator() const override { return Discriminator; }
setDiscriminator(uint32_t Value)710   void setDiscriminator(uint32_t Value) override {
711     Discriminator = Value;
712     setHasDiscriminator();
713   }
714 
getCallLineNumber()715   uint32_t getCallLineNumber() const override { return CallLineNumber; }
setCallLineNumber(uint32_t Number)716   void setCallLineNumber(uint32_t Number) override { CallLineNumber = Number; }
getCallFilenameIndex()717   size_t getCallFilenameIndex() const override { return CallFilenameIndex; }
setCallFilenameIndex(size_t Index)718   void setCallFilenameIndex(size_t Index) override {
719     CallFilenameIndex = Index;
720   }
721 
722   // Line number for display; in the case of Inlined Functions, we use the
723   // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
724   std::string lineNumberAsString(bool ShowZero = false) const override {
725     return lineAsString(getCallLineNumber(), getDiscriminator(), ShowZero);
726   }
727 
728   void resolveExtra() override;
729 
730   // Returns true if current scope is logically equal to the given 'Scope'.
731   bool equals(const LVScope *Scope) const override;
732 
733   // For the given 'Scopes' returns a scope that is logically equal
734   // to the current scope; otherwise 'nullptr'.
735   LVScope *findEqualScope(const LVScopes *Scopes) const override;
736 
737   void printExtra(raw_ostream &OS, bool Full = true) const override;
738 };
739 
740 // Class to represent a DWARF subroutine type.
741 class LVScopeFunctionType final : public LVScopeFunction {
742 public:
LVScopeFunctionType()743   LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); }
744   LVScopeFunctionType(const LVScopeFunctionType &) = delete;
745   LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete;
746   ~LVScopeFunctionType() = default;
747 
748   void resolveExtra() override;
749 };
750 
751 // Class to represent a DWARF Namespace.
752 class LVScopeNamespace final : public LVScope {
753   LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute.
754 
755 public:
LVScopeNamespace()756   LVScopeNamespace() : LVScope() { setIsNamespace(); }
757   LVScopeNamespace(const LVScopeNamespace &) = delete;
758   LVScopeNamespace &operator=(const LVScopeNamespace &) = delete;
759   ~LVScopeNamespace() = default;
760 
761   // Access DW_AT_extension reference.
getReference()762   LVScope *getReference() const override { return Reference; }
setReference(LVScope * Scope)763   void setReference(LVScope *Scope) override {
764     Reference = Scope;
765     setHasReference();
766   }
setReference(LVElement * Element)767   void setReference(LVElement *Element) override {
768     setReference(static_cast<LVScope *>(Element));
769   }
770 
771   // Returns true if current scope is logically equal to the given 'Scope'.
772   bool equals(const LVScope *Scope) const override;
773 
774   // For the given 'Scopes' returns a scope that is logically equal
775   // to the current scope; otherwise 'nullptr'.
776   LVScope *findEqualScope(const LVScopes *Scopes) const override;
777 
778   void printExtra(raw_ostream &OS, bool Full = true) const override;
779 };
780 
781 // Class to represent the binary file being analyzed.
782 class LVScopeRoot final : public LVScope {
783   size_t FileFormatNameIndex = 0;
784 
785 public:
LVScopeRoot()786   LVScopeRoot() : LVScope() { setIsRoot(); }
787   LVScopeRoot(const LVScopeRoot &) = delete;
788   LVScopeRoot &operator=(const LVScopeRoot &) = delete;
789   ~LVScopeRoot() = default;
790 
getFileFormatName()791   StringRef getFileFormatName() const {
792     return getStringPool().getString(FileFormatNameIndex);
793   }
setFileFormatName(StringRef FileFormatName)794   void setFileFormatName(StringRef FileFormatName) {
795     FileFormatNameIndex = getStringPool().getIndex(FileFormatName);
796   }
797 
798   // The CodeView Reader uses scoped names. Recursively transform the
799   // element name to use just the most inner component.
800   void transformScopedName();
801 
802   // Process the collected location, ranges and calculate coverage.
803   void processRangeInformation();
804 
805   // Returns true if current scope is logically equal to the given 'Scope'.
806   bool equals(const LVScope *Scope) const override;
807 
808   void print(raw_ostream &OS, bool Full = true) const override;
809   void printExtra(raw_ostream &OS, bool Full = true) const override;
810   Error doPrintMatches(bool Split, raw_ostream &OS,
811                        bool UseMatchedElements) const;
812 };
813 
814 // Class to represent a DWARF template parameter pack
815 // (DW_TAG_GNU_template_parameter_pack).
816 class LVScopeTemplatePack final : public LVScope {
817 public:
LVScopeTemplatePack()818   LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); }
819   LVScopeTemplatePack(const LVScopeTemplatePack &) = delete;
820   LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
821   ~LVScopeTemplatePack() = default;
822 
823   // Returns true if current scope is logically equal to the given 'Scope'.
824   bool equals(const LVScope *Scope) const override;
825 
826   void printExtra(raw_ostream &OS, bool Full = true) const override;
827 };
828 
829 } // end namespace logicalview
830 } // end namespace llvm
831 
832 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
833