summaryrefslogtreecommitdiff
path: root/tools/llvm-pdbutil/PrettyClassDefinitionDumper.cpp
blob: 651cb8b7649e40459f2edb12416ede722c30a497 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//===- PrettyClassDefinitionDumper.cpp --------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "PrettyClassDefinitionDumper.h"

#include "LinePrinter.h"
#include "PrettyClassLayoutGraphicalDumper.h"
#include "llvm-pdbutil.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/UDTLayout.h"

#include "llvm/Support/Format.h"

using namespace llvm;
using namespace llvm::pdb;

ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
    : PDBSymDumper(true), Printer(P) {}

void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
  assert(opts::pretty::ClassFormat !=
         opts::pretty::ClassDefinitionFormat::None);

  ClassLayout Layout(Class);
  start(Layout);
}

void ClassDefinitionDumper::start(const ClassLayout &Layout) {
  prettyPrintClassIntro(Layout);

  PrettyClassLayoutGraphicalDumper Dumper(Printer, 1, 0);
  DumpedAnything |= Dumper.start(Layout);

  prettyPrintClassOutro(Layout);
}

void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
  DumpedAnything = false;
  Printer.NewLine();

  uint32_t Size = Layout.getSize();
  const PDBSymbolTypeUDT &Class = Layout.getClass();

  WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
  WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
  WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
                                                   << "]";
  uint32_t BaseCount = Layout.bases().size();
  if (BaseCount > 0) {
    Printer.Indent();
    char NextSeparator = ':';
    for (auto BC : Layout.bases()) {
      const auto &Base = BC->getBase();
      if (Base.isIndirectVirtualBaseClass())
        continue;

      Printer.NewLine();
      Printer << NextSeparator << " ";
      WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
      if (BC->isVirtualBase())
        WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";

      WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
      NextSeparator = ',';
    }

    Printer.Unindent();
  }

  Printer << " {";
  Printer.Indent();
}

void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) {
  Printer.Unindent();
  if (DumpedAnything)
    Printer.NewLine();
  Printer << "}";
  Printer.NewLine();
  if (Layout.deepPaddingSize() > 0) {
    APFloat Pct(100.0 * (double)Layout.deepPaddingSize() /
                (double)Layout.getSize());
    SmallString<8> PctStr;
    Pct.toString(PctStr, 4);
    WithColor(Printer, PDB_ColorItem::Padding).get()
        << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
        << "% of class size)";
    Printer.NewLine();
    APFloat Pct2(100.0 * (double)Layout.immediatePadding() /
                 (double)Layout.getSize());
    PctStr.clear();
    Pct2.toString(PctStr, 4);
    WithColor(Printer, PDB_ColorItem::Padding).get()
        << "Immediate padding " << Layout.immediatePadding() << " bytes ("
        << PctStr << "% of class size)";
    Printer.NewLine();
  }
}