diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp')
-rw-r--r-- | contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp b/contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp new file mode 100644 index 0000000000..a522935e34 --- /dev/null +++ b/contrib/libs/llvm12/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp @@ -0,0 +1,212 @@ +//===- 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); +} |