xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp (revision e28b9357b14c84f1b48646b64eed01fb19dad250)
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 StringRef llvm::logicalview::typeNone() { return StringRef(); }
25 StringRef llvm::logicalview::typeVoid() { return "void"; }
26 StringRef llvm::logicalview::typeInt() { return "int"; }
27 StringRef llvm::logicalview::typeUnknown() { return "?"; }
28 StringRef llvm::logicalview::emptyString() { return StringRef(); }
29 
30 // Get a string representing the indentation level.
31 std::string LVObject::indentAsString(LVLevel Level) const {
32   return std::string(Level * 2, ' ');
33 }
34 
35 // Get a string representing the indentation level.
36 std::string LVObject::indentAsString() const {
37   return (options().getPrintFormatting() || options().getPrintOffset())
38              ? indentAsString(ScopeLevel)
39              : "";
40 }
41 
42 // String used as padding for printing objects with no line number.
43 std::string LVObject::noLineAsString(bool ShowZero) const {
44   return std::string(8, ' ');
45 }
46 
47 // Get a string representation for the given number and discriminator.
48 std::string LVObject::lineAsString(uint32_t LineNumber, LVHalf Discriminator,
49                                    bool ShowZero) const {
50   // The representation is formatted as:
51   // a) line number (xxxxx) and discriminator (yy): 'xxxxx,yy'
52   // b) Only line number (xxxxx):                   'xxxxx   '
53   // c) No line number:                             '        '
54   std::stringstream Stream;
55   if (LineNumber) {
56     if (Discriminator && options().getAttributeDiscriminator())
57       Stream << std::setw(5) << LineNumber << "," << std::left << std::setw(2)
58              << Discriminator;
59     else
60       Stream << std::setw(5) << LineNumber << "   ";
61   } else
62     Stream << noLineAsString(ShowZero);
63 
64   return Stream.str();
65 }
66 
67 // Same as 'LineString' but with stripped whitespaces.
68 std::string LVObject::lineNumberAsStringStripped(bool ShowZero) const {
69   return std::string(StringRef(lineNumberAsString(ShowZero)).trim());
70 }
71 
72 std::string LVObject::referenceAsString(uint32_t LineNumber,
73                                         bool Spaces) const {
74   std::string String;
75   raw_string_ostream Stream(String);
76   if (LineNumber)
77     Stream << "@" << LineNumber << (Spaces ? " " : "");
78 
79   return String;
80 }
81 
82 void LVObject::setParent(LVScope *Scope) {
83   Parent.Scope = Scope;
84   setLevel(Scope->getLevel() + 1);
85 }
86 void LVObject::setParent(LVSymbol *Symbol) {
87   Parent.Symbol = Symbol;
88   setLevel(Symbol->getLevel() + 1);
89 }
90 
91 Error LVObject::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
92                         bool Full) const {
93   print(OS, Full);
94   return Error::success();
95 }
96 
97 void LVObject::printAttributes(raw_ostream &OS, bool Full, StringRef Name,
98                                LVObject *Parent, StringRef Value,
99                                bool UseQuotes, bool PrintRef) const {
100   // The current object will be the enclosing scope, use its offset and level.
101   LVObject Object(*Parent);
102   Object.setLevel(Parent->getLevel() + 1);
103   Object.setLineNumber(0);
104   Object.printAttributes(OS, Full);
105 
106   // Print the line.
107   std::string TheLineNumber(Object.lineNumberAsString());
108   std::string TheIndentation(Object.indentAsString());
109   OS << format(" %5s %s ", TheLineNumber.c_str(), TheIndentation.c_str());
110 
111   OS << Name;
112   if (PrintRef && options().getAttributeOffset())
113     OS << hexSquareString(getOffset());
114   if (UseQuotes)
115     OS << formattedName(Value) << "\n";
116   else
117     OS << Value << "\n";
118 }
119 
120 void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
121   if (options().getAttributeOffset())
122     OS << hexSquareString(getOffset());
123   if (options().getAttributeLevel()) {
124     std::stringstream Stream;
125     Stream.str(std::string());
126     Stream << "[" << std::setfill('0') << std::setw(3) << getLevel() << "]";
127     std::string TheLevel(Stream.str());
128     OS << TheLevel;
129   }
130   if (options().getAttributeGlobal())
131     OS << (getIsGlobalReference() ? 'X' : ' ');
132 }
133 
134 void LVObject::print(raw_ostream &OS, bool Full) const {
135   printFileIndex(OS, Full);
136   printAttributes(OS, Full);
137 
138   // Print the line and any discriminator.
139   std::stringstream Stream;
140   Stream << " " << std::setw(5) << lineNumberAsString() << " "
141          << indentAsString() << " ";
142   OS << Stream.str();
143 }
144