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