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 9 #include "PrettyClassDefinitionDumper.h" 10 11 #include "LinePrinter.h" 12 #include "PrettyClassLayoutGraphicalDumper.h" 13 #include "llvm-pdbutil.h" 14 15 #include "llvm/ADT/APFloat.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" 19 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 20 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 21 #include "llvm/DebugInfo/PDB/UDTLayout.h" 22 23 #include "llvm/Support/Format.h" 24 25 using namespace llvm; 26 using namespace llvm::pdb; 27 28 ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P) 29 : PDBSymDumper(true), Printer(P) {} 30 31 void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) { 32 assert(opts::pretty::ClassFormat != 33 opts::pretty::ClassDefinitionFormat::None); 34 35 ClassLayout Layout(Class); 36 start(Layout); 37 } 38 39 void ClassDefinitionDumper::start(const ClassLayout &Layout) { 40 prettyPrintClassIntro(Layout); 41 42 PrettyClassLayoutGraphicalDumper Dumper(Printer, 1, 0); 43 DumpedAnything |= Dumper.start(Layout); 44 45 prettyPrintClassOutro(Layout); 46 } 47 48 void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) { 49 DumpedAnything = false; 50 Printer.NewLine(); 51 52 uint32_t Size = Layout.getSize(); 53 const PDBSymbolTypeUDT &Class = Layout.getClass(); 54 55 if (Layout.getClass().isConstType()) 56 WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; 57 if (Layout.getClass().isVolatileType()) 58 WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; 59 if (Layout.getClass().isUnalignedType()) 60 WithColor(Printer, PDB_ColorItem::Keyword).get() << "unaligned "; 61 62 WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " "; 63 WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName(); 64 WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size 65 << "]"; 66 uint32_t BaseCount = Layout.bases().size(); 67 if (BaseCount > 0) { 68 Printer.Indent(); 69 char NextSeparator = ':'; 70 for (auto BC : Layout.bases()) { 71 const auto &Base = BC->getBase(); 72 if (Base.isIndirectVirtualBaseClass()) 73 continue; 74 75 Printer.NewLine(); 76 Printer << NextSeparator << " "; 77 WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess(); 78 if (BC->isVirtualBase()) 79 WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual"; 80 81 WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName(); 82 NextSeparator = ','; 83 } 84 85 Printer.Unindent(); 86 } 87 88 Printer << " {"; 89 Printer.Indent(); 90 } 91 92 void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) { 93 Printer.Unindent(); 94 if (DumpedAnything) 95 Printer.NewLine(); 96 Printer << "}"; 97 Printer.NewLine(); 98 if (Layout.deepPaddingSize() > 0) { 99 APFloat Pct(100.0 * (double)Layout.deepPaddingSize() / 100 (double)Layout.getSize()); 101 SmallString<8> PctStr; 102 Pct.toString(PctStr, 4); 103 WithColor(Printer, PDB_ColorItem::Padding).get() 104 << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr 105 << "% of class size)"; 106 Printer.NewLine(); 107 APFloat Pct2(100.0 * (double)Layout.immediatePadding() / 108 (double)Layout.getSize()); 109 PctStr.clear(); 110 Pct2.toString(PctStr, 4); 111 WithColor(Printer, PDB_ColorItem::Padding).get() 112 << "Immediate padding " << Layout.immediatePadding() << " bytes (" 113 << PctStr << "% of class size)"; 114 Printer.NewLine(); 115 } 116 } 117