Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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