xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- LVObject.cpp ------------------------------------------------------===//
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 implements the LVObject class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
16 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
17 #include <iomanip>
18 
19 using namespace llvm;
20 using namespace llvm::logicalview;
21 
22 #define DEBUG_TYPE "Object"
23 
24 uint32_t LVObject::GID = 0;
25 
typeNone()26 StringRef llvm::logicalview::typeNone() { return StringRef(); }
typeVoid()27 StringRef llvm::logicalview::typeVoid() { return "void"; }
typeInt()28 StringRef llvm::logicalview::typeInt() { return "int"; }
typeUnknown()29 StringRef llvm::logicalview::typeUnknown() { return "?"; }
emptyString()30 StringRef llvm::logicalview::emptyString() { return StringRef(); }
31 
32 // Get a string representing the indentation level.
indentAsString(LVLevel Level) const33 std::string LVObject::indentAsString(LVLevel Level) const {
34   return std::string(Level * 2, ' ');
35 }
36 
37 // Get a string representing the indentation level.
indentAsString() const38 std::string LVObject::indentAsString() const {
39   return (options().getPrintFormatting() || options().getPrintOffset())
40              ? indentAsString(ScopeLevel)
41              : "";
42 }
43 
44 // String used as padding for printing objects with no line number.
noLineAsString(bool ShowZero) const45 std::string LVObject::noLineAsString(bool ShowZero) const {
46   return std::string(8, ' ');
47 }
48 
49 // Get a string representation for the given number and discriminator.
lineAsString(uint32_t LineNumber,LVHalf Discriminator,bool ShowZero) const50 std::string LVObject::lineAsString(uint32_t LineNumber, LVHalf Discriminator,
51                                    bool ShowZero) const {
52   // The representation is formatted as:
53   // a) line number (xxxxx) and discriminator (yy): 'xxxxx,yy'
54   // b) Only line number (xxxxx):                   'xxxxx   '
55   // c) No line number:                             '        '
56   std::stringstream Stream;
57   if (LineNumber) {
58     if (Discriminator && options().getAttributeDiscriminator())
59       Stream << std::setw(5) << LineNumber << "," << std::left << std::setw(2)
60              << Discriminator;
61     else
62       Stream << std::setw(5) << LineNumber << "   ";
63   } else
64     Stream << noLineAsString(ShowZero);
65 
66   if (options().getInternalNone())
67     Stream.str(noLineAsString(ShowZero));
68 
69   return Stream.str();
70 }
71 
72 // Same as 'LineString' but with stripped whitespaces.
lineNumberAsStringStripped(bool ShowZero) const73 std::string LVObject::lineNumberAsStringStripped(bool ShowZero) const {
74   return std::string(StringRef(lineNumberAsString(ShowZero)).trim());
75 }
76 
referenceAsString(uint32_t LineNumber,bool Spaces) const77 std::string LVObject::referenceAsString(uint32_t LineNumber,
78                                         bool Spaces) const {
79   std::string String;
80   raw_string_ostream Stream(String);
81   if (LineNumber)
82     Stream << "@" << LineNumber << (Spaces ? " " : "");
83 
84   return String;
85 }
86 
setParent(LVScope * Scope)87 void LVObject::setParent(LVScope *Scope) {
88   Parent.Scope = Scope;
89   setLevel(Scope->getLevel() + 1);
90 }
setParent(LVSymbol * Symbol)91 void LVObject::setParent(LVSymbol *Symbol) {
92   Parent.Symbol = Symbol;
93   setLevel(Symbol->getLevel() + 1);
94 }
95 
markBranchAsMissing()96 void LVObject::markBranchAsMissing() {
97   // Mark the current object as 'missing'; then traverse the parents chain
98   // marking them as 'special missing' to indicate a missing branch. They
99   // can not be marked as missing, because will generate incorrect reports.
100   LVObject *Parent = this;
101   Parent->setIsMissing();
102   while (Parent) {
103     Parent->setIsMissingLink();
104     Parent = Parent->getParent();
105   }
106 }
107 
doPrint(bool Split,bool Match,bool Print,raw_ostream & OS,bool Full) const108 Error LVObject::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
109                         bool Full) const {
110   print(OS, Full);
111   return Error::success();
112 }
113 
printAttributes(raw_ostream & OS,bool Full,StringRef Name,LVObject * Parent,StringRef Value,bool UseQuotes,bool PrintRef) const114 void LVObject::printAttributes(raw_ostream &OS, bool Full, StringRef Name,
115                                LVObject *Parent, StringRef Value,
116                                bool UseQuotes, bool PrintRef) const {
117   // The current object will be the enclosing scope, use its offset and level.
118   LVObject Object(*Parent);
119   Object.setLevel(Parent->getLevel() + 1);
120   Object.setLineNumber(0);
121   Object.printAttributes(OS, Full);
122 
123   // Print the line.
124   std::string TheLineNumber(Object.lineNumberAsString());
125   std::string TheIndentation(Object.indentAsString());
126   OS << format(" %5s %s ", TheLineNumber.c_str(), TheIndentation.c_str());
127 
128   OS << Name;
129   if (PrintRef && options().getAttributeOffset())
130     OS << hexSquareString(getOffset());
131   if (UseQuotes)
132     OS << formattedName(Value) << "\n";
133   else
134     OS << Value << "\n";
135 }
136 
printAttributes(raw_ostream & OS,bool Full) const137 void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
138   if (options().getInternalID())
139     OS << hexSquareString(getID());
140   if (options().getCompareExecute() &&
141       (options().getAttributeAdded() || options().getAttributeMissing()))
142     OS << (getIsAdded() ? '+' : getIsMissing() ? '-' : ' ');
143   if (options().getAttributeOffset())
144     OS << hexSquareString(getOffset());
145   if (options().getAttributeLevel()) {
146     std::stringstream Stream;
147     Stream.str(std::string());
148     Stream << "[" << std::setfill('0') << std::setw(3) << getLevel() << "]";
149     std::string TheLevel(Stream.str());
150     OS << TheLevel;
151   }
152   if (options().getAttributeGlobal())
153     OS << (getIsGlobalReference() ? 'X' : ' ');
154 }
155 
print(raw_ostream & OS,bool Full) const156 void LVObject::print(raw_ostream &OS, bool Full) const {
157   printFileIndex(OS, Full);
158   printAttributes(OS, Full);
159 
160   // Print the line and any discriminator.
161   std::stringstream Stream;
162   Stream << " " << std::setw(5) << lineNumberAsString() << " "
163          << indentAsString() << " ";
164   OS << Stream.str();
165 }
166