blob: 8204163f34de6d3a97941558f3e8f8c585bf421f [file] [log] [blame]
//===-- LVScope.h -----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the LVScope class, which is used to describe a debug
// information scope.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
#include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
#include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
#include "llvm/Object/ObjectFile.h"
#include <list>
#include <map>
#include <set>
namespace llvm {
namespace logicalview {
// Name address, Code size.
using LVNameInfo = std::pair<LVAddress, uint64_t>;
using LVPublicNames = std::map<LVScope *, LVNameInfo>;
using LVPublicAddresses = std::map<LVAddress, LVNameInfo>;
class LVRange;
enum class LVScopeKind {
IsAggregate,
IsArray,
IsBlock,
IsCallSite,
IsCatchBlock,
IsClass,
IsCompileUnit,
IsEntryPoint,
IsEnumeration,
IsFunction,
IsFunctionType,
IsInlinedFunction,
IsLabel,
IsLexicalBlock,
IsMember,
IsNamespace,
IsRoot,
IsStructure,
IsSubprogram,
IsTemplate,
IsTemplateAlias,
IsTemplatePack,
IsTryBlock,
IsUnion,
LastEntry
};
using LVScopeKindSet = std::set<LVScopeKind>;
using LVScopeDispatch = std::map<LVScopeKind, LVScopeGetFunction>;
using LVScopeRequest = std::vector<LVScopeGetFunction>;
using LVOffsetList = std::list<LVOffset>;
using LVOffsetElementMap = std::map<LVOffset, LVElement *>;
using LVOffsetLinesMap = std::map<LVOffset, LVLines *>;
using LVOffsetLocationsMap = std::map<LVOffset, LVLocations *>;
using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>;
using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsetList *>;
// Class to represent a DWARF Scope.
class LVScope : public LVElement {
enum class Property {
HasDiscriminator,
CanHaveRanges,
CanHaveLines,
HasGlobals,
HasLocals,
HasLines,
HasScopes,
HasSymbols,
HasTypes,
IsComdat,
HasComdatScopes, // Compile Unit has comdat functions.
HasRanges,
AddedMissing, // Added missing referenced symbols.
LastEntry
};
// Typed bitvector with kinds and properties for this scope.
LVProperties<LVScopeKind> Kinds;
LVProperties<Property> Properties;
static LVScopeDispatch Dispatch;
// Coverage factor in units (bytes).
unsigned CoverageFactor = 0;
// Calculate coverage factor.
void calculateCoverage() {
float CoveragePercentage = 0;
LVLocation::calculateCoverage(Ranges, CoverageFactor, CoveragePercentage);
}
// Decide if the scope will be printed, using some conditions given by:
// only-globals, only-locals, a-pattern.
bool resolvePrinting() const;
// Find the current scope in the given 'Targets'.
LVScope *findIn(const LVScopes *Targets) const;
// Traverse the scope parent tree, executing the given callback function
// on each scope.
void traverseParents(LVScopeGetFunction GetFunction,
LVScopeSetFunction SetFunction);
protected:
// Types, Symbols, Scopes, Lines, Locations in this scope.
LVAutoTypes *Types = nullptr;
LVAutoSymbols *Symbols = nullptr;
LVAutoScopes *Scopes = nullptr;
LVAutoLines *Lines = nullptr;
LVAutoLocations *Ranges = nullptr;
// Vector of elements (types, scopes and symbols).
// It is the union of (*Types, *Symbols and *Scopes) to be used for
// the following reasons:
// - Preserve the order the logical elements are read in.
// - To have a single container with all the logical elements, when
// the traversal does not require any specific element kind.
LVElements *Children = nullptr;
// Resolve the template parameters/arguments relationship.
void resolveTemplate();
void printEncodedArgs(raw_ostream &OS, bool Full) const;
void printActiveRanges(raw_ostream &OS, bool Full = true) const;
virtual void printSizes(raw_ostream &OS) const {}
virtual void printSummary(raw_ostream &OS) const {}
// Encoded template arguments.
virtual StringRef getEncodedArgs() const { return StringRef(); }
virtual void setEncodedArgs(StringRef EncodedArgs) {}
public:
LVScope() : LVElement(LVSubclassID::LV_SCOPE) {
setIsScope();
setIncludeInPrint();
}
LVScope(const LVScope &) = delete;
LVScope &operator=(const LVScope &) = delete;
virtual ~LVScope();
static bool classof(const LVElement *Element) {
return Element->getSubclassID() == LVSubclassID::LV_SCOPE;
}
KIND(LVScopeKind, IsAggregate);
KIND(LVScopeKind, IsArray);
KIND_2(LVScopeKind, IsBlock, CanHaveRanges, CanHaveLines);
KIND_1(LVScopeKind, IsCallSite, IsFunction);
KIND_1(LVScopeKind, IsCatchBlock, IsBlock);
KIND_1(LVScopeKind, IsClass, IsAggregate);
KIND_3(LVScopeKind, IsCompileUnit, CanHaveRanges, CanHaveLines,
TransformName);
KIND_1(LVScopeKind, IsEntryPoint, IsFunction);
KIND(LVScopeKind, IsEnumeration);
KIND_2(LVScopeKind, IsFunction, CanHaveRanges, CanHaveLines);
KIND_1(LVScopeKind, IsFunctionType, IsFunction);
KIND_2(LVScopeKind, IsInlinedFunction, IsFunction, IsInlined);
KIND_1(LVScopeKind, IsLabel, IsFunction);
KIND_1(LVScopeKind, IsLexicalBlock, IsBlock);
KIND(LVScopeKind, IsMember);
KIND(LVScopeKind, IsNamespace);
KIND_1(LVScopeKind, IsRoot, TransformName);
KIND_1(LVScopeKind, IsStructure, IsAggregate);
KIND_1(LVScopeKind, IsSubprogram, IsFunction);
KIND(LVScopeKind, IsTemplate);
KIND(LVScopeKind, IsTemplateAlias);
KIND(LVScopeKind, IsTemplatePack);
KIND_1(LVScopeKind, IsTryBlock, IsBlock);
KIND_1(LVScopeKind, IsUnion, IsAggregate);
PROPERTY(Property, HasDiscriminator);
PROPERTY(Property, CanHaveRanges);
PROPERTY(Property, CanHaveLines);
PROPERTY(Property, HasGlobals);
PROPERTY(Property, HasLocals);
PROPERTY(Property, HasLines);
PROPERTY(Property, HasScopes);
PROPERTY(Property, HasSymbols);
PROPERTY(Property, HasTypes);
PROPERTY(Property, IsComdat);
PROPERTY(Property, HasComdatScopes);
PROPERTY(Property, HasRanges);
PROPERTY(Property, AddedMissing);
bool isCompileUnit() const override { return getIsCompileUnit(); }
bool isRoot() const override { return getIsRoot(); }
const char *kind() const override;
// Get the specific children.
const LVLines *getLines() const { return Lines; }
const LVLocations *getRanges() const { return Ranges; }
const LVScopes *getScopes() const { return Scopes; }
const LVSymbols *getSymbols() const { return Symbols; }
const LVTypes *getTypes() const { return Types; }
const LVElements *getChildren() const { return Children; }
void addElement(LVElement *Element);
void addElement(LVLine *Line);
void addElement(LVScope *Scope);
void addElement(LVSymbol *Symbol);
void addElement(LVType *Type);
void addObject(LVLocation *Location);
void addObject(LVAddress LowerAddress, LVAddress UpperAddress);
void addToChildren(LVElement *Element);
// Add the missing elements from the given 'Reference', which is the
// scope associated with any DW_AT_specification, DW_AT_abstract_origin.
void addMissingElements(LVScope *Reference);
// Traverse the scope parent tree and the children, executing the given
// callback function on each element.
void traverseParentsAndChildren(LVObjectGetFunction GetFunction,
LVObjectSetFunction SetFunction);
// Get the size of specific children.
size_t lineCount() const { return Lines ? Lines->size() : 0; }
size_t rangeCount() const { return Ranges ? Ranges->size() : 0; }
size_t scopeCount() const { return Scopes ? Scopes->size() : 0; }
size_t symbolCount() const { return Symbols ? Symbols->size() : 0; }
size_t typeCount() const { return Types ? Types->size() : 0; }
// Find containing parent for the given address.
LVScope *outermostParent(LVAddress Address);
// Get all the locations associated with symbols.
void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation,
bool RecordInvalid = false);
void getRanges(LVLocations &LocationList, LVValidLocation ValidLocation,
bool RecordInvalid = false);
void getRanges(LVRange &RangeList);
unsigned getCoverageFactor() const { return CoverageFactor; }
Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
bool Full = true) const override;
// Sort the logical elements using the criteria specified by the
// command line option '--output-sort'.
void sort();
// Get template parameter types.
bool getTemplateParameterTypes(LVTypes &Params);
// DW_AT_specification, DW_AT_abstract_origin, DW_AT_extension.
virtual LVScope *getReference() const { return nullptr; }
LVScope *getCompileUnitParent() const override {
return LVElement::getCompileUnitParent();
}
// Follow a chain of references given by DW_AT_abstract_origin and/or
// DW_AT_specification and update the scope name.
StringRef resolveReferencesChain();
bool removeElement(LVElement *Element) override;
void updateLevel(LVScope *Parent, bool Moved) override;
void resolve() override;
void resolveName() override;
void resolveReferences() override;
// Return the chain of parents as a string.
void getQualifiedName(std::string &QualifiedName) const;
// Encode the template arguments.
void encodeTemplateArguments(std::string &Name) const;
void encodeTemplateArguments(std::string &Name, const LVTypes *Types) const;
void resolveElements();
// Iterate through the 'References' set and check that all its elements
// are present in the 'Targets' set. For a missing element, mark its
// parents as missing.
static void markMissingParents(const LVScopes *References,
const LVScopes *Targets,
bool TraverseChildren);
// Checks if the current scope is contained within the target scope.
// Depending on the result, the callback may be performed.
virtual void markMissingParents(const LVScope *Target, bool TraverseChildren);
// Returns true if the current scope and the given 'Scope' have the
// same number of children.
virtual bool equalNumberOfChildren(const LVScope *Scope) const;
// Returns true if current scope is logically equal to the given 'Scope'.
virtual bool equals(const LVScope *Scope) const;
// Returns true if the given 'References' are logically equal to the
// given 'Targets'.
static bool equals(const LVScopes *References, const LVScopes *Targets);
// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
virtual LVScope *findEqualScope(const LVScopes *Scopes) const;
// Report the current scope as missing or added during comparison.
void report(LVComparePass Pass) override;
static LVScopeDispatch &getDispatch() { return Dispatch; }
void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
virtual void printWarnings(raw_ostream &OS, bool Full = true) const {}
virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() const override { print(dbgs()); }
#endif
};
// Class to represent a DWARF Union/Structure/Class.
class LVScopeAggregate final : public LVScope {
LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
size_t EncodedArgsIndex = 0; // Template encoded arguments.
public:
LVScopeAggregate() : LVScope() {}
LVScopeAggregate(const LVScopeAggregate &) = delete;
LVScopeAggregate &operator=(const LVScopeAggregate &) = delete;
~LVScopeAggregate() = default;
// DW_AT_specification, DW_AT_abstract_origin.
LVScope *getReference() const override { return Reference; }
void setReference(LVScope *Scope) override {
Reference = Scope;
setHasReference();
}
void setReference(LVElement *Element) override {
setReference(static_cast<LVScope *>(Element));
}
StringRef getEncodedArgs() const override {
return getStringPool().getString(EncodedArgsIndex);
}
void setEncodedArgs(StringRef EncodedArgs) override {
EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
}
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF Template alias.
class LVScopeAlias final : public LVScope {
public:
LVScopeAlias() : LVScope() {
setIsTemplateAlias();
setIsTemplate();
}
LVScopeAlias(const LVScopeAlias &) = delete;
LVScopeAlias &operator=(const LVScopeAlias &) = delete;
~LVScopeAlias() = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF array (DW_TAG_array_type).
class LVScopeArray final : public LVScope {
public:
LVScopeArray() : LVScope() { setIsArray(); }
LVScopeArray(const LVScopeArray &) = delete;
LVScopeArray &operator=(const LVScopeArray &) = delete;
~LVScopeArray() = default;
void resolveExtra() override;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF Compilation Unit (CU).
class LVScopeCompileUnit final : public LVScope {
// Names (files and directories) used by the Compile Unit.
std::vector<size_t> Filenames;
// As the .debug_pubnames section has been removed in DWARF5, we have a
// similar functionality, which is used by the decoded functions. We use
// the low-pc and high-pc for those scopes that are marked as public, in
// order to support DWARF and CodeView.
LVPublicNames PublicNames;
// Toolchain producer.
size_t ProducerIndex = 0;
// Compilation directory name.
size_t CompilationDirectoryIndex = 0;
// Keep record of elements. They are needed at the compilation unit level
// to print the summary at the end of the printing.
LVCounter Allocated;
LVCounter Found;
LVCounter Printed;
// Elements that match a given command line pattern.
LVElements MatchedElements;
LVScopes MatchedScopes;
// It records the mapping between logical lines representing a debug line
// entry and its address in the text section. It is used to find a line
// giving its exact or closest address. To support comdat functions, all
// addresses for the same section are recorded in the same map.
using LVAddressToLine = std::map<LVAddress, LVLine *>;
LVDoubleMap<LVSectionIndex, LVAddress, LVLine *> SectionMappings;
// DWARF Tags (Tag, Element list).
LVTagOffsetsMap DebugTags;
// Offsets associated with objects being flagged as having invalid data
// (ranges, locations, lines zero or coverages).
LVOffsetElementMap WarningOffsets;
// Symbols with invalid locations. (Symbol, Location List).
LVOffsetLocationsMap InvalidLocations;
// Symbols with invalid coverage values.
LVOffsetSymbolMap InvalidCoverages;
// Scopes with invalid ranges (Scope, Range list).
LVOffsetLocationsMap InvalidRanges;
// Scopes with lines zero (Scope, Line list).
LVOffsetLinesMap LinesZero;
// Record scopes contribution in bytes to the debug information.
using LVSizesMap = std::map<const LVScope *, LVOffset>;
LVSizesMap Sizes;
LVOffset CUContributionSize = 0;
// Helper function to add an invalid location/range.
void addInvalidLocationOrRange(LVLocation *Location, LVElement *Element,
LVOffsetLocationsMap *Map) {
LVOffset Offset = Element->getOffset();
addInvalidOffset(Offset, Element);
addItem<LVOffsetLocationsMap, LVLocations, LVOffset, LVLocation *>(
Map, Offset, Location);
}
// Record scope sizes indexed by lexical level.
// Setting an initial size that will cover a very deep nested scopes.
const size_t TotalInitialSize = 8;
using LVTotalsEntry = std::pair<unsigned, float>;
SmallVector<LVTotalsEntry> Totals;
// Maximum seen lexical level. It is used to control how many entries
// in the 'Totals' vector are valid values.
LVLevel MaxSeenLevel = 0;
// Get the line located at the given address.
LVLine *lineLowerBound(LVAddress Address, LVScope *Scope) const;
LVLine *lineUpperBound(LVAddress Address, LVScope *Scope) const;
void printScopeSize(const LVScope *Scope, raw_ostream &OS);
void printScopeSize(const LVScope *Scope, raw_ostream &OS) const {
(const_cast<LVScopeCompileUnit *>(this))->printScopeSize(Scope, OS);
}
void printTotals(raw_ostream &OS) const;
protected:
void printSizes(raw_ostream &OS) const override;
void printSummary(raw_ostream &OS) const override;
public:
LVScopeCompileUnit() : LVScope(), Totals(TotalInitialSize, {0, 0.0}) {
setIsCompileUnit();
}
LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
~LVScopeCompileUnit() {
deleteList<LVTagOffsetsMap>(DebugTags);
deleteList<LVOffsetLocationsMap>(InvalidLocations);
deleteList<LVOffsetLocationsMap>(InvalidRanges);
deleteList<LVOffsetLinesMap>(LinesZero);
}
LVScope *getCompileUnitParent() const override {
return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));
}
// Add line to address mapping.
void addMapping(LVLine *Line, LVSectionIndex SectionIndex);
LVLineRange lineRange(LVLocation *Location) const;
LVNameInfo NameNone = {UINT64_MAX, 0};
void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC) {
PublicNames.emplace(std::piecewise_construct, std::forward_as_tuple(Scope),
std::forward_as_tuple(LowPC, HighPC - LowPC));
}
const LVNameInfo &findPublicName(LVScope *Scope) {
LVPublicNames::iterator Iter = PublicNames.find(Scope);
return (Iter != PublicNames.end()) ? Iter->second : NameNone;
}
const LVPublicNames &getPublicNames() const { return PublicNames; }
// The base address of the scope for any of the debugging information
// entries listed, is given by either the DW_AT_low_pc attribute or the
// first address in the first range entry in the list of ranges given by
// the DW_AT_ranges attribute.
LVAddress getBaseAddress() const {
return Ranges ? Ranges->front()->getLowerAddress() : 0;
}
StringRef getCompilationDirectory() const {
return getStringPool().getString(CompilationDirectoryIndex);
}
void setCompilationDirectory(StringRef CompilationDirectory) {
CompilationDirectoryIndex = getStringPool().getIndex(CompilationDirectory);
}
StringRef getFilename(size_t Index) const;
void addFilename(StringRef Name) {
Filenames.push_back(getStringPool().getIndex(Name));
}
StringRef getProducer() const override {
return getStringPool().getString(ProducerIndex);
}
void setProducer(StringRef ProducerName) override {
ProducerIndex = getStringPool().getIndex(ProducerName);
}
// Record DWARF tags.
void addDebugTag(dwarf::Tag Target, LVOffset Offset);
// Record elements with invalid offsets.
void addInvalidOffset(LVOffset Offset, LVElement *Element);
// Record symbols with invalid coverage values.
void addInvalidCoverage(LVSymbol *Symbol);
// Record symbols with invalid locations.
void addInvalidLocation(LVLocation *Location);
// Record scopes with invalid ranges.
void addInvalidRange(LVLocation *Location);
// Record line zero.
void addLineZero(LVLine *Line);
const LVTagOffsetsMap &getDebugTags() const { return DebugTags; }
const LVOffsetElementMap &getWarningOffsets() const { return WarningOffsets; }
const LVOffsetLocationsMap &getInvalidLocations() const {
return InvalidLocations;
}
const LVOffsetSymbolMap &getInvalidCoverages() const {
return InvalidCoverages;
}
const LVOffsetLocationsMap &getInvalidRanges() const { return InvalidRanges; }
const LVOffsetLinesMap &getLinesZero() const { return LinesZero; }
// Process ranges, locations and calculate coverage.
void processRangeLocationCoverage(
LVValidLocation ValidLocation = &LVLocation::validateRanges);
// Add matched element.
void addMatched(LVElement *Element) { MatchedElements.push_back(Element); }
void addMatched(LVScope *Scope) { MatchedScopes.push_back(Scope); }
void propagatePatternMatch();
const LVElements &getMatchedElements() const { return MatchedElements; }
const LVScopes &getMatchedScopes() const { return MatchedScopes; }
void printLocalNames(raw_ostream &OS, bool Full = true) const;
void printSummary(raw_ostream &OS, const LVCounter &Counter,
const char *Header) const;
void incrementPrintedLines();
void incrementPrintedScopes();
void incrementPrintedSymbols();
void incrementPrintedTypes();
// Values are used by '--summary' option (allocated).
void increment(LVLine *Line);
void increment(LVScope *Scope);
void increment(LVSymbol *Symbol);
void increment(LVType *Type);
// A new element has been added to the scopes tree. Take the following steps:
// Increase the added element counters, for printing summary.
// During comparison notify the Reader of the new element.
void addedElement(LVLine *Line);
void addedElement(LVScope *Scope);
void addedElement(LVSymbol *Symbol);
void addedElement(LVType *Type);
void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper);
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
void printWarnings(raw_ostream &OS, bool Full = true) const override;
void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) override;
};
// Class to represent a DWARF enumerator (DW_TAG_enumeration_type).
class LVScopeEnumeration final : public LVScope {
public:
LVScopeEnumeration() : LVScope() { setIsEnumeration(); }
LVScopeEnumeration(const LVScopeEnumeration &) = delete;
LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
~LVScopeEnumeration() = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF formal parameter pack
// (DW_TAG_GNU_formal_parameter_pack).
class LVScopeFormalPack final : public LVScope {
public:
LVScopeFormalPack() : LVScope() { setIsTemplatePack(); }
LVScopeFormalPack(const LVScopeFormalPack &) = delete;
LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
~LVScopeFormalPack() = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF Function.
class LVScopeFunction : public LVScope {
LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin.
size_t LinkageNameIndex = 0; // Function DW_AT_linkage_name attribute.
size_t EncodedArgsIndex = 0; // Template encoded arguments.
public:
LVScopeFunction() : LVScope() {}
LVScopeFunction(const LVScopeFunction &) = delete;
LVScopeFunction &operator=(const LVScopeFunction &) = delete;
virtual ~LVScopeFunction() = default;
// DW_AT_specification, DW_AT_abstract_origin.
LVScope *getReference() const override { return Reference; }
void setReference(LVScope *Scope) override {
Reference = Scope;
setHasReference();
}
void setReference(LVElement *Element) override {
setReference(static_cast<LVScope *>(Element));
}
StringRef getEncodedArgs() const override {
return getStringPool().getString(EncodedArgsIndex);
}
void setEncodedArgs(StringRef EncodedArgs) override {
EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
}
void setLinkageName(StringRef LinkageName) override {
LinkageNameIndex = getStringPool().getIndex(LinkageName);
}
StringRef getLinkageName() const override {
return getStringPool().getString(LinkageNameIndex);
}
size_t getLinkageNameIndex() const override { return LinkageNameIndex; }
void setName(StringRef ObjectName) override;
void resolveExtra() override;
void resolveReferences() override;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF inlined function.
class LVScopeFunctionInlined final : public LVScopeFunction {
size_t CallFilenameIndex = 0;
uint32_t CallLineNumber = 0;
uint32_t Discriminator = 0;
public:
LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); }
LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete;
LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete;
~LVScopeFunctionInlined() = default;
uint32_t getDiscriminator() const override { return Discriminator; }
void setDiscriminator(uint32_t Value) override {
Discriminator = Value;
setHasDiscriminator();
}
uint32_t getCallLineNumber() const override { return CallLineNumber; }
void setCallLineNumber(uint32_t Number) override { CallLineNumber = Number; }
size_t getCallFilenameIndex() const override { return CallFilenameIndex; }
void setCallFilenameIndex(size_t Index) override {
CallFilenameIndex = Index;
}
// Line number for display; in the case of Inlined Functions, we use the
// DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
std::string lineNumberAsString(bool ShowZero = false) const override {
return lineAsString(getCallLineNumber(), getDiscriminator(), ShowZero);
}
void resolveExtra() override;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent a DWARF subroutine type.
class LVScopeFunctionType final : public LVScopeFunction {
public:
LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); }
LVScopeFunctionType(const LVScopeFunctionType &) = delete;
LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete;
~LVScopeFunctionType() = default;
void resolveExtra() override;
};
// Class to represent a DWARF Namespace.
class LVScopeNamespace final : public LVScope {
LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute.
public:
LVScopeNamespace() : LVScope() { setIsNamespace(); }
LVScopeNamespace(const LVScopeNamespace &) = delete;
LVScopeNamespace &operator=(const LVScopeNamespace &) = delete;
~LVScopeNamespace() = default;
// Access DW_AT_extension reference.
LVScope *getReference() const override { return Reference; }
void setReference(LVScope *Scope) override {
Reference = Scope;
setHasReference();
}
void setReference(LVElement *Element) override {
setReference(static_cast<LVScope *>(Element));
}
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
// Class to represent the binary file being analyzed.
class LVScopeRoot final : public LVScope {
size_t FileFormatNameIndex = 0;
public:
LVScopeRoot() : LVScope() { setIsRoot(); }
LVScopeRoot(const LVScopeRoot &) = delete;
LVScopeRoot &operator=(const LVScopeRoot &) = delete;
~LVScopeRoot() = default;
StringRef getFileFormatName() const {
return getStringPool().getString(FileFormatNameIndex);
}
void setFileFormatName(StringRef FileFormatName) {
FileFormatNameIndex = getStringPool().getIndex(FileFormatName);
}
// Process the collected location, ranges and calculate coverage.
void processRangeInformation();
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
Error doPrintMatches(bool Split, raw_ostream &OS,
bool UseMatchedElements) const;
};
// Class to represent a DWARF template parameter pack
// (DW_TAG_GNU_template_parameter_pack).
class LVScopeTemplatePack final : public LVScope {
public:
LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); }
LVScopeTemplatePack(const LVScopeTemplatePack &) = delete;
LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
~LVScopeTemplatePack() = default;
// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
} // end namespace logicalview
} // end namespace llvm
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H