Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:43

0001 //===-- LVScope.h -----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the LVScope class, which is used to describe a debug
0010 // information scope.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
0015 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
0016 
0017 #include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
0018 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
0019 #include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
0020 #include "llvm/Object/ObjectFile.h"
0021 #include <list>
0022 #include <map>
0023 #include <set>
0024 
0025 namespace llvm {
0026 namespace logicalview {
0027 
0028 // Name address, Code size.
0029 using LVNameInfo = std::pair<LVAddress, uint64_t>;
0030 using LVPublicNames = std::map<LVScope *, LVNameInfo>;
0031 using LVPublicAddresses = std::map<LVAddress, LVNameInfo>;
0032 
0033 class LVRange;
0034 
0035 enum class LVScopeKind {
0036   IsAggregate,
0037   IsArray,
0038   IsBlock,
0039   IsCallSite,
0040   IsCatchBlock,
0041   IsClass,
0042   IsCompileUnit,
0043   IsEntryPoint,
0044   IsEnumeration,
0045   IsFunction,
0046   IsFunctionType,
0047   IsInlinedFunction,
0048   IsLabel,
0049   IsLexicalBlock,
0050   IsMember,
0051   IsNamespace,
0052   IsRoot,
0053   IsStructure,
0054   IsSubprogram,
0055   IsTemplate,
0056   IsTemplateAlias,
0057   IsTemplatePack,
0058   IsTryBlock,
0059   IsUnion,
0060   LastEntry
0061 };
0062 using LVScopeKindSet = std::set<LVScopeKind>;
0063 using LVScopeDispatch = std::map<LVScopeKind, LVScopeGetFunction>;
0064 using LVScopeRequest = std::vector<LVScopeGetFunction>;
0065 
0066 using LVOffsetElementMap = std::map<LVOffset, LVElement *>;
0067 using LVOffsetLinesMap = std::map<LVOffset, LVLines>;
0068 using LVOffsetLocationsMap = std::map<LVOffset, LVLocations>;
0069 using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>;
0070 using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsets>;
0071 
0072 // Class to represent a DWARF Scope.
0073 class LVScope : public LVElement {
0074   enum class Property {
0075     HasDiscriminator,
0076     CanHaveRanges,
0077     CanHaveLines,
0078     HasGlobals,
0079     HasLocals,
0080     HasLines,
0081     HasScopes,
0082     HasSymbols,
0083     HasTypes,
0084     IsComdat,
0085     HasComdatScopes, // Compile Unit has comdat functions.
0086     HasRanges,
0087     AddedMissing, // Added missing referenced symbols.
0088     LastEntry
0089   };
0090 
0091   // Typed bitvector with kinds and properties for this scope.
0092   LVProperties<LVScopeKind> Kinds;
0093   LVProperties<Property> Properties;
0094   static LVScopeDispatch Dispatch;
0095 
0096   // Coverage factor in units (bytes).
0097   unsigned CoverageFactor = 0;
0098 
0099   // Calculate coverage factor.
0100   void calculateCoverage() {
0101     float CoveragePercentage = 0;
0102     LVLocation::calculateCoverage(Ranges.get(), CoverageFactor,
0103                                   CoveragePercentage);
0104   }
0105 
0106   // Decide if the scope will be printed, using some conditions given by:
0107   // only-globals, only-locals, a-pattern.
0108   bool resolvePrinting() const;
0109 
0110   // Find the current scope in the given 'Targets'.
0111   LVScope *findIn(const LVScopes *Targets) const;
0112 
0113   // Traverse the scope parent tree, executing the given callback function
0114   // on each scope.
0115   void traverseParents(LVScopeGetFunction GetFunction,
0116                        LVScopeSetFunction SetFunction);
0117 
0118 protected:
0119   // Types, Symbols, Scopes, Lines, Locations in this scope.
0120   std::unique_ptr<LVTypes> Types;
0121   std::unique_ptr<LVSymbols> Symbols;
0122   std::unique_ptr<LVScopes> Scopes;
0123   std::unique_ptr<LVLines> Lines;
0124   std::unique_ptr<LVLocations> Ranges;
0125 
0126   // Vector of elements (types, scopes and symbols).
0127   // It is the union of (*Types, *Symbols and *Scopes) to be used for
0128   // the following reasons:
0129   // - Preserve the order the logical elements are read in.
0130   // - To have a single container with all the logical elements, when
0131   //   the traversal does not require any specific element kind.
0132   std::unique_ptr<LVElements> Children;
0133 
0134   // Resolve the template parameters/arguments relationship.
0135   void resolveTemplate();
0136   void printEncodedArgs(raw_ostream &OS, bool Full) const;
0137 
0138   void printActiveRanges(raw_ostream &OS, bool Full = true) const;
0139   virtual void printSizes(raw_ostream &OS) const {}
0140   virtual void printSummary(raw_ostream &OS) const {}
0141 
0142   // Encoded template arguments.
0143   virtual StringRef getEncodedArgs() const { return StringRef(); }
0144   virtual void setEncodedArgs(StringRef EncodedArgs) {}
0145 
0146 public:
0147   LVScope() : LVElement(LVSubclassID::LV_SCOPE) {
0148     setIsScope();
0149     setIncludeInPrint();
0150   }
0151   LVScope(const LVScope &) = delete;
0152   LVScope &operator=(const LVScope &) = delete;
0153   virtual ~LVScope() = default;
0154 
0155   static bool classof(const LVElement *Element) {
0156     return Element->getSubclassID() == LVSubclassID::LV_SCOPE;
0157   }
0158 
0159   KIND(LVScopeKind, IsAggregate);
0160   KIND(LVScopeKind, IsArray);
0161   KIND_2(LVScopeKind, IsBlock, CanHaveRanges, CanHaveLines);
0162   KIND_1(LVScopeKind, IsCallSite, IsFunction);
0163   KIND_1(LVScopeKind, IsCatchBlock, IsBlock);
0164   KIND_1(LVScopeKind, IsClass, IsAggregate);
0165   KIND_3(LVScopeKind, IsCompileUnit, CanHaveRanges, CanHaveLines,
0166          TransformName);
0167   KIND_1(LVScopeKind, IsEntryPoint, IsFunction);
0168   KIND(LVScopeKind, IsEnumeration);
0169   KIND_2(LVScopeKind, IsFunction, CanHaveRanges, CanHaveLines);
0170   KIND_1(LVScopeKind, IsFunctionType, IsFunction);
0171   KIND_2(LVScopeKind, IsInlinedFunction, IsFunction, IsInlined);
0172   KIND_1(LVScopeKind, IsLabel, IsFunction);
0173   KIND_1(LVScopeKind, IsLexicalBlock, IsBlock);
0174   KIND(LVScopeKind, IsMember);
0175   KIND(LVScopeKind, IsNamespace);
0176   KIND_1(LVScopeKind, IsRoot, TransformName);
0177   KIND_1(LVScopeKind, IsStructure, IsAggregate);
0178   KIND_1(LVScopeKind, IsSubprogram, IsFunction);
0179   KIND(LVScopeKind, IsTemplate);
0180   KIND(LVScopeKind, IsTemplateAlias);
0181   KIND(LVScopeKind, IsTemplatePack);
0182   KIND_1(LVScopeKind, IsTryBlock, IsBlock);
0183   KIND_1(LVScopeKind, IsUnion, IsAggregate);
0184 
0185   PROPERTY(Property, HasDiscriminator);
0186   PROPERTY(Property, CanHaveRanges);
0187   PROPERTY(Property, CanHaveLines);
0188   PROPERTY(Property, HasGlobals);
0189   PROPERTY(Property, HasLocals);
0190   PROPERTY(Property, HasLines);
0191   PROPERTY(Property, HasScopes);
0192   PROPERTY(Property, HasSymbols);
0193   PROPERTY(Property, HasTypes);
0194   PROPERTY(Property, IsComdat);
0195   PROPERTY(Property, HasComdatScopes);
0196   PROPERTY(Property, HasRanges);
0197   PROPERTY(Property, AddedMissing);
0198 
0199   bool isCompileUnit() const override { return getIsCompileUnit(); }
0200   bool isRoot() const override { return getIsRoot(); }
0201 
0202   const char *kind() const override;
0203 
0204   // Get the specific children.
0205   const LVLines *getLines() const { return Lines.get(); }
0206   const LVLocations *getRanges() const { return Ranges.get(); }
0207   const LVScopes *getScopes() const { return Scopes.get(); }
0208   const LVSymbols *getSymbols() const { return Symbols.get(); }
0209   const LVTypes *getTypes() const { return Types.get(); }
0210   const LVElements *getChildren() const { return Children.get(); }
0211 
0212   void addElement(LVElement *Element);
0213   void addElement(LVLine *Line);
0214   void addElement(LVScope *Scope);
0215   void addElement(LVSymbol *Symbol);
0216   void addElement(LVType *Type);
0217   void addObject(LVLocation *Location);
0218   void addObject(LVAddress LowerAddress, LVAddress UpperAddress);
0219   void addToChildren(LVElement *Element);
0220 
0221   // Add the missing elements from the given 'Reference', which is the
0222   // scope associated with any DW_AT_specification, DW_AT_abstract_origin.
0223   void addMissingElements(LVScope *Reference);
0224 
0225   // Traverse the scope parent tree and the children, executing the given
0226   // callback function on each element.
0227   void traverseParentsAndChildren(LVObjectGetFunction GetFunction,
0228                                   LVObjectSetFunction SetFunction);
0229 
0230   // Get the size of specific children.
0231   size_t lineCount() const { return Lines ? Lines->size() : 0; }
0232   size_t rangeCount() const { return Ranges ? Ranges->size() : 0; }
0233   size_t scopeCount() const { return Scopes ? Scopes->size() : 0; }
0234   size_t symbolCount() const { return Symbols ? Symbols->size() : 0; }
0235   size_t typeCount() const { return Types ? Types->size() : 0; }
0236 
0237   // Find containing parent for the given address.
0238   LVScope *outermostParent(LVAddress Address);
0239 
0240   // Get all the locations associated with symbols.
0241   void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation,
0242                     bool RecordInvalid = false);
0243   void getRanges(LVLocations &LocationList, LVValidLocation ValidLocation,
0244                  bool RecordInvalid = false);
0245   void getRanges(LVRange &RangeList);
0246 
0247   unsigned getCoverageFactor() const { return CoverageFactor; }
0248 
0249   Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
0250                 bool Full = true) const override;
0251   // Sort the logical elements using the criteria specified by the
0252   // command line option '--output-sort'.
0253   void sort();
0254 
0255   // Get template parameter types.
0256   bool getTemplateParameterTypes(LVTypes &Params);
0257 
0258   // DW_AT_specification, DW_AT_abstract_origin, DW_AT_extension.
0259   virtual LVScope *getReference() const { return nullptr; }
0260 
0261   LVScope *getCompileUnitParent() const override {
0262     return LVElement::getCompileUnitParent();
0263   }
0264 
0265   // Follow a chain of references given by DW_AT_abstract_origin and/or
0266   // DW_AT_specification and update the scope name.
0267   StringRef resolveReferencesChain();
0268 
0269   bool removeElement(LVElement *Element) override;
0270   void updateLevel(LVScope *Parent, bool Moved) override;
0271 
0272   void resolve() override;
0273   void resolveName() override;
0274   void resolveReferences() override;
0275 
0276   // Return the chain of parents as a string.
0277   void getQualifiedName(std::string &QualifiedName) const;
0278   // Encode the template arguments.
0279   void encodeTemplateArguments(std::string &Name) const;
0280   void encodeTemplateArguments(std::string &Name, const LVTypes *Types) const;
0281 
0282   void resolveElements();
0283 
0284   // Iterate through the 'References' set and check that all its elements
0285   // are present in the 'Targets' set. For a missing element, mark its
0286   // parents as missing.
0287   static void markMissingParents(const LVScopes *References,
0288                                  const LVScopes *Targets,
0289                                  bool TraverseChildren);
0290 
0291   // Checks if the current scope is contained within the target scope.
0292   // Depending on the result, the callback may be performed.
0293   virtual void markMissingParents(const LVScope *Target, bool TraverseChildren);
0294 
0295   // Returns true if the current scope and the given 'Scope' have the
0296   // same number of children.
0297   virtual bool equalNumberOfChildren(const LVScope *Scope) const;
0298 
0299   // Returns true if current scope is logically equal to the given 'Scope'.
0300   virtual bool equals(const LVScope *Scope) const;
0301 
0302   // Returns true if the given 'References' are logically equal to the
0303   // given 'Targets'.
0304   static bool equals(const LVScopes *References, const LVScopes *Targets);
0305 
0306   // For the given 'Scopes' returns a scope that is logically equal
0307   // to the current scope; otherwise 'nullptr'.
0308   virtual LVScope *findEqualScope(const LVScopes *Scopes) const;
0309 
0310   // Report the current scope as missing or added during comparison.
0311   void report(LVComparePass Pass) override;
0312 
0313   static LVScopeDispatch &getDispatch() { return Dispatch; }
0314 
0315   void print(raw_ostream &OS, bool Full = true) const override;
0316   void printExtra(raw_ostream &OS, bool Full = true) const override;
0317   virtual void printWarnings(raw_ostream &OS, bool Full = true) const {}
0318   virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {}
0319 
0320 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0321   void dump() const override { print(dbgs()); }
0322 #endif
0323 };
0324 
0325 // Class to represent a DWARF Union/Structure/Class.
0326 class LVScopeAggregate final : public LVScope {
0327   LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
0328   size_t EncodedArgsIndex = 0;  // Template encoded arguments.
0329 
0330 public:
0331   LVScopeAggregate() : LVScope() {}
0332   LVScopeAggregate(const LVScopeAggregate &) = delete;
0333   LVScopeAggregate &operator=(const LVScopeAggregate &) = delete;
0334   ~LVScopeAggregate() = default;
0335 
0336   // DW_AT_specification, DW_AT_abstract_origin.
0337   LVScope *getReference() const override { return Reference; }
0338   void setReference(LVScope *Scope) override {
0339     Reference = Scope;
0340     setHasReference();
0341   }
0342   void setReference(LVElement *Element) override {
0343     setReference(static_cast<LVScope *>(Element));
0344   }
0345 
0346   StringRef getEncodedArgs() const override {
0347     return getStringPool().getString(EncodedArgsIndex);
0348   }
0349   void setEncodedArgs(StringRef EncodedArgs) override {
0350     EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
0351   }
0352 
0353   // Returns true if current scope is logically equal to the given 'Scope'.
0354   bool equals(const LVScope *Scope) const override;
0355 
0356   // For the given 'Scopes' returns a scope that is logically equal
0357   // to the current scope; otherwise 'nullptr'.
0358   LVScope *findEqualScope(const LVScopes *Scopes) const override;
0359 
0360   void printExtra(raw_ostream &OS, bool Full = true) const override;
0361 };
0362 
0363 // Class to represent a DWARF Template alias.
0364 class LVScopeAlias final : public LVScope {
0365 public:
0366   LVScopeAlias() : LVScope() {
0367     setIsTemplateAlias();
0368     setIsTemplate();
0369   }
0370   LVScopeAlias(const LVScopeAlias &) = delete;
0371   LVScopeAlias &operator=(const LVScopeAlias &) = delete;
0372   ~LVScopeAlias() = default;
0373 
0374   // Returns true if current scope is logically equal to the given 'Scope'.
0375   bool equals(const LVScope *Scope) const override;
0376 
0377   void printExtra(raw_ostream &OS, bool Full = true) const override;
0378 };
0379 
0380 // Class to represent a DWARF array (DW_TAG_array_type).
0381 class LVScopeArray final : public LVScope {
0382 public:
0383   LVScopeArray() : LVScope() { setIsArray(); }
0384   LVScopeArray(const LVScopeArray &) = delete;
0385   LVScopeArray &operator=(const LVScopeArray &) = delete;
0386   ~LVScopeArray() = default;
0387 
0388   void resolveExtra() override;
0389 
0390   // Returns true if current scope is logically equal to the given 'Scope'.
0391   bool equals(const LVScope *Scope) const override;
0392 
0393   void printExtra(raw_ostream &OS, bool Full = true) const override;
0394 };
0395 
0396 // Class to represent a DWARF Compilation Unit (CU).
0397 class LVScopeCompileUnit final : public LVScope {
0398   // Names (files and directories) used by the Compile Unit.
0399   std::vector<size_t> Filenames;
0400 
0401   // As the .debug_pubnames section has been removed in DWARF5, we have a
0402   // similar functionality, which is used by the decoded functions. We use
0403   // the low-pc and high-pc for those scopes that are marked as public, in
0404   // order to support DWARF and CodeView.
0405   LVPublicNames PublicNames;
0406 
0407   // Toolchain producer.
0408   size_t ProducerIndex = 0;
0409 
0410   // Compilation directory name.
0411   size_t CompilationDirectoryIndex = 0;
0412 
0413   // Used by the CodeView Reader.
0414   codeview::CPUType CompilationCPUType = codeview::CPUType::X64;
0415 
0416   // Keep record of elements. They are needed at the compilation unit level
0417   // to print the summary at the end of the printing.
0418   LVCounter Allocated;
0419   LVCounter Found;
0420   LVCounter Printed;
0421 
0422   // Elements that match a given command line pattern.
0423   LVElements MatchedElements;
0424   LVScopes MatchedScopes;
0425 
0426   // It records the mapping between logical lines representing a debug line
0427   // entry and its address in the text section. It is used to find a line
0428   // giving its exact or closest address. To support comdat functions, all
0429   // addresses for the same section are recorded in the same map.
0430   using LVAddressToLine = std::map<LVAddress, LVLine *>;
0431   LVDoubleMap<LVSectionIndex, LVAddress, LVLine *> SectionMappings;
0432 
0433   // DWARF Tags (Tag, Element list).
0434   LVTagOffsetsMap DebugTags;
0435 
0436   // Offsets associated with objects being flagged as having invalid data
0437   // (ranges, locations, lines zero or coverages).
0438   LVOffsetElementMap WarningOffsets;
0439 
0440   // Symbols with invalid locations. (Symbol, Location List).
0441   LVOffsetLocationsMap InvalidLocations;
0442 
0443   // Symbols with invalid coverage values.
0444   LVOffsetSymbolMap InvalidCoverages;
0445 
0446   // Scopes with invalid ranges (Scope, Range list).
0447   LVOffsetLocationsMap InvalidRanges;
0448 
0449   // Scopes with lines zero (Scope, Line list).
0450   LVOffsetLinesMap LinesZero;
0451 
0452   // Record scopes contribution in bytes to the debug information.
0453   using LVSizesMap = std::map<const LVScope *, LVOffset>;
0454   LVSizesMap Sizes;
0455   LVOffset CUContributionSize = 0;
0456 
0457   // Helper function to add an invalid location/range.
0458   void addInvalidLocationOrRange(LVLocation *Location, LVElement *Element,
0459                                  LVOffsetLocationsMap *Map) {
0460     LVOffset Offset = Element->getOffset();
0461     addInvalidOffset(Offset, Element);
0462     addItem<LVOffsetLocationsMap, LVOffset, LVLocation *>(Map, Offset,
0463                                                           Location);
0464   }
0465 
0466   // Record scope sizes indexed by lexical level.
0467   // Setting an initial size that will cover a very deep nested scopes.
0468   const size_t TotalInitialSize = 8;
0469   using LVTotalsEntry = std::pair<unsigned, float>;
0470   SmallVector<LVTotalsEntry> Totals;
0471   // Maximum seen lexical level. It is used to control how many entries
0472   // in the 'Totals' vector are valid values.
0473   LVLevel MaxSeenLevel = 0;
0474 
0475   // Get the line located at the given address.
0476   LVLine *lineLowerBound(LVAddress Address, LVScope *Scope) const;
0477   LVLine *lineUpperBound(LVAddress Address, LVScope *Scope) const;
0478 
0479   void printScopeSize(const LVScope *Scope, raw_ostream &OS);
0480   void printScopeSize(const LVScope *Scope, raw_ostream &OS) const {
0481     (const_cast<LVScopeCompileUnit *>(this))->printScopeSize(Scope, OS);
0482   }
0483   void printTotals(raw_ostream &OS) const;
0484 
0485 protected:
0486   void printSizes(raw_ostream &OS) const override;
0487   void printSummary(raw_ostream &OS) const override;
0488 
0489 public:
0490   LVScopeCompileUnit() : LVScope(), Totals(TotalInitialSize, {0, 0.0}) {
0491     setIsCompileUnit();
0492   }
0493   LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
0494   LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
0495   ~LVScopeCompileUnit() = default;
0496 
0497   LVScope *getCompileUnitParent() const override {
0498     return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));
0499   }
0500 
0501   // Add line to address mapping.
0502   void addMapping(LVLine *Line, LVSectionIndex SectionIndex);
0503   LVLineRange lineRange(LVLocation *Location) const;
0504 
0505   LVNameInfo NameNone = {UINT64_MAX, 0};
0506   void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC) {
0507     PublicNames.emplace(std::piecewise_construct, std::forward_as_tuple(Scope),
0508                         std::forward_as_tuple(LowPC, HighPC - LowPC));
0509   }
0510   const LVNameInfo &findPublicName(LVScope *Scope) {
0511     LVPublicNames::iterator Iter = PublicNames.find(Scope);
0512     return (Iter != PublicNames.end()) ? Iter->second : NameNone;
0513   }
0514   const LVPublicNames &getPublicNames() const { return PublicNames; }
0515 
0516   // The base address of the scope for any of the debugging information
0517   // entries listed, is given by either the DW_AT_low_pc attribute or the
0518   // first address in the first range entry in the list of ranges given by
0519   // the DW_AT_ranges attribute.
0520   LVAddress getBaseAddress() const {
0521     return Ranges ? Ranges->front()->getLowerAddress() : 0;
0522   }
0523 
0524   StringRef getCompilationDirectory() const {
0525     return getStringPool().getString(CompilationDirectoryIndex);
0526   }
0527   void setCompilationDirectory(StringRef CompilationDirectory) {
0528     CompilationDirectoryIndex = getStringPool().getIndex(CompilationDirectory);
0529   }
0530 
0531   StringRef getFilename(size_t Index) const;
0532   void addFilename(StringRef Name) {
0533     Filenames.push_back(getStringPool().getIndex(Name));
0534   }
0535 
0536   StringRef getProducer() const override {
0537     return getStringPool().getString(ProducerIndex);
0538   }
0539   void setProducer(StringRef ProducerName) override {
0540     ProducerIndex = getStringPool().getIndex(ProducerName);
0541   }
0542 
0543   void setCPUType(codeview::CPUType Type) { CompilationCPUType = Type; }
0544   codeview::CPUType getCPUType() { return CompilationCPUType; }
0545 
0546   // Record DWARF tags.
0547   void addDebugTag(dwarf::Tag Target, LVOffset Offset);
0548   // Record elements with invalid offsets.
0549   void addInvalidOffset(LVOffset Offset, LVElement *Element);
0550   // Record symbols with invalid coverage values.
0551   void addInvalidCoverage(LVSymbol *Symbol);
0552   // Record symbols with invalid locations.
0553   void addInvalidLocation(LVLocation *Location);
0554   // Record scopes with invalid ranges.
0555   void addInvalidRange(LVLocation *Location);
0556   // Record line zero.
0557   void addLineZero(LVLine *Line);
0558 
0559   const LVTagOffsetsMap &getDebugTags() const { return DebugTags; }
0560   const LVOffsetElementMap &getWarningOffsets() const { return WarningOffsets; }
0561   const LVOffsetLocationsMap &getInvalidLocations() const {
0562     return InvalidLocations;
0563   }
0564   const LVOffsetSymbolMap &getInvalidCoverages() const {
0565     return InvalidCoverages;
0566   }
0567   const LVOffsetLocationsMap &getInvalidRanges() const { return InvalidRanges; }
0568   const LVOffsetLinesMap &getLinesZero() const { return LinesZero; }
0569 
0570   // Process ranges, locations and calculate coverage.
0571   void processRangeLocationCoverage(
0572       LVValidLocation ValidLocation = &LVLocation::validateRanges);
0573 
0574   // Add matched element.
0575   void addMatched(LVElement *Element) { MatchedElements.push_back(Element); }
0576   void addMatched(LVScope *Scope) { MatchedScopes.push_back(Scope); }
0577   void propagatePatternMatch();
0578 
0579   const LVElements &getMatchedElements() const { return MatchedElements; }
0580   const LVScopes &getMatchedScopes() const { return MatchedScopes; }
0581 
0582   void printLocalNames(raw_ostream &OS, bool Full = true) const;
0583   void printSummary(raw_ostream &OS, const LVCounter &Counter,
0584                     const char *Header) const;
0585 
0586   void incrementPrintedLines();
0587   void incrementPrintedScopes();
0588   void incrementPrintedSymbols();
0589   void incrementPrintedTypes();
0590 
0591   // Values are used by '--summary' option (allocated).
0592   void increment(LVLine *Line);
0593   void increment(LVScope *Scope);
0594   void increment(LVSymbol *Symbol);
0595   void increment(LVType *Type);
0596 
0597   // A new element has been added to the scopes tree. Take the following steps:
0598   // Increase the added element counters, for printing summary.
0599   // During comparison notify the Reader of the new element.
0600   void addedElement(LVLine *Line);
0601   void addedElement(LVScope *Scope);
0602   void addedElement(LVSymbol *Symbol);
0603   void addedElement(LVType *Type);
0604 
0605   void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper);
0606 
0607   // Returns true if current scope is logically equal to the given 'Scope'.
0608   bool equals(const LVScope *Scope) const override;
0609 
0610   void print(raw_ostream &OS, bool Full = true) const override;
0611   void printExtra(raw_ostream &OS, bool Full = true) const override;
0612   void printWarnings(raw_ostream &OS, bool Full = true) const override;
0613   void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) override;
0614 };
0615 
0616 // Class to represent a DWARF enumerator (DW_TAG_enumeration_type).
0617 class LVScopeEnumeration final : public LVScope {
0618 public:
0619   LVScopeEnumeration() : LVScope() { setIsEnumeration(); }
0620   LVScopeEnumeration(const LVScopeEnumeration &) = delete;
0621   LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
0622   ~LVScopeEnumeration() = default;
0623 
0624   // Returns true if current scope is logically equal to the given 'Scope'.
0625   bool equals(const LVScope *Scope) const override;
0626 
0627   void printExtra(raw_ostream &OS, bool Full = true) const override;
0628 };
0629 
0630 // Class to represent a DWARF formal parameter pack
0631 // (DW_TAG_GNU_formal_parameter_pack).
0632 class LVScopeFormalPack final : public LVScope {
0633 public:
0634   LVScopeFormalPack() : LVScope() { setIsTemplatePack(); }
0635   LVScopeFormalPack(const LVScopeFormalPack &) = delete;
0636   LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
0637   ~LVScopeFormalPack() = default;
0638 
0639   // Returns true if current scope is logically equal to the given 'Scope'.
0640   bool equals(const LVScope *Scope) const override;
0641 
0642   void printExtra(raw_ostream &OS, bool Full = true) const override;
0643 };
0644 
0645 // Class to represent a DWARF Function.
0646 class LVScopeFunction : public LVScope {
0647   LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
0648   size_t LinkageNameIndex = 0;  // Function DW_AT_linkage_name attribute.
0649   size_t EncodedArgsIndex = 0;  // Template encoded arguments.
0650 
0651 public:
0652   LVScopeFunction() : LVScope() {}
0653   LVScopeFunction(const LVScopeFunction &) = delete;
0654   LVScopeFunction &operator=(const LVScopeFunction &) = delete;
0655   virtual ~LVScopeFunction() = default;
0656 
0657   // DW_AT_specification, DW_AT_abstract_origin.
0658   LVScope *getReference() const override { return Reference; }
0659   void setReference(LVScope *Scope) override {
0660     Reference = Scope;
0661     setHasReference();
0662   }
0663   void setReference(LVElement *Element) override {
0664     setReference(static_cast<LVScope *>(Element));
0665   }
0666 
0667   StringRef getEncodedArgs() const override {
0668     return getStringPool().getString(EncodedArgsIndex);
0669   }
0670   void setEncodedArgs(StringRef EncodedArgs) override {
0671     EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
0672   }
0673 
0674   void setLinkageName(StringRef LinkageName) override {
0675     LinkageNameIndex = getStringPool().getIndex(LinkageName);
0676   }
0677   StringRef getLinkageName() const override {
0678     return getStringPool().getString(LinkageNameIndex);
0679   }
0680   size_t getLinkageNameIndex() const override { return LinkageNameIndex; }
0681 
0682   void setName(StringRef ObjectName) override;
0683 
0684   void resolveExtra() override;
0685   void resolveReferences() override;
0686 
0687   // Returns true if current scope is logically equal to the given 'Scope'.
0688   bool equals(const LVScope *Scope) const override;
0689 
0690   // For the given 'Scopes' returns a scope that is logically equal
0691   // to the current scope; otherwise 'nullptr'.
0692   LVScope *findEqualScope(const LVScopes *Scopes) const override;
0693 
0694   void printExtra(raw_ostream &OS, bool Full = true) const override;
0695 };
0696 
0697 // Class to represent a DWARF inlined function.
0698 class LVScopeFunctionInlined final : public LVScopeFunction {
0699   size_t CallFilenameIndex = 0;
0700   uint32_t CallLineNumber = 0;
0701   uint32_t Discriminator = 0;
0702 
0703 public:
0704   LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); }
0705   LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete;
0706   LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete;
0707   ~LVScopeFunctionInlined() = default;
0708 
0709   uint32_t getDiscriminator() const override { return Discriminator; }
0710   void setDiscriminator(uint32_t Value) override {
0711     Discriminator = Value;
0712     setHasDiscriminator();
0713   }
0714 
0715   uint32_t getCallLineNumber() const override { return CallLineNumber; }
0716   void setCallLineNumber(uint32_t Number) override { CallLineNumber = Number; }
0717   size_t getCallFilenameIndex() const override { return CallFilenameIndex; }
0718   void setCallFilenameIndex(size_t Index) override {
0719     CallFilenameIndex = Index;
0720   }
0721 
0722   // Line number for display; in the case of Inlined Functions, we use the
0723   // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
0724   std::string lineNumberAsString(bool ShowZero = false) const override {
0725     return lineAsString(getCallLineNumber(), getDiscriminator(), ShowZero);
0726   }
0727 
0728   void resolveExtra() override;
0729 
0730   // Returns true if current scope is logically equal to the given 'Scope'.
0731   bool equals(const LVScope *Scope) const override;
0732 
0733   // For the given 'Scopes' returns a scope that is logically equal
0734   // to the current scope; otherwise 'nullptr'.
0735   LVScope *findEqualScope(const LVScopes *Scopes) const override;
0736 
0737   void printExtra(raw_ostream &OS, bool Full = true) const override;
0738 };
0739 
0740 // Class to represent a DWARF subroutine type.
0741 class LVScopeFunctionType final : public LVScopeFunction {
0742 public:
0743   LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); }
0744   LVScopeFunctionType(const LVScopeFunctionType &) = delete;
0745   LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete;
0746   ~LVScopeFunctionType() = default;
0747 
0748   void resolveExtra() override;
0749 };
0750 
0751 // Class to represent a DWARF Namespace.
0752 class LVScopeNamespace final : public LVScope {
0753   LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute.
0754 
0755 public:
0756   LVScopeNamespace() : LVScope() { setIsNamespace(); }
0757   LVScopeNamespace(const LVScopeNamespace &) = delete;
0758   LVScopeNamespace &operator=(const LVScopeNamespace &) = delete;
0759   ~LVScopeNamespace() = default;
0760 
0761   // Access DW_AT_extension reference.
0762   LVScope *getReference() const override { return Reference; }
0763   void setReference(LVScope *Scope) override {
0764     Reference = Scope;
0765     setHasReference();
0766   }
0767   void setReference(LVElement *Element) override {
0768     setReference(static_cast<LVScope *>(Element));
0769   }
0770 
0771   // Returns true if current scope is logically equal to the given 'Scope'.
0772   bool equals(const LVScope *Scope) const override;
0773 
0774   // For the given 'Scopes' returns a scope that is logically equal
0775   // to the current scope; otherwise 'nullptr'.
0776   LVScope *findEqualScope(const LVScopes *Scopes) const override;
0777 
0778   void printExtra(raw_ostream &OS, bool Full = true) const override;
0779 };
0780 
0781 // Class to represent the binary file being analyzed.
0782 class LVScopeRoot final : public LVScope {
0783   size_t FileFormatNameIndex = 0;
0784 
0785 public:
0786   LVScopeRoot() : LVScope() { setIsRoot(); }
0787   LVScopeRoot(const LVScopeRoot &) = delete;
0788   LVScopeRoot &operator=(const LVScopeRoot &) = delete;
0789   ~LVScopeRoot() = default;
0790 
0791   StringRef getFileFormatName() const {
0792     return getStringPool().getString(FileFormatNameIndex);
0793   }
0794   void setFileFormatName(StringRef FileFormatName) {
0795     FileFormatNameIndex = getStringPool().getIndex(FileFormatName);
0796   }
0797 
0798   // The CodeView Reader uses scoped names. Recursively transform the
0799   // element name to use just the most inner component.
0800   void transformScopedName();
0801 
0802   // Process the collected location, ranges and calculate coverage.
0803   void processRangeInformation();
0804 
0805   // Returns true if current scope is logically equal to the given 'Scope'.
0806   bool equals(const LVScope *Scope) const override;
0807 
0808   void print(raw_ostream &OS, bool Full = true) const override;
0809   void printExtra(raw_ostream &OS, bool Full = true) const override;
0810   Error doPrintMatches(bool Split, raw_ostream &OS,
0811                        bool UseMatchedElements) const;
0812 };
0813 
0814 // Class to represent a DWARF template parameter pack
0815 // (DW_TAG_GNU_template_parameter_pack).
0816 class LVScopeTemplatePack final : public LVScope {
0817 public:
0818   LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); }
0819   LVScopeTemplatePack(const LVScopeTemplatePack &) = delete;
0820   LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
0821   ~LVScopeTemplatePack() = default;
0822 
0823   // Returns true if current scope is logically equal to the given 'Scope'.
0824   bool equals(const LVScope *Scope) const override;
0825 
0826   void printExtra(raw_ostream &OS, bool Full = true) const override;
0827 };
0828 
0829 } // end namespace logicalview
0830 } // end namespace llvm
0831 
0832 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H