]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp
Update our copy of DTS from the ones from Linux 4.14
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / llvm-pdbutil / 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 "PrettyEnumDumper.h"
15 #include "PrettyFunctionDumper.h"
16 #include "PrettyTypedefDumper.h"
17 #include "PrettyVariableDumper.h"
18 #include "PrettyVariableDumper.h"
19 #include "llvm-pdbutil.h"
20
21 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
22 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
23 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
24 #include "llvm/DebugInfo/PDB/UDTLayout.h"
25 #include "llvm/Support/Format.h"
26
27 using namespace llvm;
28 using namespace llvm::pdb;
29
30 PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
31     LinePrinter &P, uint32_t RecurseLevel, uint32_t InitialOffset)
32     : PDBSymDumper(true), Printer(P), RecursionLevel(RecurseLevel),
33       ClassOffsetZero(InitialOffset), CurrentAbsoluteOffset(InitialOffset) {}
34
35 bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {
36
37   if (RecursionLevel == 1 &&
38       opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::All) {
39     for (auto &Other : Layout.other_items())
40       Other->dump(*this);
41     for (auto &Func : Layout.funcs())
42       Func->dump(*this);
43   }
44
45   const BitVector &UseMap = Layout.usedBytes();
46   int NextPaddingByte = UseMap.find_first_unset();
47
48   for (auto &Item : Layout.layout_items()) {
49     // Calculate the absolute offset of the first byte of the next field.
50     uint32_t RelativeOffset = Item->getOffsetInParent();
51     CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;
52
53     // Since there is storage there, it should be set!  However, this might
54     // be an empty base, in which case it could extend outside the bounds of
55     // the parent class.
56     if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {
57       assert(UseMap.test(RelativeOffset));
58
59       // If there is any remaining padding in this class, and the offset of the
60       // new item is after the padding, then we must have just jumped over some
61       // padding.  Print a padding row and then look for where the next block
62       // of padding begins.
63       if ((NextPaddingByte >= 0) &&
64           (RelativeOffset > uint32_t(NextPaddingByte))) {
65         printPaddingRow(RelativeOffset - NextPaddingByte);
66         NextPaddingByte = UseMap.find_next_unset(RelativeOffset);
67       }
68     }
69
70     CurrentItem = Item;
71     if (Item->isVBPtr()) {
72       VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
73
74       VariableDumper VarDumper(Printer);
75       VarDumper.startVbptr(CurrentAbsoluteOffset, Layout.getSize());
76     } else {
77       if (auto Sym = Item->getSymbol())
78         Sym->dump(*this);
79     }
80
81     if (Item->getLayoutSize() > 0) {
82       uint32_t Prev = RelativeOffset + Item->getLayoutSize() - 1;
83       if (Prev < UseMap.size())
84         NextPaddingByte = UseMap.find_next_unset(Prev);
85     }
86   }
87
88   auto TailPadding = Layout.tailPadding();
89   if (TailPadding > 0) {
90     if (TailPadding != 1 || Layout.getSize() != 1) {
91       Printer.NewLine();
92       WithColor(Printer, PDB_ColorItem::Padding).get()
93           << "<padding> (" << TailPadding << " bytes)";
94       DumpedAnything = true;
95     }
96   }
97
98   return DumpedAnything;
99 }
100
101 void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {
102   if (Amount == 0)
103     return;
104
105   Printer.NewLine();
106   WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
107                                                    << " bytes)";
108   DumpedAnything = true;
109 }
110
111 void PrettyClassLayoutGraphicalDumper::dump(
112     const PDBSymbolTypeBaseClass &Symbol) {
113   assert(CurrentItem != nullptr);
114
115   Printer.NewLine();
116   BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
117
118   std::string Label = "base";
119   if (Layout.isVirtualBase()) {
120     Label.insert(Label.begin(), 'v');
121     if (Layout.getBase().isIndirectVirtualBaseClass())
122       Label.insert(Label.begin(), 'i');
123   }
124   Printer << Label << " ";
125
126   uint32_t Size = Layout.isEmptyBase() ? 1 : Layout.getLayoutSize();
127
128   WithColor(Printer, PDB_ColorItem::Offset).get()
129       << "+" << format_hex(CurrentAbsoluteOffset, 4) << " [sizeof=" << Size
130       << "] ";
131
132   WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
133
134   if (shouldRecurse()) {
135     Printer.Indent();
136     uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
137     PrettyClassLayoutGraphicalDumper BaseDumper(Printer, RecursionLevel + 1,
138                                                 ChildOffsetZero);
139     DumpedAnything |= BaseDumper.start(Layout);
140     Printer.Unindent();
141   }
142
143   DumpedAnything = true;
144 }
145
146 bool PrettyClassLayoutGraphicalDumper::shouldRecurse() const {
147   uint32_t Limit = opts::pretty::ClassRecursionDepth;
148   if (Limit == 0)
149     return true;
150   return RecursionLevel < Limit;
151 }
152
153 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {
154   VariableDumper VarDumper(Printer);
155   VarDumper.start(Symbol, ClassOffsetZero);
156
157   if (CurrentItem != nullptr) {
158     DataMemberLayoutItem &Layout =
159         static_cast<DataMemberLayoutItem &>(*CurrentItem);
160
161     if (Layout.hasUDTLayout() && shouldRecurse()) {
162       uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
163       Printer.Indent();
164       PrettyClassLayoutGraphicalDumper TypeDumper(Printer, RecursionLevel + 1,
165                                                   ChildOffsetZero);
166       TypeDumper.start(Layout.getUDTLayout());
167       Printer.Unindent();
168     }
169   }
170
171   DumpedAnything = true;
172 }
173
174 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
175   assert(CurrentItem != nullptr);
176
177   VariableDumper VarDumper(Printer);
178   VarDumper.start(Symbol, ClassOffsetZero);
179
180   DumpedAnything = true;
181 }
182
183 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {
184   DumpedAnything = true;
185   Printer.NewLine();
186   EnumDumper Dumper(Printer);
187   Dumper.start(Symbol);
188 }
189
190 void PrettyClassLayoutGraphicalDumper::dump(
191     const PDBSymbolTypeTypedef &Symbol) {
192   DumpedAnything = true;
193   Printer.NewLine();
194   TypedefDumper Dumper(Printer);
195   Dumper.start(Symbol);
196 }
197
198 void PrettyClassLayoutGraphicalDumper::dump(
199     const PDBSymbolTypeBuiltin &Symbol) {}
200
201 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
202
203 void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {
204   if (Printer.IsSymbolExcluded(Symbol.getName()))
205     return;
206   if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
207     return;
208   if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&
209       !Symbol.isIntroVirtualFunction())
210     return;
211
212   DumpedAnything = true;
213   Printer.NewLine();
214   FunctionDumper Dumper(Printer);
215   Dumper.start(Symbol, FunctionDumper::PointerType::None);
216 }