blob: 2e1e54e4db1af056c6b055cf66256c27349ee16b [file] [log] [blame]
Zachary Turnera9054dd2017-01-11 00:35:43 +00001//===- PrettyClassDefinitionDumper.cpp --------------------------*- C++ -*-===//
Zachary Turner29c69102015-02-23 05:58:34 +00002//
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
Zachary Turnera9054dd2017-01-11 00:35:43 +000010#include "PrettyClassDefinitionDumper.h"
11
Zachary Turner2d11c202015-02-27 09:15:59 +000012#include "LinePrinter.h"
Zachary Turnera9054dd2017-01-11 00:35:43 +000013#include "PrettyEnumDumper.h"
14#include "PrettyFunctionDumper.h"
15#include "PrettyTypedefDumper.h"
16#include "PrettyVariableDumper.h"
Zachary Turner29c69102015-02-23 05:58:34 +000017#include "llvm-pdbdump.h"
Zachary Turner29c69102015-02-23 05:58:34 +000018
Zachary Turner0c990bbe2017-04-10 19:33:29 +000019#include "llvm/ADT/APFloat.h"
20#include "llvm/ADT/SmallString.h"
Zachary Turner29c69102015-02-23 05:58:34 +000021#include "llvm/DebugInfo/PDB/IPDBSession.h"
22#include "llvm/DebugInfo/PDB/PDBExtras.h"
23#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
24#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
25#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
26#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
27#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
28#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
29#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
30#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
Zachary Turnerc883a8c2017-04-12 23:18:21 +000031#include "llvm/DebugInfo/PDB/UDTLayout.h"
32
Zachary Turner29c69102015-02-23 05:58:34 +000033#include "llvm/Support/Format.h"
34
35using namespace llvm;
Zachary Turnerec28fc32016-05-04 20:32:13 +000036using namespace llvm::pdb;
Zachary Turner29c69102015-02-23 05:58:34 +000037
Zachary Turner2d11c202015-02-27 09:15:59 +000038ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
39 : PDBSymDumper(true), Printer(P) {}
Zachary Turner29c69102015-02-23 05:58:34 +000040
Zachary Turnerb52d08d2015-03-01 06:51:29 +000041void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
Zachary Turner10169b62017-04-06 23:43:39 +000042 assert(opts::pretty::ClassFormat !=
43 opts::pretty::ClassDefinitionFormat::None);
44
Zachary Turner0c990bbe2017-04-10 19:33:29 +000045 uint32_t Size = Class.getLength();
Zachary Turner0c990bbe2017-04-10 19:33:29 +000046
Zachary Turnerc883a8c2017-04-12 23:18:21 +000047 ClassLayout Layout(Class.clone());
48
49 if (opts::pretty::OnlyPaddingClasses && (Layout.shallowPaddingSize() == 0))
Zachary Turner0c990bbe2017-04-10 19:33:29 +000050 return;
51
52 Printer.NewLine();
Zachary Turner0c990bbe2017-04-10 19:33:29 +000053
Zachary Turner7797c722015-03-02 04:39:56 +000054 WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
Zachary Turner2d11c202015-02-27 09:15:59 +000055 WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
Zachary Turnerc883a8c2017-04-12 23:18:21 +000056 WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
57 << "]";
Zachary Turner7797c722015-03-02 04:39:56 +000058
59 auto Bases = Class.findAllChildren<PDBSymbolTypeBaseClass>();
60 if (Bases->getChildCount() > 0) {
61 Printer.Indent();
62 Printer.NewLine();
63 Printer << ":";
64 uint32_t BaseIndex = 0;
65 while (auto Base = Bases->getNext()) {
66 Printer << " ";
67 WithColor(Printer, PDB_ColorItem::Keyword).get() << Base->getAccess();
68 if (Base->isVirtualBaseClass())
69 WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
70 WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base->getName();
71 if (++BaseIndex < Bases->getChildCount()) {
72 Printer.NewLine();
73 Printer << ",";
74 }
75 }
76 Printer.Unindent();
77 }
78
Zachary Turner2d11c202015-02-27 09:15:59 +000079 Printer << " {";
Zachary Turner10169b62017-04-06 23:43:39 +000080 Printer.Indent();
Zachary Turner29c69102015-02-23 05:58:34 +000081
Zachary Turnerc883a8c2017-04-12 23:18:21 +000082 // Dump non-layout items first, but only if we're not in layout-only mode.
83 if (opts::pretty::ClassFormat !=
84 opts::pretty::ClassDefinitionFormat::Layout) {
85 for (auto &Other : Layout.other_items())
86 Other->dump(*this);
Zachary Turner29c69102015-02-23 05:58:34 +000087 }
88
Zachary Turnerc883a8c2017-04-12 23:18:21 +000089 const BitVector &UseMap = Layout.usedBytes();
90 int NextUnusedByte = Layout.usedBytes().find_first_unset();
91 // Next dump items which affect class layout.
92 for (auto &LayoutItem : Layout.layout_items()) {
93 if (NextUnusedByte >= 0) {
94 // If there are padding bytes remaining, see if this field is the first to
95 // cross a padding boundary, and print a padding field indicator if so.
96 int Off = LayoutItem->getOffsetInParent();
97 if (Off > NextUnusedByte) {
98 uint32_t Amount = Off - NextUnusedByte;
99 Printer.NewLine();
100 WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> ("
101 << Amount << " bytes)";
102 assert(UseMap.find_next(NextUnusedByte) == Off);
103 NextUnusedByte = UseMap.find_next_unset(Off);
104 }
105 }
106 LayoutItem->getSymbol().dump(*this);
107 }
108
109 if (NextUnusedByte >= 0 && Layout.getClassSize() > 1) {
110 uint32_t Amount = Layout.getClassSize() - NextUnusedByte;
Zachary Turner0c990bbe2017-04-10 19:33:29 +0000111 Printer.NewLine();
112 WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
113 << " bytes)";
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000114 DumpedAnything = true;
Zachary Turner0c990bbe2017-04-10 19:33:29 +0000115 }
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000116
Zachary Turner10169b62017-04-06 23:43:39 +0000117 Printer.Unindent();
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000118 if (DumpedAnything)
Zachary Turner2d11c202015-02-27 09:15:59 +0000119 Printer.NewLine();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000120 Printer << "}";
Zachary Turner0c990bbe2017-04-10 19:33:29 +0000121 Printer.NewLine();
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000122 if (Layout.deepPaddingSize() > 0) {
123 APFloat Pct(100.0 * (double)Layout.deepPaddingSize() / (double)Size);
Zachary Turner0c990bbe2017-04-10 19:33:29 +0000124 SmallString<8> PctStr;
125 Pct.toString(PctStr, 4);
126 WithColor(Printer, PDB_ColorItem::Padding).get()
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000127 << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
Zachary Turner0c990bbe2017-04-10 19:33:29 +0000128 << "% of class size)";
129 Printer.NewLine();
130 }
Zachary Turner29c69102015-02-23 05:58:34 +0000131}
132
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000133void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {}
Zachary Turner29c69102015-02-23 05:58:34 +0000134
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000135void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000136 VariableDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000137 Dumper.start(Symbol);
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000138 DumpedAnything = true;
Zachary Turner29c69102015-02-23 05:58:34 +0000139}
140
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000141void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol) {
Zachary Turnerf5abda22015-03-01 06:49:49 +0000142 if (Printer.IsSymbolExcluded(Symbol.getName()))
143 return;
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000144 if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
145 return;
146 if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&
147 !Symbol.isIntroVirtualFunction())
148 return;
Zachary Turnerf5abda22015-03-01 06:49:49 +0000149
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000150 DumpedAnything = true;
Zachary Turner2d11c202015-02-27 09:15:59 +0000151 Printer.NewLine();
152 FunctionDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000153 Dumper.start(Symbol, FunctionDumper::PointerType::None);
Zachary Turner29c69102015-02-23 05:58:34 +0000154}
155
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000156void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol) {
157 VariableDumper Dumper(Printer);
158 Dumper.start(Symbol);
159 DumpedAnything = true;
160}
Zachary Turner29c69102015-02-23 05:58:34 +0000161
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000162void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
Zachary Turnerf5abda22015-03-01 06:49:49 +0000163 if (Printer.IsTypeExcluded(Symbol.getName()))
164 return;
165
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000166 DumpedAnything = true;
Zachary Turner2d11c202015-02-27 09:15:59 +0000167 Printer.NewLine();
Zachary Turner65323652015-03-04 06:09:53 +0000168 EnumDumper Dumper(Printer);
169 Dumper.start(Symbol);
Zachary Turner29c69102015-02-23 05:58:34 +0000170}
171
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000172void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
Zachary Turnerf5abda22015-03-01 06:49:49 +0000173 if (Printer.IsTypeExcluded(Symbol.getName()))
174 return;
175
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000176 DumpedAnything = true;
Zachary Turner2d11c202015-02-27 09:15:59 +0000177 Printer.NewLine();
178 TypedefDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000179 Dumper.start(Symbol);
Zachary Turner29c69102015-02-23 05:58:34 +0000180}
181
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000182void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol) {}