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