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