123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- //===- PrettyClassLayoutGraphicalDumper.h -----------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "PrettyClassLayoutGraphicalDumper.h"
- #include "LinePrinter.h"
- #include "PrettyClassDefinitionDumper.h"
- #include "PrettyEnumDumper.h"
- #include "PrettyFunctionDumper.h"
- #include "PrettyTypedefDumper.h"
- #include "PrettyVariableDumper.h"
- #include "PrettyVariableDumper.h"
- #include "llvm-pdbutil.h"
- #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
- #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
- #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
- #include "llvm/DebugInfo/PDB/UDTLayout.h"
- #include "llvm/Support/Format.h"
- using namespace llvm;
- using namespace llvm::pdb;
- PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
- LinePrinter &P, uint32_t RecurseLevel, uint32_t InitialOffset)
- : PDBSymDumper(true), Printer(P), RecursionLevel(RecurseLevel),
- ClassOffsetZero(InitialOffset), CurrentAbsoluteOffset(InitialOffset) {}
- bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {
- if (RecursionLevel == 1 &&
- opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::All) {
- for (auto &Other : Layout.other_items())
- Other->dump(*this);
- for (auto &Func : Layout.funcs())
- Func->dump(*this);
- }
- const BitVector &UseMap = Layout.usedBytes();
- int NextPaddingByte = UseMap.find_first_unset();
- for (auto &Item : Layout.layout_items()) {
- // Calculate the absolute offset of the first byte of the next field.
- uint32_t RelativeOffset = Item->getOffsetInParent();
- CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;
- // This might be an empty base, in which case it could extend outside the
- // bounds of the parent class.
- if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {
- // If there is any remaining padding in this class, and the offset of the
- // new item is after the padding, then we must have just jumped over some
- // padding. Print a padding row and then look for where the next block
- // of padding begins.
- if ((NextPaddingByte >= 0) &&
- (RelativeOffset > uint32_t(NextPaddingByte))) {
- printPaddingRow(RelativeOffset - NextPaddingByte);
- NextPaddingByte = UseMap.find_next_unset(RelativeOffset);
- }
- }
- CurrentItem = Item;
- if (Item->isVBPtr()) {
- VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
- VariableDumper VarDumper(Printer);
- VarDumper.startVbptr(CurrentAbsoluteOffset, Layout.getSize());
- } else {
- if (auto Sym = Item->getSymbol())
- Sym->dump(*this);
- }
- if (Item->getLayoutSize() > 0) {
- uint32_t Prev = RelativeOffset + Item->getLayoutSize() - 1;
- if (Prev < UseMap.size())
- NextPaddingByte = UseMap.find_next_unset(Prev);
- }
- }
- auto TailPadding = Layout.tailPadding();
- if (TailPadding > 0) {
- if (TailPadding != 1 || Layout.getSize() != 1) {
- Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Padding).get()
- << "<padding> (" << TailPadding << " bytes)";
- DumpedAnything = true;
- }
- }
- return DumpedAnything;
- }
- void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {
- if (Amount == 0)
- return;
- Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
- << " bytes)";
- DumpedAnything = true;
- }
- void PrettyClassLayoutGraphicalDumper::dump(
- const PDBSymbolTypeBaseClass &Symbol) {
- assert(CurrentItem != nullptr);
- Printer.NewLine();
- BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
- std::string Label = "base";
- if (Layout.isVirtualBase()) {
- Label.insert(Label.begin(), 'v');
- if (Layout.getBase().isIndirectVirtualBaseClass())
- Label.insert(Label.begin(), 'i');
- }
- Printer << Label << " ";
- uint32_t Size = Layout.isEmptyBase() ? 1 : Layout.getLayoutSize();
- WithColor(Printer, PDB_ColorItem::Offset).get()
- << "+" << format_hex(CurrentAbsoluteOffset, 4) << " [sizeof=" << Size
- << "] ";
- WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
- if (shouldRecurse()) {
- Printer.Indent();
- uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
- PrettyClassLayoutGraphicalDumper BaseDumper(Printer, RecursionLevel + 1,
- ChildOffsetZero);
- DumpedAnything |= BaseDumper.start(Layout);
- Printer.Unindent();
- }
- DumpedAnything = true;
- }
- bool PrettyClassLayoutGraphicalDumper::shouldRecurse() const {
- uint32_t Limit = opts::pretty::ClassRecursionDepth;
- if (Limit == 0)
- return true;
- return RecursionLevel < Limit;
- }
- void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {
- VariableDumper VarDumper(Printer);
- VarDumper.start(Symbol, ClassOffsetZero);
- if (CurrentItem != nullptr) {
- DataMemberLayoutItem &Layout =
- static_cast<DataMemberLayoutItem &>(*CurrentItem);
- if (Layout.hasUDTLayout() && shouldRecurse()) {
- uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
- Printer.Indent();
- PrettyClassLayoutGraphicalDumper TypeDumper(Printer, RecursionLevel + 1,
- ChildOffsetZero);
- TypeDumper.start(Layout.getUDTLayout());
- Printer.Unindent();
- }
- }
- DumpedAnything = true;
- }
- void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
- assert(CurrentItem != nullptr);
- VariableDumper VarDumper(Printer);
- VarDumper.start(Symbol, ClassOffsetZero);
- DumpedAnything = true;
- }
- void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {
- DumpedAnything = true;
- Printer.NewLine();
- EnumDumper Dumper(Printer);
- Dumper.start(Symbol);
- }
- void PrettyClassLayoutGraphicalDumper::dump(
- const PDBSymbolTypeTypedef &Symbol) {
- DumpedAnything = true;
- Printer.NewLine();
- TypedefDumper Dumper(Printer);
- Dumper.start(Symbol);
- }
- void PrettyClassLayoutGraphicalDumper::dump(
- const PDBSymbolTypeBuiltin &Symbol) {}
- void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
- void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {
- if (Printer.IsSymbolExcluded(Symbol.getName()))
- return;
- if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
- return;
- if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&
- !Symbol.isIntroVirtualFunction())
- return;
- DumpedAnything = true;
- Printer.NewLine();
- FunctionDumper Dumper(Printer);
- Dumper.start(Symbol, FunctionDumper::PointerType::None);
- }
|