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