1e28b9357SCarlos Alberto Enciso //===-- LVObject.cpp ------------------------------------------------------===//
2e28b9357SCarlos Alberto Enciso //
3e28b9357SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e28b9357SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
5e28b9357SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e28b9357SCarlos Alberto Enciso //
7e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
8e28b9357SCarlos Alberto Enciso //
9e28b9357SCarlos Alberto Enciso // This implements the LVObject class.
10e28b9357SCarlos Alberto Enciso //
11e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
12e28b9357SCarlos Alberto Enciso
13e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
14e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
15e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
16e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
17e28b9357SCarlos Alberto Enciso #include <iomanip>
18e28b9357SCarlos Alberto Enciso
19e28b9357SCarlos Alberto Enciso using namespace llvm;
20e28b9357SCarlos Alberto Enciso using namespace llvm::logicalview;
21e28b9357SCarlos Alberto Enciso
22e28b9357SCarlos Alberto Enciso #define DEBUG_TYPE "Object"
23e28b9357SCarlos Alberto Enciso
242c155d37SCarlos Alberto Enciso #ifndef NDEBUG
252c155d37SCarlos Alberto Enciso uint64_t LVObject::GID = 0;
262c155d37SCarlos Alberto Enciso #endif
272c155d37SCarlos Alberto Enciso
typeNone()28e28b9357SCarlos Alberto Enciso StringRef llvm::logicalview::typeNone() { return StringRef(); }
typeVoid()29e28b9357SCarlos Alberto Enciso StringRef llvm::logicalview::typeVoid() { return "void"; }
typeInt()30e28b9357SCarlos Alberto Enciso StringRef llvm::logicalview::typeInt() { return "int"; }
typeUnknown()31e28b9357SCarlos Alberto Enciso StringRef llvm::logicalview::typeUnknown() { return "?"; }
emptyString()32e28b9357SCarlos Alberto Enciso StringRef llvm::logicalview::emptyString() { return StringRef(); }
33e28b9357SCarlos Alberto Enciso
34e28b9357SCarlos Alberto Enciso // Get a string representing the indentation level.
indentAsString(LVLevel Level) const35e28b9357SCarlos Alberto Enciso std::string LVObject::indentAsString(LVLevel Level) const {
36e28b9357SCarlos Alberto Enciso return std::string(Level * 2, ' ');
37e28b9357SCarlos Alberto Enciso }
38e28b9357SCarlos Alberto Enciso
39e28b9357SCarlos Alberto Enciso // Get a string representing the indentation level.
indentAsString() const40e28b9357SCarlos Alberto Enciso std::string LVObject::indentAsString() const {
41e28b9357SCarlos Alberto Enciso return (options().getPrintFormatting() || options().getPrintOffset())
42e28b9357SCarlos Alberto Enciso ? indentAsString(ScopeLevel)
43e28b9357SCarlos Alberto Enciso : "";
44e28b9357SCarlos Alberto Enciso }
45e28b9357SCarlos Alberto Enciso
46e28b9357SCarlos Alberto Enciso // String used as padding for printing objects with no line number.
noLineAsString(bool ShowZero) const47e28b9357SCarlos Alberto Enciso std::string LVObject::noLineAsString(bool ShowZero) const {
48e28b9357SCarlos Alberto Enciso return std::string(8, ' ');
49e28b9357SCarlos Alberto Enciso }
50e28b9357SCarlos Alberto Enciso
51e28b9357SCarlos Alberto Enciso // Get a string representation for the given number and discriminator.
lineAsString(uint32_t LineNumber,LVHalf Discriminator,bool ShowZero) const52e28b9357SCarlos Alberto Enciso std::string LVObject::lineAsString(uint32_t LineNumber, LVHalf Discriminator,
53e28b9357SCarlos Alberto Enciso bool ShowZero) const {
54e28b9357SCarlos Alberto Enciso // The representation is formatted as:
55e28b9357SCarlos Alberto Enciso // a) line number (xxxxx) and discriminator (yy): 'xxxxx,yy'
56e28b9357SCarlos Alberto Enciso // b) Only line number (xxxxx): 'xxxxx '
57e28b9357SCarlos Alberto Enciso // c) No line number: ' '
58e28b9357SCarlos Alberto Enciso std::stringstream Stream;
59e28b9357SCarlos Alberto Enciso if (LineNumber) {
60e28b9357SCarlos Alberto Enciso if (Discriminator && options().getAttributeDiscriminator())
61e28b9357SCarlos Alberto Enciso Stream << std::setw(5) << LineNumber << "," << std::left << std::setw(2)
62e28b9357SCarlos Alberto Enciso << Discriminator;
63e28b9357SCarlos Alberto Enciso else
64e28b9357SCarlos Alberto Enciso Stream << std::setw(5) << LineNumber << " ";
65e28b9357SCarlos Alberto Enciso } else
66e28b9357SCarlos Alberto Enciso Stream << noLineAsString(ShowZero);
67e28b9357SCarlos Alberto Enciso
682c155d37SCarlos Alberto Enciso if (options().getInternalNone())
692c155d37SCarlos Alberto Enciso Stream.str(noLineAsString(ShowZero));
702c155d37SCarlos Alberto Enciso
71e28b9357SCarlos Alberto Enciso return Stream.str();
72e28b9357SCarlos Alberto Enciso }
73e28b9357SCarlos Alberto Enciso
74e28b9357SCarlos Alberto Enciso // Same as 'LineString' but with stripped whitespaces.
lineNumberAsStringStripped(bool ShowZero) const75e28b9357SCarlos Alberto Enciso std::string LVObject::lineNumberAsStringStripped(bool ShowZero) const {
76e28b9357SCarlos Alberto Enciso return std::string(StringRef(lineNumberAsString(ShowZero)).trim());
77e28b9357SCarlos Alberto Enciso }
78e28b9357SCarlos Alberto Enciso
referenceAsString(uint32_t LineNumber,bool Spaces) const79e28b9357SCarlos Alberto Enciso std::string LVObject::referenceAsString(uint32_t LineNumber,
80e28b9357SCarlos Alberto Enciso bool Spaces) const {
81e28b9357SCarlos Alberto Enciso std::string String;
82e28b9357SCarlos Alberto Enciso raw_string_ostream Stream(String);
83e28b9357SCarlos Alberto Enciso if (LineNumber)
84e28b9357SCarlos Alberto Enciso Stream << "@" << LineNumber << (Spaces ? " " : "");
85e28b9357SCarlos Alberto Enciso
86e28b9357SCarlos Alberto Enciso return String;
87e28b9357SCarlos Alberto Enciso }
88e28b9357SCarlos Alberto Enciso
setParent(LVScope * Scope)89e28b9357SCarlos Alberto Enciso void LVObject::setParent(LVScope *Scope) {
90e28b9357SCarlos Alberto Enciso Parent.Scope = Scope;
91e28b9357SCarlos Alberto Enciso setLevel(Scope->getLevel() + 1);
92e28b9357SCarlos Alberto Enciso }
setParent(LVSymbol * Symbol)93e28b9357SCarlos Alberto Enciso void LVObject::setParent(LVSymbol *Symbol) {
94e28b9357SCarlos Alberto Enciso Parent.Symbol = Symbol;
95e28b9357SCarlos Alberto Enciso setLevel(Symbol->getLevel() + 1);
96e28b9357SCarlos Alberto Enciso }
97e28b9357SCarlos Alberto Enciso
markBranchAsMissing()98*e98a4c5aSCarlos Alberto Enciso void LVObject::markBranchAsMissing() {
99*e98a4c5aSCarlos Alberto Enciso // Mark the current object as 'missing'; then traverse the parents chain
100*e98a4c5aSCarlos Alberto Enciso // marking them as 'special missing' to indicate a missing branch. They
101*e98a4c5aSCarlos Alberto Enciso // can not be marked as missing, because will generate incorrect reports.
102*e98a4c5aSCarlos Alberto Enciso LVObject *Parent = this;
103*e98a4c5aSCarlos Alberto Enciso Parent->setIsMissing();
104*e98a4c5aSCarlos Alberto Enciso while (Parent) {
105*e98a4c5aSCarlos Alberto Enciso Parent->setIsMissingLink();
106*e98a4c5aSCarlos Alberto Enciso Parent = Parent->getParent();
107*e98a4c5aSCarlos Alberto Enciso }
108*e98a4c5aSCarlos Alberto Enciso }
109*e98a4c5aSCarlos Alberto Enciso
doPrint(bool Split,bool Match,bool Print,raw_ostream & OS,bool Full) const110e28b9357SCarlos Alberto Enciso Error LVObject::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
111e28b9357SCarlos Alberto Enciso bool Full) const {
112e28b9357SCarlos Alberto Enciso print(OS, Full);
113e28b9357SCarlos Alberto Enciso return Error::success();
114e28b9357SCarlos Alberto Enciso }
115e28b9357SCarlos Alberto Enciso
printAttributes(raw_ostream & OS,bool Full,StringRef Name,LVObject * Parent,StringRef Value,bool UseQuotes,bool PrintRef) const116e28b9357SCarlos Alberto Enciso void LVObject::printAttributes(raw_ostream &OS, bool Full, StringRef Name,
117e28b9357SCarlos Alberto Enciso LVObject *Parent, StringRef Value,
118e28b9357SCarlos Alberto Enciso bool UseQuotes, bool PrintRef) const {
119e28b9357SCarlos Alberto Enciso // The current object will be the enclosing scope, use its offset and level.
120e28b9357SCarlos Alberto Enciso LVObject Object(*Parent);
121e28b9357SCarlos Alberto Enciso Object.setLevel(Parent->getLevel() + 1);
122e28b9357SCarlos Alberto Enciso Object.setLineNumber(0);
123e28b9357SCarlos Alberto Enciso Object.printAttributes(OS, Full);
124e28b9357SCarlos Alberto Enciso
125e28b9357SCarlos Alberto Enciso // Print the line.
126e28b9357SCarlos Alberto Enciso std::string TheLineNumber(Object.lineNumberAsString());
127e28b9357SCarlos Alberto Enciso std::string TheIndentation(Object.indentAsString());
128e28b9357SCarlos Alberto Enciso OS << format(" %5s %s ", TheLineNumber.c_str(), TheIndentation.c_str());
129e28b9357SCarlos Alberto Enciso
130e28b9357SCarlos Alberto Enciso OS << Name;
131e28b9357SCarlos Alberto Enciso if (PrintRef && options().getAttributeOffset())
132e28b9357SCarlos Alberto Enciso OS << hexSquareString(getOffset());
133e28b9357SCarlos Alberto Enciso if (UseQuotes)
134e28b9357SCarlos Alberto Enciso OS << formattedName(Value) << "\n";
135e28b9357SCarlos Alberto Enciso else
136e28b9357SCarlos Alberto Enciso OS << Value << "\n";
137e28b9357SCarlos Alberto Enciso }
138e28b9357SCarlos Alberto Enciso
printAttributes(raw_ostream & OS,bool Full) const139e28b9357SCarlos Alberto Enciso void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
1402c155d37SCarlos Alberto Enciso #ifndef NDEBUG
1412c155d37SCarlos Alberto Enciso if (options().getInternalID())
1422c155d37SCarlos Alberto Enciso OS << hexSquareString(getID());
1432c155d37SCarlos Alberto Enciso #endif
144*e98a4c5aSCarlos Alberto Enciso if (options().getCompareExecute() &&
145*e98a4c5aSCarlos Alberto Enciso (options().getAttributeAdded() || options().getAttributeMissing()))
146*e98a4c5aSCarlos Alberto Enciso OS << (getIsAdded() ? '+' : getIsMissing() ? '-' : ' ');
147e28b9357SCarlos Alberto Enciso if (options().getAttributeOffset())
148e28b9357SCarlos Alberto Enciso OS << hexSquareString(getOffset());
149e28b9357SCarlos Alberto Enciso if (options().getAttributeLevel()) {
150e28b9357SCarlos Alberto Enciso std::stringstream Stream;
151e28b9357SCarlos Alberto Enciso Stream.str(std::string());
152e28b9357SCarlos Alberto Enciso Stream << "[" << std::setfill('0') << std::setw(3) << getLevel() << "]";
153e28b9357SCarlos Alberto Enciso std::string TheLevel(Stream.str());
154e28b9357SCarlos Alberto Enciso OS << TheLevel;
155e28b9357SCarlos Alberto Enciso }
156e28b9357SCarlos Alberto Enciso if (options().getAttributeGlobal())
157e28b9357SCarlos Alberto Enciso OS << (getIsGlobalReference() ? 'X' : ' ');
158e28b9357SCarlos Alberto Enciso }
159e28b9357SCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const160e28b9357SCarlos Alberto Enciso void LVObject::print(raw_ostream &OS, bool Full) const {
161e28b9357SCarlos Alberto Enciso printFileIndex(OS, Full);
162e28b9357SCarlos Alberto Enciso printAttributes(OS, Full);
163e28b9357SCarlos Alberto Enciso
164e28b9357SCarlos Alberto Enciso // Print the line and any discriminator.
165e28b9357SCarlos Alberto Enciso std::stringstream Stream;
166e28b9357SCarlos Alberto Enciso Stream << " " << std::setw(5) << lineNumberAsString() << " "
167e28b9357SCarlos Alberto Enciso << indentAsString() << " ";
168e28b9357SCarlos Alberto Enciso OS << Stream.str();
169e28b9357SCarlos Alberto Enciso }
170