clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
332 lines
11 KiB
C++
332 lines
11 KiB
C++
//===-- LVObject.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 LVObject class, which is used to describe a debug
|
|
// information object.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
|
|
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
|
|
|
|
#include "llvm/BinaryFormat/Dwarf.h"
|
|
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
|
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
|
#include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
|
|
#include <limits>
|
|
#include <list>
|
|
#include <string>
|
|
|
|
namespace llvm {
|
|
namespace dwarf {
|
|
// Support for CodeView ModifierOptions::Unaligned.
|
|
constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
|
|
} // namespace dwarf
|
|
} // namespace llvm
|
|
|
|
namespace llvm {
|
|
namespace logicalview {
|
|
|
|
using LVSectionIndex = uint64_t;
|
|
using LVAddress = uint64_t;
|
|
using LVHalf = uint16_t;
|
|
using LVLevel = uint32_t;
|
|
using LVOffset = uint64_t;
|
|
using LVSigned = int64_t;
|
|
using LVUnsigned = uint64_t;
|
|
using LVSmall = uint8_t;
|
|
|
|
class LVElement;
|
|
class LVLine;
|
|
class LVLocation;
|
|
class LVLocationSymbol;
|
|
class LVObject;
|
|
class LVOperation;
|
|
class LVScope;
|
|
class LVSymbol;
|
|
class LVType;
|
|
|
|
class LVOptions;
|
|
class LVPatterns;
|
|
|
|
StringRef typeNone();
|
|
StringRef typeVoid();
|
|
StringRef typeInt();
|
|
StringRef typeUnknown();
|
|
StringRef emptyString();
|
|
|
|
using LVElementSetFunction = void (LVElement::*)();
|
|
using LVElementGetFunction = bool (LVElement::*)() const;
|
|
using LVLineSetFunction = void (LVLine::*)();
|
|
using LVLineGetFunction = bool (LVLine::*)() const;
|
|
using LVObjectSetFunction = void (LVObject::*)();
|
|
using LVObjectGetFunction = bool (LVObject::*)() const;
|
|
using LVScopeSetFunction = void (LVScope::*)();
|
|
using LVScopeGetFunction = bool (LVScope::*)() const;
|
|
using LVSymbolSetFunction = void (LVSymbol::*)();
|
|
using LVSymbolGetFunction = bool (LVSymbol::*)() const;
|
|
using LVTypeSetFunction = void (LVType::*)();
|
|
using LVTypeGetFunction = bool (LVType::*)() const;
|
|
|
|
using LVElements = SmallVector<LVElement *, 8>;
|
|
using LVLines = SmallVector<LVLine *, 8>;
|
|
using LVLocations = SmallVector<LVLocation *, 8>;
|
|
using LVOperations = SmallVector<LVOperation *, 8>;
|
|
using LVScopes = SmallVector<LVScope *, 8>;
|
|
using LVSymbols = SmallVector<LVSymbol *, 8>;
|
|
using LVTypes = SmallVector<LVType *, 8>;
|
|
|
|
using LVOffsets = SmallVector<LVOffset, 8>;
|
|
|
|
const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
|
|
|
|
enum class LVBinaryType { NONE, ELF, COFF };
|
|
enum class LVComparePass { Missing, Added };
|
|
|
|
// Validate functions.
|
|
using LVValidLocation = bool (LVLocation::*)();
|
|
|
|
// Keep counters of objects.
|
|
struct LVCounter {
|
|
unsigned Lines = 0;
|
|
unsigned Scopes = 0;
|
|
unsigned Symbols = 0;
|
|
unsigned Types = 0;
|
|
void reset() {
|
|
Lines = 0;
|
|
Scopes = 0;
|
|
Symbols = 0;
|
|
Types = 0;
|
|
}
|
|
};
|
|
|
|
class LVObject {
|
|
enum class Property {
|
|
IsLocation, // Location.
|
|
IsGlobalReference, // This object is being referenced from another CU.
|
|
IsGeneratedName, // The Object name was generated.
|
|
IsResolved, // Object has been resolved.
|
|
IsResolvedName, // Object name has been resolved.
|
|
IsDiscarded, // Object has been stripped by the linker.
|
|
IsOptimized, // Object has been optimized by the compiler.
|
|
IsAdded, // Object has been 'added'.
|
|
IsMatched, // Object has been matched to a given pattern.
|
|
IsMissing, // Object is 'missing'.
|
|
IsMissingLink, // Object is indirectly 'missing'.
|
|
IsInCompare, // In 'compare' mode.
|
|
IsFileFromReference, // File ID from specification.
|
|
IsLineFromReference, // Line No from specification.
|
|
HasMoved, // The object was moved from 'target' to 'reference'.
|
|
HasPattern, // The object has a pattern.
|
|
IsFinalized, // CodeView object is finalized.
|
|
IsReferenced, // CodeView object being referenced.
|
|
HasCodeViewLocation, // CodeView object with debug location.
|
|
LastEntry
|
|
};
|
|
// Typed bitvector with properties for this object.
|
|
LVProperties<Property> Properties;
|
|
|
|
LVOffset Offset = 0;
|
|
uint32_t LineNumber = 0;
|
|
LVLevel ScopeLevel = 0;
|
|
union {
|
|
dwarf::Tag Tag;
|
|
dwarf::Attribute Attr;
|
|
LVSmall Opcode;
|
|
} TagAttrOpcode = {dwarf::DW_TAG_null};
|
|
|
|
// The parent of this object (nullptr if the root scope). For locations,
|
|
// the parent is a symbol object; otherwise it is a scope object.
|
|
union {
|
|
LVElement *Element;
|
|
LVScope *Scope;
|
|
LVSymbol *Symbol;
|
|
} Parent = {nullptr};
|
|
|
|
// We do not support any object duplication, as they are created by parsing
|
|
// the debug information. There is only the case where we need a very basic
|
|
// object, to manipulate its offset, line number and scope level. Allow the
|
|
// copy constructor to create that object; it is used to print a reference
|
|
// to another object and in the case of templates, to print its encoded args.
|
|
LVObject(const LVObject &Object) {
|
|
#ifndef NDEBUG
|
|
incID();
|
|
#endif
|
|
Properties = Object.Properties;
|
|
Offset = Object.Offset;
|
|
LineNumber = Object.LineNumber;
|
|
ScopeLevel = Object.ScopeLevel;
|
|
TagAttrOpcode = Object.TagAttrOpcode;
|
|
Parent = Object.Parent;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
// This is an internal ID used for debugging logical elements. It is used
|
|
// for cases where an unique offset within the binary input file is not
|
|
// available.
|
|
static uint64_t GID;
|
|
uint64_t ID = 0;
|
|
|
|
void incID() {
|
|
++GID;
|
|
ID = GID;
|
|
}
|
|
#endif
|
|
|
|
protected:
|
|
// Get a string representation for the given number and discriminator.
|
|
std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
|
|
bool ShowZero) const;
|
|
|
|
// Get a string representation for the given number.
|
|
std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
|
|
|
|
// Print the Filename or Pathname.
|
|
// Empty implementation for those objects that do not have any user
|
|
// source file references, such as debug locations.
|
|
virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
|
|
|
|
public:
|
|
LVObject() {
|
|
#ifndef NDEBUG
|
|
incID();
|
|
#endif
|
|
};
|
|
LVObject &operator=(const LVObject &) = delete;
|
|
virtual ~LVObject() = default;
|
|
|
|
PROPERTY(Property, IsLocation);
|
|
PROPERTY(Property, IsGlobalReference);
|
|
PROPERTY(Property, IsGeneratedName);
|
|
PROPERTY(Property, IsResolved);
|
|
PROPERTY(Property, IsResolvedName);
|
|
PROPERTY(Property, IsDiscarded);
|
|
PROPERTY(Property, IsOptimized);
|
|
PROPERTY(Property, IsAdded);
|
|
PROPERTY(Property, IsMatched);
|
|
PROPERTY(Property, IsMissing);
|
|
PROPERTY(Property, IsMissingLink);
|
|
PROPERTY(Property, IsInCompare);
|
|
PROPERTY(Property, IsFileFromReference);
|
|
PROPERTY(Property, IsLineFromReference);
|
|
PROPERTY(Property, HasMoved);
|
|
PROPERTY(Property, HasPattern);
|
|
PROPERTY(Property, IsFinalized);
|
|
PROPERTY(Property, IsReferenced);
|
|
PROPERTY(Property, HasCodeViewLocation);
|
|
|
|
// True if the scope has been named or typed or with line number.
|
|
virtual bool isNamed() const { return false; }
|
|
virtual bool isTyped() const { return false; }
|
|
virtual bool isFiled() const { return false; }
|
|
bool isLined() const { return LineNumber != 0; }
|
|
|
|
// DWARF tag, attribute or expression opcode.
|
|
dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
|
|
void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
|
|
dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
|
|
void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
|
|
LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
|
|
void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
|
|
|
|
// DIE offset.
|
|
LVOffset getOffset() const { return Offset; }
|
|
void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
|
|
|
|
// Level where this object is located.
|
|
LVLevel getLevel() const { return ScopeLevel; }
|
|
void setLevel(LVLevel Level) { ScopeLevel = Level; }
|
|
|
|
virtual StringRef getName() const { return StringRef(); }
|
|
virtual void setName(StringRef ObjectName) {}
|
|
|
|
LVElement *getParent() const {
|
|
assert((!Parent.Element || static_cast<LVElement *>(Parent.Element)) &&
|
|
"Invalid element");
|
|
return Parent.Element;
|
|
}
|
|
LVScope *getParentScope() const {
|
|
assert((!Parent.Scope || static_cast<LVScope *>(Parent.Scope)) &&
|
|
"Invalid scope");
|
|
return Parent.Scope;
|
|
}
|
|
LVSymbol *getParentSymbol() const {
|
|
assert((!Parent.Symbol || static_cast<LVSymbol *>(Parent.Symbol)) &&
|
|
"Invalid symbol");
|
|
return Parent.Symbol;
|
|
}
|
|
void setParent(LVScope *Scope);
|
|
void setParent(LVSymbol *Symbol);
|
|
void resetParent() { Parent = {nullptr}; }
|
|
|
|
virtual LVAddress getLowerAddress() const { return 0; }
|
|
virtual void setLowerAddress(LVAddress Address) {}
|
|
virtual LVAddress getUpperAddress() const { return 0; }
|
|
virtual void setUpperAddress(LVAddress Address) {}
|
|
|
|
uint32_t getLineNumber() const { return LineNumber; }
|
|
void setLineNumber(uint32_t Number) { LineNumber = Number; }
|
|
|
|
virtual const char *kind() const { return nullptr; }
|
|
|
|
std::string indentAsString() const;
|
|
std::string indentAsString(LVLevel Level) const;
|
|
|
|
// String used as padding for printing objects with no line number.
|
|
virtual std::string noLineAsString(bool ShowZero) const;
|
|
|
|
// 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.
|
|
virtual std::string lineNumberAsString(bool ShowZero = false) const {
|
|
return lineAsString(getLineNumber(), 0, ShowZero);
|
|
}
|
|
std::string lineNumberAsStringStripped(bool ShowZero = false) const;
|
|
|
|
// This function prints the logical view to an output stream.
|
|
// Split: Prints the compilation unit view to a file.
|
|
// Match: Prints the object only if it satisfies the patterns collected
|
|
// from the command line. See the '--select' option.
|
|
// Print: Print the object only if satisfies the conditions specified by
|
|
// the different '--print' options.
|
|
// Full: Prints full information for objects representing debug locations,
|
|
// aggregated scopes, compile unit, functions and namespaces.
|
|
virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
|
|
bool Full = true) const;
|
|
void printAttributes(raw_ostream &OS, bool Full = true) const;
|
|
void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
|
|
LVObject *Parent, StringRef Value,
|
|
bool UseQuotes = false, bool PrintRef = false) const;
|
|
|
|
// Mark branch as missing (current element and parents).
|
|
void markBranchAsMissing();
|
|
|
|
// Prints the common information for an object (name, type, etc).
|
|
virtual void print(raw_ostream &OS, bool Full = true) const;
|
|
// Prints additional information for an object, depending on its kind
|
|
// (class attributes, debug ranges, files, directories, etc).
|
|
virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
|
|
|
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
virtual void dump() const { print(dbgs()); }
|
|
#endif
|
|
|
|
uint64_t getID() const {
|
|
return
|
|
#ifndef NDEBUG
|
|
ID;
|
|
#else
|
|
0;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
} // end namespace logicalview
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
|