[uselistorder] Insert blank line, NFC
[oota-llvm.git] / tools / llvm-pdbdump / llvm-pdbdump.cpp
index e8a105d35d2ac33f77e523e6360f3a2fcc332c00..24b2b79c5c293108ca53b708065c5cceb8afb9b9 100644 (file)
@@ -15,7 +15,9 @@
 
 #include "llvm-pdbdump.h"
 #include "CompilandDumper.h"
+#include "ExternalSymbolDumper.h"
 #include "FunctionDumper.h"
+#include "LinePrinter.h"
 #include "TypeDumper.h"
 #include "VariableDumper.h"
 
@@ -55,84 +57,195 @@ cl::list<std::string> InputFilenames(cl::Positional,
                                      cl::desc("<input PDB files>"),
                                      cl::OneOrMore);
 
-cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"));
-cl::opt<bool> Symbols("symbols",
-                      cl::desc("Display symbols for each compiland"));
-cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"));
-cl::opt<bool> Types("types", cl::desc("Display types"));
-cl::opt<bool> ClassDefs("class-definitions",
-                        cl::desc("Display full class definitions"));
+cl::OptionCategory TypeCategory("Symbol Type Options");
+cl::OptionCategory FilterCategory("Filtering Options");
+cl::OptionCategory OtherOptions("Other Options");
+
+cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"),
+                         cl::cat(TypeCategory));
+cl::opt<bool> Symbols("symbols", cl::desc("Display symbols for each compiland"),
+                      cl::cat(TypeCategory));
+cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"),
+                      cl::cat(TypeCategory));
+cl::opt<bool> Externals("externals", cl::desc("Dump external symbols"),
+                        cl::cat(TypeCategory));
+cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory));
+cl::opt<bool>
+    All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
+        cl::cat(TypeCategory));
+
+cl::opt<uint64_t> LoadAddress(
+    "load-address",
+    cl::desc("Assume the module is loaded at the specified address"),
+    cl::cat(OtherOptions));
+
+cl::list<std::string>
+    ExcludeTypes("exclude-types",
+                 cl::desc("Exclude types by regular expression"),
+                 cl::ZeroOrMore, cl::cat(FilterCategory));
+cl::list<std::string>
+    ExcludeSymbols("exclude-symbols",
+                   cl::desc("Exclude symbols by regular expression"),
+                   cl::ZeroOrMore, cl::cat(FilterCategory));
+cl::list<std::string>
+    ExcludeCompilands("exclude-compilands",
+                      cl::desc("Exclude compilands by regular expression"),
+                      cl::ZeroOrMore, cl::cat(FilterCategory));
+
+cl::list<std::string> IncludeTypes(
+    "include-types",
+    cl::desc("Include only types which match a regular expression"),
+    cl::ZeroOrMore, cl::cat(FilterCategory));
+cl::list<std::string> IncludeSymbols(
+    "include-symbols",
+    cl::desc("Include only symbols which match a regular expression"),
+    cl::ZeroOrMore, cl::cat(FilterCategory));
+cl::list<std::string> IncludeCompilands(
+    "include-compilands",
+    cl::desc("Include only compilands those which match a regular expression"),
+    cl::ZeroOrMore, cl::cat(FilterCategory));
+
+cl::opt<bool> ExcludeCompilerGenerated(
+    "no-compiler-generated",
+    cl::desc("Don't show compiler generated types and symbols"),
+    cl::cat(FilterCategory));
+cl::opt<bool>
+    ExcludeSystemLibraries("no-system-libs",
+                           cl::desc("Don't show symbols from system libraries"),
+                           cl::cat(FilterCategory));
+cl::opt<bool> NoClassDefs("no-class-definitions",
+                          cl::desc("Don't display full class definitions"),
+                          cl::cat(FilterCategory));
+cl::opt<bool> NoEnumDefs("no-enum-definitions",
+                         cl::desc("Don't display full enum definitions"),
+                         cl::cat(FilterCategory));
 }
 
 static void dumpInput(StringRef Path) {
-  std::unique_ptr<IPDBSession> Session(
-      llvm::createPDBReader(PDB_ReaderType::DIA, Path));
-  if (!Session) {
-    outs() << "Unable to create PDB reader.  Check that a valid implementation";
-    outs() << " is available for your platform.";
+  std::unique_ptr<IPDBSession> Session;
+  PDB_ErrorCode Error =
+      llvm::loadDataForPDB(PDB_ReaderType::DIA, Path, Session);
+  switch (Error) {
+  case PDB_ErrorCode::Success:
+    break;
+  case PDB_ErrorCode::NoPdbImpl:
+    outs() << "Reading PDBs is not supported on this platform.\n";
+    return;
+  case PDB_ErrorCode::InvalidPath:
+    outs() << "Unable to load PDB at '" << Path
+           << "'.  Check that the file exists and is readable.\n";
+    return;
+  case PDB_ErrorCode::InvalidFileFormat:
+    outs() << "Unable to load PDB at '" << Path
+           << "'.  The file has an unrecognized format.\n";
+    return;
+  default:
+    outs() << "Unable to load PDB at '" << Path
+           << "'.  An unknown error occured.\n";
     return;
   }
+  if (opts::LoadAddress)
+    Session->setLoadAddress(opts::LoadAddress);
+
+  LinePrinter Printer(2, outs());
 
   auto GlobalScope(Session->getGlobalScope());
   std::string FileName(GlobalScope->getSymbolsFileName());
 
-  outs() << "Summary for " << FileName;
+  WithColor(Printer, PDB_ColorItem::None).get() << "Summary for ";
+  WithColor(Printer, PDB_ColorItem::Path).get() << FileName;
+  Printer.Indent();
   uint64_t FileSize = 0;
-  if (!llvm::sys::fs::file_size(FileName, FileSize))
-    outs() << newline(2) << "Size: " << FileSize << " bytes";
-  else
-    outs() << newline(2) << "Size: (Unable to obtain file size)";
-
-  outs() << newline(2) << "Guid: " << GlobalScope->getGuid();
-  outs() << newline(2) << "Age: " << GlobalScope->getAge();
-  outs() << newline(2) << "Attributes: ";
+
+  Printer.NewLine();
+  WithColor(Printer, PDB_ColorItem::Identifier).get() << "Size";
+  if (!llvm::sys::fs::file_size(FileName, FileSize)) {
+    Printer << ": " << FileSize << " bytes";
+  } else {
+    Printer << ": (Unable to obtain file size)";
+  }
+
+  Printer.NewLine();
+  WithColor(Printer, PDB_ColorItem::Identifier).get() << "Guid";
+  Printer << ": " << GlobalScope->getGuid();
+
+  Printer.NewLine();
+  WithColor(Printer, PDB_ColorItem::Identifier).get() << "Age";
+  Printer << ": " << GlobalScope->getAge();
+
+  Printer.NewLine();
+  WithColor(Printer, PDB_ColorItem::Identifier).get() << "Attributes";
+  Printer << ": ";
   if (GlobalScope->hasCTypes())
     outs() << "HasCTypes ";
   if (GlobalScope->hasPrivateSymbols())
     outs() << "HasPrivateSymbols ";
+  Printer.Unindent();
 
   if (opts::Compilands) {
-    outs() << "\n---COMPILANDS---";
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get()
+        << "---COMPILANDS---";
+    Printer.Indent();
     auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
-    CompilandDumper Dumper;
+    CompilandDumper Dumper(Printer);
     while (auto Compiland = Compilands->getNext())
-      Dumper.start(*Compiland, outs(), 2, false);
+      Dumper.start(*Compiland, false);
+    Printer.Unindent();
   }
 
   if (opts::Types) {
-    outs() << "\n---TYPES---";
-    TypeDumper Dumper(false, opts::ClassDefs);
-    Dumper.start(*GlobalScope, outs(), 2);
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
+    Printer.Indent();
+    TypeDumper Dumper(Printer);
+    Dumper.start(*GlobalScope);
+    Printer.Unindent();
   }
 
   if (opts::Symbols) {
-    outs() << "\n---SYMBOLS---";
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---";
+    Printer.Indent();
     auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
-    CompilandDumper Dumper;
+    CompilandDumper Dumper(Printer);
     while (auto Compiland = Compilands->getNext())
-      Dumper.start(*Compiland, outs(), 2, true);
+      Dumper.start(*Compiland, true);
+    Printer.Unindent();
   }
 
   if (opts::Globals) {
-    outs() << "\n---GLOBALS---";
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---";
+    Printer.Indent();
     {
-      FunctionDumper Dumper;
+      FunctionDumper Dumper(Printer);
       auto Functions = GlobalScope->findAllChildren<PDBSymbolFunc>();
-      while (auto Function = Functions->getNext())
-        Dumper.start(*Function, FunctionDumper::PointerType::None, outs(), 2);
+      while (auto Function = Functions->getNext()) {
+        Printer.NewLine();
+        Dumper.start(*Function, FunctionDumper::PointerType::None);
+      }
     }
     {
       auto Vars = GlobalScope->findAllChildren<PDBSymbolData>();
-      VariableDumper Dumper;
+      VariableDumper Dumper(Printer);
       while (auto Var = Vars->getNext())
-        Dumper.start(*Var, outs(), 2);
+        Dumper.start(*Var);
     }
     {
       auto Thunks = GlobalScope->findAllChildren<PDBSymbolThunk>();
-      CompilandDumper Dumper;
+      CompilandDumper Dumper(Printer);
       while (auto Thunk = Thunks->getNext())
-        Dumper.dump(*Thunk, outs(), 2);
+        Dumper.dump(*Thunk);
     }
+    Printer.Unindent();
+  }
+  if (opts::Externals) {
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---EXTERNALS---";
+    Printer.Indent();
+    ExternalSymbolDumper Dumper(Printer);
+    Dumper.start(*GlobalScope);
   }
   outs().flush();
 }
@@ -154,6 +267,21 @@ int main(int argc_, const char *argv_[]) {
   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
 
   cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
+  if (opts::All) {
+    opts::Compilands = true;
+    opts::Symbols = true;
+    opts::Globals = true;
+    opts::Types = true;
+    opts::Externals = true;
+  }
+  if (opts::ExcludeCompilerGenerated) {
+    opts::ExcludeTypes.push_back("__vc_attributes");
+    opts::ExcludeCompilands.push_back("* Linker *");
+  }
+  if (opts::ExcludeSystemLibraries) {
+    opts::ExcludeCompilands.push_back(
+        "f:\\binaries\\Intermediate\\vctools\\crt_bld");
+  }
 
 #if defined(HAVE_DIA_SDK)
   CoInitializeEx(nullptr, COINIT_MULTITHREADED);