166 lines · cpp
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-exception6//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 19using namespace llvm;20using namespace llvm::logicalview;21 22#define DEBUG_TYPE "Object"23 24uint32_t LVObject::GID = 0;25 26StringRef llvm::logicalview::typeNone() { return StringRef(); }27StringRef llvm::logicalview::typeVoid() { return "void"; }28StringRef llvm::logicalview::typeInt() { return "int"; }29StringRef llvm::logicalview::typeUnknown() { return "?"; }30StringRef llvm::logicalview::emptyString() { return StringRef(); }31 32// Get a string representing the indentation level.33std::string LVObject::indentAsString(LVLevel Level) const {34 return std::string(Level * 2, ' ');35}36 37// Get a string representing the indentation level.38std::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.45std::string LVObject::noLineAsString(bool ShowZero) const {46 return std::string(8, ' ');47}48 49// Get a string representation for the given number and discriminator.50std::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 else62 Stream << std::setw(5) << LineNumber << " ";63 } else64 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.73std::string LVObject::lineNumberAsStringStripped(bool ShowZero) const {74 return std::string(StringRef(lineNumberAsString(ShowZero)).trim());75}76 77std::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 87void LVObject::setParent(LVScope *Scope) {88 Parent.Scope = Scope;89 setLevel(Scope->getLevel() + 1);90}91void LVObject::setParent(LVSymbol *Symbol) {92 Parent.Symbol = Symbol;93 setLevel(Symbol->getLevel() + 1);94}95 96void LVObject::markBranchAsMissing() {97 // Mark the current object as 'missing'; then traverse the parents chain98 // marking them as 'special missing' to indicate a missing branch. They99 // 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 108Error 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 114void 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 else134 OS << Value << "\n";135}136 137void 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 156void 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