1 | //===- PrettyClassDefinitionDumper.cpp --------------------------*- 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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "PrettyClassDefinitionDumper.h" |
10 | |
11 | #include "PrettyClassLayoutGraphicalDumper.h" |
12 | #include "llvm-pdbutil.h" |
13 | |
14 | #include "llvm/ADT/APFloat.h" |
15 | #include "llvm/ADT/SmallString.h" |
16 | #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" |
17 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" |
18 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.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 | |
27 | ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P) |
28 | : PDBSymDumper(true), Printer(P) {} |
29 | |
30 | void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) { |
31 | assert(opts::pretty::ClassFormat != |
32 | opts::pretty::ClassDefinitionFormat::None); |
33 | |
34 | ClassLayout Layout(Class); |
35 | start(Class: Layout); |
36 | } |
37 | |
38 | void ClassDefinitionDumper::start(const ClassLayout &Layout) { |
39 | prettyPrintClassIntro(Class: Layout); |
40 | |
41 | PrettyClassLayoutGraphicalDumper Dumper(Printer, 1, 0); |
42 | DumpedAnything |= Dumper.start(Layout); |
43 | |
44 | prettyPrintClassOutro(Class: Layout); |
45 | } |
46 | |
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 | if (Layout.getClass().isConstType()) |
55 | WithColor(Printer, PDB_ColorItem::Keyword).get() << "const " ; |
56 | if (Layout.getClass().isVolatileType()) |
57 | WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile " ; |
58 | if (Layout.getClass().isUnalignedType()) |
59 | WithColor(Printer, PDB_ColorItem::Keyword).get() << "unaligned " ; |
60 | |
61 | WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " " ; |
62 | WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName(); |
63 | WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size |
64 | << "]" ; |
65 | uint32_t BaseCount = Layout.bases().size(); |
66 | if (BaseCount > 0) { |
67 | Printer.Indent(); |
68 | char NextSeparator = ':'; |
69 | for (auto *BC : Layout.bases()) { |
70 | const auto &Base = BC->getBase(); |
71 | if (Base.isIndirectVirtualBaseClass()) |
72 | continue; |
73 | |
74 | Printer.NewLine(); |
75 | Printer << NextSeparator << " " ; |
76 | WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess(); |
77 | if (BC->isVirtualBase()) |
78 | WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual" ; |
79 | |
80 | WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName(); |
81 | NextSeparator = ','; |
82 | } |
83 | |
84 | Printer.Unindent(); |
85 | } |
86 | |
87 | Printer << " {" ; |
88 | Printer.Indent(); |
89 | } |
90 | |
91 | void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) { |
92 | Printer.Unindent(); |
93 | if (DumpedAnything) |
94 | Printer.NewLine(); |
95 | Printer << "}" ; |
96 | Printer.NewLine(); |
97 | if (Layout.deepPaddingSize() > 0) { |
98 | APFloat Pct(100.0 * (double)Layout.deepPaddingSize() / |
99 | (double)Layout.getSize()); |
100 | SmallString<8> PctStr; |
101 | Pct.toString(Str&: PctStr, FormatPrecision: 4); |
102 | WithColor(Printer, PDB_ColorItem::Padding).get() |
103 | << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr |
104 | << "% of class size)" ; |
105 | Printer.NewLine(); |
106 | APFloat Pct2(100.0 * (double)Layout.immediatePadding() / |
107 | (double)Layout.getSize()); |
108 | PctStr.clear(); |
109 | Pct2.toString(Str&: PctStr, FormatPrecision: 4); |
110 | WithColor(Printer, PDB_ColorItem::Padding).get() |
111 | << "Immediate padding " << Layout.immediatePadding() << " bytes (" |
112 | << PctStr << "% of class size)" ; |
113 | Printer.NewLine(); |
114 | } |
115 | } |
116 | |