• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- PrettyClassDefinitionDumper.cpp --------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "PrettyClassDefinitionDumper.h"
11 
12 #include "LinePrinter.h"
13 #include "PrettyClassLayoutGraphicalDumper.h"
14 #include "llvm-pdbutil.h"
15 
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
19 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
20 #include "llvm/DebugInfo/PDB/UDTLayout.h"
21 
22 #include "llvm/Support/Format.h"
23 
24 using namespace llvm;
25 using namespace llvm::pdb;
26 
ClassDefinitionDumper(LinePrinter & P)27 ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
28     : PDBSymDumper(true), Printer(P) {}
29 
start(const PDBSymbolTypeUDT & Class)30 void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
31   assert(opts::pretty::ClassFormat !=
32          opts::pretty::ClassDefinitionFormat::None);
33 
34   ClassLayout Layout(Class);
35   start(Layout);
36 }
37 
start(const ClassLayout & Layout)38 void ClassDefinitionDumper::start(const ClassLayout &Layout) {
39   prettyPrintClassIntro(Layout);
40 
41   PrettyClassLayoutGraphicalDumper Dumper(Printer, 1, 0);
42   DumpedAnything |= Dumper.start(Layout);
43 
44   prettyPrintClassOutro(Layout);
45 }
46 
prettyPrintClassIntro(const ClassLayout & Layout)47 void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
48   DumpedAnything = false;
49   Printer.NewLine();
50 
51   uint32_t Size = Layout.getSize();
52   const PDBSymbolTypeUDT &Class = Layout.getClass();
53 
54   WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
55   WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
56   WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
57                                                    << "]";
58   uint32_t BaseCount = Layout.bases().size();
59   if (BaseCount > 0) {
60     Printer.Indent();
61     char NextSeparator = ':';
62     for (auto BC : Layout.bases()) {
63       const auto &Base = BC->getBase();
64       if (Base.isIndirectVirtualBaseClass())
65         continue;
66 
67       Printer.NewLine();
68       Printer << NextSeparator << " ";
69       WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
70       if (BC->isVirtualBase())
71         WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
72 
73       WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
74       NextSeparator = ',';
75     }
76 
77     Printer.Unindent();
78   }
79 
80   Printer << " {";
81   Printer.Indent();
82 }
83 
prettyPrintClassOutro(const ClassLayout & Layout)84 void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) {
85   Printer.Unindent();
86   if (DumpedAnything)
87     Printer.NewLine();
88   Printer << "}";
89   Printer.NewLine();
90   if (Layout.deepPaddingSize() > 0) {
91     APFloat Pct(100.0 * (double)Layout.deepPaddingSize() /
92                 (double)Layout.getSize());
93     SmallString<8> PctStr;
94     Pct.toString(PctStr, 4);
95     WithColor(Printer, PDB_ColorItem::Padding).get()
96         << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
97         << "% of class size)";
98     Printer.NewLine();
99     APFloat Pct2(100.0 * (double)Layout.immediatePadding() /
100                  (double)Layout.getSize());
101     PctStr.clear();
102     Pct2.toString(PctStr, 4);
103     WithColor(Printer, PDB_ColorItem::Padding).get()
104         << "Immediate padding " << Layout.immediatePadding() << " bytes ("
105         << PctStr << "% of class size)";
106     Printer.NewLine();
107   }
108 }
109