VariableDumper.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //===- VariableDumper.cpp - -------------------------------------*- 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. #include "VariableDumper.h"
  10. #include "BuiltinDumper.h"
  11. #include "LinePrinter.h"
  12. #include "llvm-pdbdump.h"
  13. #include "FunctionDumper.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
  16. #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
  17. #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
  18. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
  19. #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
  20. #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
  21. #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
  22. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  23. #include "llvm/Support/Format.h"
  24. using namespace llvm;
  25. VariableDumper::VariableDumper(LinePrinter &P)
  26. : PDBSymDumper(true), Printer(P) {}
  27. void VariableDumper::start(const PDBSymbolData &Var) {
  28. if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated)
  29. return;
  30. if (Printer.IsSymbolExcluded(Var.getName()))
  31. return;
  32. auto VarType = Var.getType();
  33. switch (auto LocType = Var.getLocationType()) {
  34. case PDB_LocType::Static:
  35. Printer.NewLine();
  36. Printer << "data [";
  37. WithColor(Printer, PDB_ColorItem::Address).get()
  38. << format_hex(Var.getVirtualAddress(), 10);
  39. Printer << "] ";
  40. WithColor(Printer, PDB_ColorItem::Keyword).get() << "static ";
  41. dumpSymbolTypeAndName(*VarType, Var.getName());
  42. break;
  43. case PDB_LocType::Constant:
  44. if (isa<PDBSymbolTypeEnum>(*VarType))
  45. break;
  46. Printer.NewLine();
  47. Printer << "data ";
  48. WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
  49. dumpSymbolTypeAndName(*VarType, Var.getName());
  50. Printer << " = ";
  51. WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue();
  52. break;
  53. case PDB_LocType::ThisRel:
  54. Printer.NewLine();
  55. Printer << "data ";
  56. WithColor(Printer, PDB_ColorItem::Offset).get()
  57. << "+" << format_hex(Var.getOffset(), 4) << " ";
  58. dumpSymbolTypeAndName(*VarType, Var.getName());
  59. break;
  60. case PDB_LocType::BitField:
  61. Printer.NewLine();
  62. Printer << "data ";
  63. WithColor(Printer, PDB_ColorItem::Offset).get()
  64. << "+" << format_hex(Var.getOffset(), 4) << " ";
  65. dumpSymbolTypeAndName(*VarType, Var.getName());
  66. Printer << " : ";
  67. WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
  68. break;
  69. default:
  70. Printer.NewLine();
  71. Printer << "data ";
  72. Printer << "unknown(" << LocType << ") ";
  73. WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName();
  74. break;
  75. }
  76. }
  77. void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
  78. BuiltinDumper Dumper(Printer);
  79. Dumper.start(Symbol);
  80. }
  81. void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) {
  82. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  83. }
  84. void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {}
  85. void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) {
  86. auto PointeeType = Symbol.getPointeeType();
  87. if (!PointeeType)
  88. return;
  89. if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) {
  90. FunctionDumper NestedDumper(Printer);
  91. FunctionDumper::PointerType Pointer =
  92. Symbol.isReference() ? FunctionDumper::PointerType::Reference
  93. : FunctionDumper::PointerType::Pointer;
  94. NestedDumper.start(*Func, Pointer);
  95. } else {
  96. if (Symbol.isConstType())
  97. WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
  98. if (Symbol.isVolatileType())
  99. WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
  100. PointeeType->dump(*this);
  101. Printer << (Symbol.isReference() ? "&" : "*");
  102. }
  103. }
  104. void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
  105. WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef ";
  106. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  107. }
  108. void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) {
  109. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  110. }
  111. void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type,
  112. StringRef Name) {
  113. if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) {
  114. std::string IndexSpec;
  115. raw_string_ostream IndexStream(IndexSpec);
  116. std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType();
  117. while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) {
  118. IndexStream << "[";
  119. IndexStream << NestedArray->getCount();
  120. IndexStream << "]";
  121. ElementType = NestedArray->getElementType();
  122. }
  123. IndexStream << "[" << ArrayType->getCount() << "]";
  124. ElementType->dump(*this);
  125. WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name;
  126. Printer << IndexStream.str();
  127. } else {
  128. if (!tryDumpFunctionPointer(Type, Name)) {
  129. Type.dump(*this);
  130. WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name;
  131. }
  132. }
  133. }
  134. bool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type,
  135. StringRef Name) {
  136. // Function pointers come across as pointers to function signatures. But the
  137. // signature carries no name, so we have to handle this case separately.
  138. if (auto *PointerType = dyn_cast<PDBSymbolTypePointer>(&Type)) {
  139. auto PointeeType = PointerType->getPointeeType();
  140. if (auto *FunctionSig =
  141. dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
  142. FunctionDumper Dumper(Printer);
  143. FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer;
  144. if (PointerType->isReference())
  145. PT = FunctionDumper::PointerType::Reference;
  146. std::string NameStr(Name.begin(), Name.end());
  147. Dumper.start(*FunctionSig, NameStr.c_str(), PT);
  148. return true;
  149. }
  150. }
  151. return false;
  152. }