]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
Merge ^/head r317216 through r317280.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / llvm-pdbdump / PrettyClassLayoutGraphicalDumper.cpp
1 //===- PrettyClassLayoutGraphicalDumper.h -----------------------*- 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 "PrettyClassLayoutGraphicalDumper.h"
11
12 #include "LinePrinter.h"
13 #include "PrettyClassDefinitionDumper.h"
14 #include "PrettyVariableDumper.h"
15
16 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
19 #include "llvm/DebugInfo/PDB/UDTLayout.h"
20 #include "llvm/Support/Format.h"
21
22 using namespace llvm;
23 using namespace llvm::pdb;
24
25 PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
26     LinePrinter &P, uint32_t InitialOffset)
27     : PDBSymDumper(true), Printer(P), ClassOffsetZero(InitialOffset),
28       CurrentAbsoluteOffset(InitialOffset) {}
29
30 bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {
31   const BitVector &UseMap = Layout.usedBytes();
32   int NextPaddingByte = UseMap.find_first_unset();
33
34   for (auto &Item : Layout.layout_items()) {
35     // Calculate the absolute offset of the first byte of the next field.
36     uint32_t RelativeOffset = Item->getOffsetInParent();
37     CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;
38
39     // Since there is storage there, it should be set!  However, this might
40     // be an empty base, in which case it could extend outside the bounds of
41     // the parent class.
42     if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {
43       assert(UseMap.test(RelativeOffset));
44
45       // If there is any remaining padding in this class, and the offset of the
46       // new item is after the padding, then we must have just jumped over some
47       // padding.  Print a padding row and then look for where the next block
48       // of padding begins.
49       if ((NextPaddingByte >= 0) &&
50           (RelativeOffset > uint32_t(NextPaddingByte))) {
51         printPaddingRow(RelativeOffset - NextPaddingByte);
52         NextPaddingByte = UseMap.find_next_unset(RelativeOffset);
53       }
54     }
55
56     CurrentItem = Item.get();
57     Item->getSymbol().dump(*this);
58   }
59
60   if (NextPaddingByte >= 0 && Layout.getClassSize() > 1) {
61     uint32_t Amount = Layout.getClassSize() - NextPaddingByte;
62     Printer.NewLine();
63     WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
64                                                      << " bytes)";
65     DumpedAnything = true;
66   }
67
68   return DumpedAnything;
69 }
70
71 void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {
72   if (Amount == 0)
73     return;
74
75   Printer.NewLine();
76   WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
77                                                    << " bytes)";
78   DumpedAnything = true;
79 }
80
81 void PrettyClassLayoutGraphicalDumper::dump(
82     const PDBSymbolTypeBaseClass &Symbol) {
83   assert(CurrentItem != nullptr);
84
85   Printer.NewLine();
86   BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
87
88   std::string Label = Layout.isVirtualBase() ? "vbase" : "base";
89   Printer << Label << " ";
90
91   WithColor(Printer, PDB_ColorItem::Offset).get()
92       << "+" << format_hex(CurrentAbsoluteOffset, 4)
93       << " [sizeof=" << Layout.getSize() << "] ";
94
95   WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
96
97   Printer.Indent();
98   uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
99   PrettyClassLayoutGraphicalDumper BaseDumper(Printer, ChildOffsetZero);
100   BaseDumper.start(Layout);
101   Printer.Unindent();
102
103   DumpedAnything = true;
104 }
105
106 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {
107   assert(CurrentItem != nullptr);
108
109   DataMemberLayoutItem &Layout =
110       static_cast<DataMemberLayoutItem &>(*CurrentItem);
111
112   VariableDumper VarDumper(Printer);
113   VarDumper.start(Symbol, ClassOffsetZero);
114
115   if (Layout.hasUDTLayout()) {
116     Printer.Indent();
117     PrettyClassLayoutGraphicalDumper TypeDumper(Printer, ClassOffsetZero);
118     TypeDumper.start(Layout.getUDTLayout());
119     Printer.Unindent();
120   }
121
122   DumpedAnything = true;
123 }
124
125 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
126   assert(CurrentItem != nullptr);
127
128   VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
129
130   VariableDumper VarDumper(Printer);
131   VarDumper.start(Symbol, ClassOffsetZero);
132
133   Printer.Indent();
134   uint32_t Index = 0;
135   for (auto &Func : Layout.funcs()) {
136     Printer.NewLine();
137     std::string Name = Func->getName();
138     auto ParentClass =
139         unique_dyn_cast<PDBSymbolTypeUDT>(Func->getClassParent());
140     assert(ParentClass);
141     WithColor(Printer, PDB_ColorItem::Address).get() << " [" << Index << "] ";
142     WithColor(Printer, PDB_ColorItem::Identifier).get()
143         << "&" << ParentClass->getName();
144     Printer << "::";
145     WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
146     ++Index;
147   }
148   Printer.Unindent();
149
150   DumpedAnything = true;
151 }