170 lines
5.6 KiB
C++
170 lines
5.6 KiB
C++
//===-- LVObject.cpp ------------------------------------------------------===//
|
|
//
|
|
// 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 implements the LVObject class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
|
|
#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
|
|
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
|
|
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
|
|
#include <iomanip>
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::logicalview;
|
|
|
|
#define DEBUG_TYPE "Object"
|
|
|
|
#ifndef NDEBUG
|
|
uint64_t LVObject::GID = 0;
|
|
#endif
|
|
|
|
StringRef llvm::logicalview::typeNone() { return StringRef(); }
|
|
StringRef llvm::logicalview::typeVoid() { return "void"; }
|
|
StringRef llvm::logicalview::typeInt() { return "int"; }
|
|
StringRef llvm::logicalview::typeUnknown() { return "?"; }
|
|
StringRef llvm::logicalview::emptyString() { return StringRef(); }
|
|
|
|
// Get a string representing the indentation level.
|
|
std::string LVObject::indentAsString(LVLevel Level) const {
|
|
return std::string(Level * 2, ' ');
|
|
}
|
|
|
|
// Get a string representing the indentation level.
|
|
std::string LVObject::indentAsString() const {
|
|
return (options().getPrintFormatting() || options().getPrintOffset())
|
|
? indentAsString(ScopeLevel)
|
|
: "";
|
|
}
|
|
|
|
// String used as padding for printing objects with no line number.
|
|
std::string LVObject::noLineAsString(bool ShowZero) const {
|
|
return std::string(8, ' ');
|
|
}
|
|
|
|
// Get a string representation for the given number and discriminator.
|
|
std::string LVObject::lineAsString(uint32_t LineNumber, LVHalf Discriminator,
|
|
bool ShowZero) const {
|
|
// The representation is formatted as:
|
|
// a) line number (xxxxx) and discriminator (yy): 'xxxxx,yy'
|
|
// b) Only line number (xxxxx): 'xxxxx '
|
|
// c) No line number: ' '
|
|
std::stringstream Stream;
|
|
if (LineNumber) {
|
|
if (Discriminator && options().getAttributeDiscriminator())
|
|
Stream << std::setw(5) << LineNumber << "," << std::left << std::setw(2)
|
|
<< Discriminator;
|
|
else
|
|
Stream << std::setw(5) << LineNumber << " ";
|
|
} else
|
|
Stream << noLineAsString(ShowZero);
|
|
|
|
if (options().getInternalNone())
|
|
Stream.str(noLineAsString(ShowZero));
|
|
|
|
return Stream.str();
|
|
}
|
|
|
|
// Same as 'LineString' but with stripped whitespaces.
|
|
std::string LVObject::lineNumberAsStringStripped(bool ShowZero) const {
|
|
return std::string(StringRef(lineNumberAsString(ShowZero)).trim());
|
|
}
|
|
|
|
std::string LVObject::referenceAsString(uint32_t LineNumber,
|
|
bool Spaces) const {
|
|
std::string String;
|
|
raw_string_ostream Stream(String);
|
|
if (LineNumber)
|
|
Stream << "@" << LineNumber << (Spaces ? " " : "");
|
|
|
|
return String;
|
|
}
|
|
|
|
void LVObject::setParent(LVScope *Scope) {
|
|
Parent.Scope = Scope;
|
|
setLevel(Scope->getLevel() + 1);
|
|
}
|
|
void LVObject::setParent(LVSymbol *Symbol) {
|
|
Parent.Symbol = Symbol;
|
|
setLevel(Symbol->getLevel() + 1);
|
|
}
|
|
|
|
void LVObject::markBranchAsMissing() {
|
|
// Mark the current object as 'missing'; then traverse the parents chain
|
|
// marking them as 'special missing' to indicate a missing branch. They
|
|
// can not be marked as missing, because will generate incorrect reports.
|
|
LVObject *Parent = this;
|
|
Parent->setIsMissing();
|
|
while (Parent) {
|
|
Parent->setIsMissingLink();
|
|
Parent = Parent->getParent();
|
|
}
|
|
}
|
|
|
|
Error LVObject::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
|
|
bool Full) const {
|
|
print(OS, Full);
|
|
return Error::success();
|
|
}
|
|
|
|
void LVObject::printAttributes(raw_ostream &OS, bool Full, StringRef Name,
|
|
LVObject *Parent, StringRef Value,
|
|
bool UseQuotes, bool PrintRef) const {
|
|
// The current object will be the enclosing scope, use its offset and level.
|
|
LVObject Object(*Parent);
|
|
Object.setLevel(Parent->getLevel() + 1);
|
|
Object.setLineNumber(0);
|
|
Object.printAttributes(OS, Full);
|
|
|
|
// Print the line.
|
|
std::string TheLineNumber(Object.lineNumberAsString());
|
|
std::string TheIndentation(Object.indentAsString());
|
|
OS << format(" %5s %s ", TheLineNumber.c_str(), TheIndentation.c_str());
|
|
|
|
OS << Name;
|
|
if (PrintRef && options().getAttributeOffset())
|
|
OS << hexSquareString(getOffset());
|
|
if (UseQuotes)
|
|
OS << formattedName(Value) << "\n";
|
|
else
|
|
OS << Value << "\n";
|
|
}
|
|
|
|
void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
|
|
#ifndef NDEBUG
|
|
if (options().getInternalID())
|
|
OS << hexSquareString(getID());
|
|
#endif
|
|
if (options().getCompareExecute() &&
|
|
(options().getAttributeAdded() || options().getAttributeMissing()))
|
|
OS << (getIsAdded() ? '+' : getIsMissing() ? '-' : ' ');
|
|
if (options().getAttributeOffset())
|
|
OS << hexSquareString(getOffset());
|
|
if (options().getAttributeLevel()) {
|
|
std::stringstream Stream;
|
|
Stream.str(std::string());
|
|
Stream << "[" << std::setfill('0') << std::setw(3) << getLevel() << "]";
|
|
std::string TheLevel(Stream.str());
|
|
OS << TheLevel;
|
|
}
|
|
if (options().getAttributeGlobal())
|
|
OS << (getIsGlobalReference() ? 'X' : ' ');
|
|
}
|
|
|
|
void LVObject::print(raw_ostream &OS, bool Full) const {
|
|
printFileIndex(OS, Full);
|
|
printAttributes(OS, Full);
|
|
|
|
// Print the line and any discriminator.
|
|
std::stringstream Stream;
|
|
Stream << " " << std::setw(5) << lineNumberAsString() << " "
|
|
<< indentAsString() << " ";
|
|
OS << Stream.str();
|
|
}
|