brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 4c8e096 Raw
213 lines · cpp
1//===- PrettyClassLayoutGraphicalDumper.h -----------------------*- C++ -*-===//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#include "PrettyClassLayoutGraphicalDumper.h"10 11#include "PrettyClassDefinitionDumper.h"12#include "PrettyEnumDumper.h"13#include "PrettyFunctionDumper.h"14#include "PrettyTypedefDumper.h"15#include "PrettyVariableDumper.h"16#include "llvm-pdbutil.h"17 18#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"19#include "llvm/DebugInfo/PDB/PDBSymbolData.h"20#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"21#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"22#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"23#include "llvm/DebugInfo/PDB/UDTLayout.h"24#include "llvm/Support/Format.h"25 26using namespace llvm;27using namespace llvm::pdb;28 29PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(30    LinePrinter &P, uint32_t RecurseLevel, uint32_t InitialOffset)31    : PDBSymDumper(true), Printer(P), RecursionLevel(RecurseLevel),32      ClassOffsetZero(InitialOffset), CurrentAbsoluteOffset(InitialOffset) {}33 34bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {35 36  if (RecursionLevel == 1 &&37      opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::All) {38    for (const auto &Other : Layout.other_items())39      Other->dump(*this);40    for (const auto &Func : Layout.funcs())41      Func->dump(*this);42  }43 44  const BitVector &UseMap = Layout.usedBytes();45  int NextPaddingByte = UseMap.find_first_unset();46 47  for (const auto &Item : Layout.layout_items()) {48    // Calculate the absolute offset of the first byte of the next field.49    uint32_t RelativeOffset = Item->getOffsetInParent();50    CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;51 52    // This might be an empty base, in which case it could extend outside the53    // bounds of the parent class.54    if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {55      // If there is any remaining padding in this class, and the offset of the56      // new item is after the padding, then we must have just jumped over some57      // padding.  Print a padding row and then look for where the next block58      // of padding begins.59      if ((NextPaddingByte >= 0) &&60          (RelativeOffset > uint32_t(NextPaddingByte))) {61        printPaddingRow(RelativeOffset - NextPaddingByte);62        NextPaddingByte = UseMap.find_next_unset(RelativeOffset);63      }64    }65 66    CurrentItem = Item;67    if (Item->isVBPtr()) {68      VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);69 70      VariableDumper VarDumper(Printer);71      VarDumper.startVbptr(CurrentAbsoluteOffset, Layout.getSize());72    } else {73      if (auto Sym = Item->getSymbol())74        Sym->dump(*this);75    }76 77    if (Item->getLayoutSize() > 0) {78      uint32_t Prev = RelativeOffset + Item->getLayoutSize() - 1;79      if (Prev < UseMap.size())80        NextPaddingByte = UseMap.find_next_unset(Prev);81    }82  }83 84  auto TailPadding = Layout.tailPadding();85  if (TailPadding > 0) {86    if (TailPadding != 1 || Layout.getSize() != 1) {87      Printer.NewLine();88      WithColor(Printer, PDB_ColorItem::Padding).get()89          << "<padding> (" << TailPadding << " bytes)";90      DumpedAnything = true;91    }92  }93 94  return DumpedAnything;95}96 97void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {98  if (Amount == 0)99    return;100 101  Printer.NewLine();102  WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount103                                                   << " bytes)";104  DumpedAnything = true;105}106 107void PrettyClassLayoutGraphicalDumper::dump(108    const PDBSymbolTypeBaseClass &Symbol) {109  assert(CurrentItem != nullptr);110 111  Printer.NewLine();112  BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);113 114  std::string Label = "base";115  if (Layout.isVirtualBase()) {116    Label.insert(Label.begin(), 'v');117    if (Layout.getBase().isIndirectVirtualBaseClass())118      Label.insert(Label.begin(), 'i');119  }120  Printer << Label << " ";121 122  uint32_t Size = Layout.isEmptyBase() ? 1 : Layout.getLayoutSize();123 124  WithColor(Printer, PDB_ColorItem::Offset).get()125      << "+" << format_hex(CurrentAbsoluteOffset, 4) << " [sizeof=" << Size126      << "] ";127 128  WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();129 130  if (shouldRecurse()) {131    Printer.Indent();132    uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();133    PrettyClassLayoutGraphicalDumper BaseDumper(Printer, RecursionLevel + 1,134                                                ChildOffsetZero);135    DumpedAnything |= BaseDumper.start(Layout);136    Printer.Unindent();137  }138 139  DumpedAnything = true;140}141 142bool PrettyClassLayoutGraphicalDumper::shouldRecurse() const {143  uint32_t Limit = opts::pretty::ClassRecursionDepth;144  if (Limit == 0)145    return true;146  return RecursionLevel < Limit;147}148 149void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {150  VariableDumper VarDumper(Printer);151  VarDumper.start(Symbol, ClassOffsetZero);152 153  if (CurrentItem != nullptr) {154    DataMemberLayoutItem &Layout =155        static_cast<DataMemberLayoutItem &>(*CurrentItem);156 157    if (Layout.hasUDTLayout() && shouldRecurse()) {158      uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();159      Printer.Indent();160      PrettyClassLayoutGraphicalDumper TypeDumper(Printer, RecursionLevel + 1,161                                                  ChildOffsetZero);162      TypeDumper.start(Layout.getUDTLayout());163      Printer.Unindent();164    }165  }166 167  DumpedAnything = true;168}169 170void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {171  assert(CurrentItem != nullptr);172 173  VariableDumper VarDumper(Printer);174  VarDumper.start(Symbol, ClassOffsetZero);175 176  DumpedAnything = true;177}178 179void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {180  DumpedAnything = true;181  Printer.NewLine();182  EnumDumper Dumper(Printer);183  Dumper.start(Symbol);184}185 186void PrettyClassLayoutGraphicalDumper::dump(187    const PDBSymbolTypeTypedef &Symbol) {188  DumpedAnything = true;189  Printer.NewLine();190  TypedefDumper Dumper(Printer);191  Dumper.start(Symbol);192}193 194void PrettyClassLayoutGraphicalDumper::dump(195    const PDBSymbolTypeBuiltin &Symbol) {}196 197void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}198 199void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {200  if (Printer.IsSymbolExcluded(Symbol.getName()))201    return;202  if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)203    return;204  if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&205      !Symbol.isIntroVirtualFunction())206    return;207 208  DumpedAnything = true;209  Printer.NewLine();210  FunctionDumper Dumper(Printer);211  Dumper.start(Symbol, FunctionDumper::PointerType::None);212}213