PrettyClassDefinitionDumper.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //===- PrettyClassDefinitionDumper.cpp --------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "PrettyClassDefinitionDumper.h"
  9. #include "LinePrinter.h"
  10. #include "PrettyClassLayoutGraphicalDumper.h"
  11. #include "llvm-pdbutil.h"
  12. #include "llvm/ADT/APFloat.h"
  13. #include "llvm/ADT/SmallString.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  16. #include "llvm/DebugInfo/PDB/UDTLayout.h"
  17. #include "llvm/Support/Format.h"
  18. using namespace llvm;
  19. using namespace llvm::pdb;
  20. ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
  21. : PDBSymDumper(true), Printer(P) {}
  22. void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
  23. assert(opts::pretty::ClassFormat !=
  24. opts::pretty::ClassDefinitionFormat::None);
  25. ClassLayout Layout(Class);
  26. start(Layout);
  27. }
  28. void ClassDefinitionDumper::start(const ClassLayout &Layout) {
  29. prettyPrintClassIntro(Layout);
  30. PrettyClassLayoutGraphicalDumper Dumper(Printer, 1, 0);
  31. DumpedAnything |= Dumper.start(Layout);
  32. prettyPrintClassOutro(Layout);
  33. }
  34. void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
  35. DumpedAnything = false;
  36. Printer.NewLine();
  37. uint32_t Size = Layout.getSize();
  38. const PDBSymbolTypeUDT &Class = Layout.getClass();
  39. if (Layout.getClass().isConstType())
  40. WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
  41. if (Layout.getClass().isVolatileType())
  42. WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
  43. if (Layout.getClass().isUnalignedType())
  44. WithColor(Printer, PDB_ColorItem::Keyword).get() << "unaligned ";
  45. WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
  46. WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
  47. WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
  48. << "]";
  49. uint32_t BaseCount = Layout.bases().size();
  50. if (BaseCount > 0) {
  51. Printer.Indent();
  52. char NextSeparator = ':';
  53. for (auto BC : Layout.bases()) {
  54. const auto &Base = BC->getBase();
  55. if (Base.isIndirectVirtualBaseClass())
  56. continue;
  57. Printer.NewLine();
  58. Printer << NextSeparator << " ";
  59. WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
  60. if (BC->isVirtualBase())
  61. WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
  62. WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
  63. NextSeparator = ',';
  64. }
  65. Printer.Unindent();
  66. }
  67. Printer << " {";
  68. Printer.Indent();
  69. }
  70. void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) {
  71. Printer.Unindent();
  72. if (DumpedAnything)
  73. Printer.NewLine();
  74. Printer << "}";
  75. Printer.NewLine();
  76. if (Layout.deepPaddingSize() > 0) {
  77. APFloat Pct(100.0 * (double)Layout.deepPaddingSize() /
  78. (double)Layout.getSize());
  79. SmallString<8> PctStr;
  80. Pct.toString(PctStr, 4);
  81. WithColor(Printer, PDB_ColorItem::Padding).get()
  82. << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
  83. << "% of class size)";
  84. Printer.NewLine();
  85. APFloat Pct2(100.0 * (double)Layout.immediatePadding() /
  86. (double)Layout.getSize());
  87. PctStr.clear();
  88. Pct2.toString(PctStr, 4);
  89. WithColor(Printer, PDB_ColorItem::Padding).get()
  90. << "Immediate padding " << Layout.immediatePadding() << " bytes ("
  91. << PctStr << "% of class size)";
  92. Printer.NewLine();
  93. }
  94. }