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