From 4c5e43da7792f75567b693105cc53e3f1992ad98 Mon Sep 17 00:00:00 2001 From: Pirama Arumuga Nainar Date: Wed, 8 Apr 2015 08:55:49 -0700 Subject: Update aosp/master llvm for rebase to r233350 Change-Id: I07d935f8793ee8ec6b7da003f6483046594bca49 --- tools/llvm-pdbdump/Android.mk | 5 +- tools/llvm-pdbdump/BuiltinDumper.cpp | 87 ++++++++++++ tools/llvm-pdbdump/BuiltinDumper.h | 30 ++++ tools/llvm-pdbdump/CMakeLists.txt | 3 + tools/llvm-pdbdump/ClassDefinitionDumper.cpp | 136 +++++++++++------- tools/llvm-pdbdump/ClassDefinitionDumper.h | 30 ++-- tools/llvm-pdbdump/CompilandDumper.cpp | 107 ++++++++------ tools/llvm-pdbdump/CompilandDumper.h | 34 ++--- tools/llvm-pdbdump/EnumDumper.cpp | 52 +++++++ tools/llvm-pdbdump/EnumDumper.h | 30 ++++ tools/llvm-pdbdump/FunctionDumper.cpp | 199 ++++++++++++++------------- tools/llvm-pdbdump/FunctionDumper.h | 37 +++-- tools/llvm-pdbdump/LinePrinter.cpp | 124 +++++++++++++++++ tools/llvm-pdbdump/LinePrinter.h | 89 ++++++++++++ tools/llvm-pdbdump/TypeDumper.cpp | 97 ++++++------- tools/llvm-pdbdump/TypeDumper.h | 20 ++- tools/llvm-pdbdump/TypedefDumper.cpp | 61 ++++---- tools/llvm-pdbdump/TypedefDumper.h | 31 ++--- tools/llvm-pdbdump/VariableDumper.cpp | 136 ++++++++++++------ tools/llvm-pdbdump/VariableDumper.h | 34 +++-- tools/llvm-pdbdump/llvm-pdbdump.cpp | 187 +++++++++++++++++++++---- tools/llvm-pdbdump/llvm-pdbdump.h | 24 ++-- 22 files changed, 1106 insertions(+), 447 deletions(-) create mode 100644 tools/llvm-pdbdump/BuiltinDumper.cpp create mode 100644 tools/llvm-pdbdump/BuiltinDumper.h create mode 100644 tools/llvm-pdbdump/EnumDumper.cpp create mode 100644 tools/llvm-pdbdump/EnumDumper.h create mode 100644 tools/llvm-pdbdump/LinePrinter.cpp create mode 100644 tools/llvm-pdbdump/LinePrinter.h (limited to 'tools/llvm-pdbdump') diff --git a/tools/llvm-pdbdump/Android.mk b/tools/llvm-pdbdump/Android.mk index 82a406a..313e9a4 100644 --- a/tools/llvm-pdbdump/Android.mk +++ b/tools/llvm-pdbdump/Android.mk @@ -4,10 +4,13 @@ LLVM_ROOT_PATH := $(LOCAL_PATH)/../.. include $(LLVM_ROOT_PATH)/llvm.mk llvm_pdbdump_SRC_FILES := \ + llvm-pdbdump.cpp \ + BuiltinDumper.cpp \ ClassDefinitionDumper.cpp \ CompilandDumper.cpp \ + EnumDumper.cpp \ FunctionDumper.cpp \ - llvm-pdbdump.cpp \ + LinePrinter.cpp \ TypedefDumper.cpp \ TypeDumper.cpp \ VariableDumper.cpp diff --git a/tools/llvm-pdbdump/BuiltinDumper.cpp b/tools/llvm-pdbdump/BuiltinDumper.cpp new file mode 100644 index 0000000..d808298 --- /dev/null +++ b/tools/llvm-pdbdump/BuiltinDumper.cpp @@ -0,0 +1,87 @@ +//===- BuiltinDumper.cpp ---------------------------------------- *- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" + +using namespace llvm; + +BuiltinDumper::BuiltinDumper(LinePrinter &P) + : PDBSymDumper(false), Printer(P) {} + +void BuiltinDumper::start(const PDBSymbolTypeBuiltin &Symbol) { + PDB_BuiltinType Type = Symbol.getBuiltinType(); + switch (Type) { + case PDB_BuiltinType::Float: + if (Symbol.getLength() == 4) + WithColor(Printer, PDB_ColorItem::Type).get() << "float"; + else + WithColor(Printer, PDB_ColorItem::Type).get() << "double"; + break; + case PDB_BuiltinType::UInt: + WithColor(Printer, PDB_ColorItem::Type).get() << "unsigned"; + if (Symbol.getLength() == 8) + WithColor(Printer, PDB_ColorItem::Type).get() << " __int64"; + break; + case PDB_BuiltinType::Int: + if (Symbol.getLength() == 4) + WithColor(Printer, PDB_ColorItem::Type).get() << "int"; + else + WithColor(Printer, PDB_ColorItem::Type).get() << "__int64"; + break; + case PDB_BuiltinType::Char: + WithColor(Printer, PDB_ColorItem::Type).get() << "char"; + break; + case PDB_BuiltinType::WCharT: + WithColor(Printer, PDB_ColorItem::Type).get() << "wchar_t"; + break; + case PDB_BuiltinType::Void: + WithColor(Printer, PDB_ColorItem::Type).get() << "void"; + break; + case PDB_BuiltinType::Long: + WithColor(Printer, PDB_ColorItem::Type).get() << "long"; + break; + case PDB_BuiltinType::ULong: + WithColor(Printer, PDB_ColorItem::Type).get() << "unsigned long"; + break; + case PDB_BuiltinType::Bool: + WithColor(Printer, PDB_ColorItem::Type).get() << "bool"; + break; + case PDB_BuiltinType::Currency: + WithColor(Printer, PDB_ColorItem::Type).get() << "CURRENCY"; + break; + case PDB_BuiltinType::Date: + WithColor(Printer, PDB_ColorItem::Type).get() << "DATE"; + break; + case PDB_BuiltinType::Variant: + WithColor(Printer, PDB_ColorItem::Type).get() << "VARIANT"; + break; + case PDB_BuiltinType::Complex: + WithColor(Printer, PDB_ColorItem::Type).get() << "complex"; + break; + case PDB_BuiltinType::Bitfield: + WithColor(Printer, PDB_ColorItem::Type).get() << "bitfield"; + break; + case PDB_BuiltinType::BSTR: + WithColor(Printer, PDB_ColorItem::Type).get() << "BSTR"; + break; + case PDB_BuiltinType::HResult: + WithColor(Printer, PDB_ColorItem::Type).get() << "HRESULT"; + break; + case PDB_BuiltinType::BCD: + WithColor(Printer, PDB_ColorItem::Type).get() << "HRESULT"; + break; + default: + WithColor(Printer, PDB_ColorItem::Type).get() << "void"; + break; + } +} diff --git a/tools/llvm-pdbdump/BuiltinDumper.h b/tools/llvm-pdbdump/BuiltinDumper.h new file mode 100644 index 0000000..8cf984a --- /dev/null +++ b/tools/llvm-pdbdump/BuiltinDumper.h @@ -0,0 +1,30 @@ +//===- BuiltinDumper.h ---------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMPDBDUMP_BUILTINDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_BUILTINDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class BuiltinDumper : public PDBSymDumper { +public: + BuiltinDumper(LinePrinter &P); + + void start(const PDBSymbolTypeBuiltin &Symbol); + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/tools/llvm-pdbdump/CMakeLists.txt b/tools/llvm-pdbdump/CMakeLists.txt index 0519bf0..4dd339c 100644 --- a/tools/llvm-pdbdump/CMakeLists.txt +++ b/tools/llvm-pdbdump/CMakeLists.txt @@ -5,9 +5,12 @@ set(LLVM_LINK_COMPONENTS add_llvm_tool(llvm-pdbdump llvm-pdbdump.cpp + BuiltinDumper.cpp ClassDefinitionDumper.cpp CompilandDumper.cpp + EnumDumper.cpp FunctionDumper.cpp + LinePrinter.cpp TypeDumper.cpp TypedefDumper.cpp VariableDumper.cpp diff --git a/tools/llvm-pdbdump/ClassDefinitionDumper.cpp b/tools/llvm-pdbdump/ClassDefinitionDumper.cpp index edf6eb4..8abf3fa 100644 --- a/tools/llvm-pdbdump/ClassDefinitionDumper.cpp +++ b/tools/llvm-pdbdump/ClassDefinitionDumper.cpp @@ -8,7 +8,9 @@ //===----------------------------------------------------------------------===// #include "ClassDefinitionDumper.h" +#include "EnumDumper.h" #include "FunctionDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "TypedefDumper.h" #include "VariableDumper.h" @@ -27,14 +29,38 @@ using namespace llvm; -ClassDefinitionDumper::ClassDefinitionDumper() : PDBSymDumper(true) {} +ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) { + std::string Name = Class.getName(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " "; + WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName(); + + auto Bases = Class.findAllChildren(); + if (Bases->getChildCount() > 0) { + Printer.Indent(); + Printer.NewLine(); + Printer << ":"; + uint32_t BaseIndex = 0; + while (auto Base = Bases->getNext()) { + Printer << " "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << Base->getAccess(); + if (Base->isVirtualBaseClass()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual"; + WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base->getName(); + if (++BaseIndex < Bases->getChildCount()) { + Printer.NewLine(); + Printer << ","; + } + } + Printer.Unindent(); + } -void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class, - raw_ostream &OS, int Indent) { - OS << "class " << Class.getName() << " {"; + Printer << " {"; auto Children = Class.findAllChildren(); if (Children->getChildCount() == 0) { - OS << "}"; + Printer << "}"; return; } @@ -58,9 +84,10 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class, auto &AccessGroup = Groups.find((int)Access)->second; if (auto Func = dyn_cast(Child.get())) { - if (Func->isCompilerGenerated()) + if (Func->isCompilerGenerated() && opts::ExcludeCompilerGenerated) continue; - if (Func->getLength() == 0 && !Func->isPureVirtual()) + if (Func->getLength() == 0 && !Func->isPureVirtual() && + !Func->isIntroVirtualFunction()) continue; Child.release(); AccessGroup.Functions.push_back(std::unique_ptr(Func)); @@ -73,80 +100,91 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class, } int Count = 0; - Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[0], OS, Indent); + Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[0]); Count += dumpAccessGroup(PDB_MemberAccess::Public, - Groups[(int)PDB_MemberAccess::Public], OS, Indent); - Count += - dumpAccessGroup(PDB_MemberAccess::Protected, - Groups[(int)PDB_MemberAccess::Protected], OS, Indent); + Groups[(int)PDB_MemberAccess::Public]); + Count += dumpAccessGroup(PDB_MemberAccess::Protected, + Groups[(int)PDB_MemberAccess::Protected]); Count += dumpAccessGroup(PDB_MemberAccess::Private, - Groups[(int)PDB_MemberAccess::Private], OS, Indent); - + Groups[(int)PDB_MemberAccess::Private]); if (Count > 0) - OS << newline(Indent); - OS << "}"; + Printer.NewLine(); + Printer << "}"; } int ClassDefinitionDumper::dumpAccessGroup(PDB_MemberAccess Access, - const SymbolGroup &Group, - raw_ostream &OS, int Indent) { + const SymbolGroup &Group) { if (Group.Functions.empty() && Group.Data.empty() && Group.Unknown.empty()) return 0; int Count = 0; - if (Access == PDB_MemberAccess::Private) - OS << newline(Indent) << "private:"; - else if (Access == PDB_MemberAccess::Protected) - OS << newline(Indent) << "protected:"; - else if (Access == PDB_MemberAccess::Public) - OS << newline(Indent) << "public:"; + if (Access == PDB_MemberAccess::Private) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "private"; + Printer << ":"; + } else if (Access == PDB_MemberAccess::Protected) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "protected"; + Printer << ":"; + } else if (Access == PDB_MemberAccess::Public) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "public"; + Printer << ":"; + } + Printer.Indent(); for (auto iter = Group.Functions.begin(), end = Group.Functions.end(); iter != end; ++iter) { ++Count; - (*iter)->dump(OS, Indent + 2, *this); + (*iter)->dump(*this); } for (auto iter = Group.Data.begin(), end = Group.Data.end(); iter != end; ++iter) { ++Count; - (*iter)->dump(OS, Indent + 2, *this); + (*iter)->dump(*this); } for (auto iter = Group.Unknown.begin(), end = Group.Unknown.end(); iter != end; ++iter) { ++Count; - (*iter)->dump(OS, Indent + 2, *this); + (*iter)->dump(*this); } + Printer.Unindent(); return Count; } -void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol, - raw_ostream &OS, int Indent) {} +void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {} -void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS, - int Indent) { - VariableDumper Dumper; - Dumper.start(Symbol, OS, Indent); +void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol) { + VariableDumper Dumper(Printer); + Dumper.start(Symbol); } -void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, - int Indent) { - FunctionDumper Dumper; - Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent); +void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, FunctionDumper::PointerType::None); } -void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol, - raw_ostream &OS, int Indent) {} +void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol) {} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; -void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol, - raw_ostream &OS, int Indent) { - OS << newline(Indent) << "enum " << Symbol.getName(); + Printer.NewLine(); + EnumDumper Dumper(Printer); + Dumper.start(Symbol); } -void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol, - raw_ostream &OS, int Indent) { - OS << newline(Indent); - TypedefDumper Dumper; - Dumper.start(Symbol, OS, Indent); +void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + TypedefDumper Dumper(Printer); + Dumper.start(Symbol); } -void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol, - raw_ostream &OS, int Indent) {} +void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol) {} diff --git a/tools/llvm-pdbdump/ClassDefinitionDumper.h b/tools/llvm-pdbdump/ClassDefinitionDumper.h index aaf0376..5b48ba8 100644 --- a/tools/llvm-pdbdump/ClassDefinitionDumper.h +++ b/tools/llvm-pdbdump/ClassDefinitionDumper.h @@ -20,26 +20,25 @@ namespace llvm { +class LinePrinter; + class ClassDefinitionDumper : public PDBSymDumper { public: - ClassDefinitionDumper(); + ClassDefinitionDumper(LinePrinter &P); - void start(const PDBSymbolTypeUDT &Exe, raw_ostream &OS, int Indent); + void start(const PDBSymbolTypeUDT &Exe); - void dump(const PDBSymbolTypeBaseClass &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeVTable &Symbol, raw_ostream &OS, - int Indent) override; + void dump(const PDBSymbolTypeBaseClass &Symbol) override; + void dump(const PDBSymbolData &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolFunc &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + void dump(const PDBSymbolTypeVTable &Symbol) override; private: + LinePrinter &Printer; + struct SymbolGroup { SymbolGroup() {} SymbolGroup(SymbolGroup &&Other) { @@ -56,8 +55,7 @@ private: }; typedef std::unordered_map SymbolGroupByAccess; - int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group, - raw_ostream &OS, int Indent); + int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group); }; } diff --git a/tools/llvm-pdbdump/CompilandDumper.cpp b/tools/llvm-pdbdump/CompilandDumper.cpp index 852ddfa..86bf32d 100644 --- a/tools/llvm-pdbdump/CompilandDumper.cpp +++ b/tools/llvm-pdbdump/CompilandDumper.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "CompilandDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" @@ -34,84 +35,106 @@ using namespace llvm; -CompilandDumper::CompilandDumper() : PDBSymDumper(true) {} +CompilandDumper::CompilandDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} -void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol, - raw_ostream &OS, int Indent) {} +void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {} -void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol, raw_ostream &OS, - int Indent) {} +void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {} -void CompilandDumper::start(const PDBSymbolCompiland &Symbol, raw_ostream &OS, - int Indent, bool Children) { +void CompilandDumper::start(const PDBSymbolCompiland &Symbol, bool Children) { std::string FullName = Symbol.getName(); - OS << newline(Indent) << FullName; + if (Printer.IsCompilandExcluded(FullName)) + return; + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Path).get() << FullName; if (!Children) return; auto ChildrenEnum = Symbol.findAllChildren(); + Printer.Indent(); while (auto Child = ChildrenEnum->getNext()) - Child->dump(OS, Indent + 2, *this); + Child->dump(*this); + Printer.Unindent(); } -void CompilandDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS, - int Indent) { - OS << newline(Indent); +void CompilandDumper::dump(const PDBSymbolData &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + switch (auto LocType = Symbol.getLocationType()) { case PDB_LocType::Static: - OS << "data: ["; - OS << format_hex(Symbol.getRelativeVirtualAddress(), 10); - OS << "]"; + Printer << "data: "; + WithColor(Printer, PDB_ColorItem::Address).get() + << "[" << format_hex(Symbol.getRelativeVirtualAddress(), 10) << "]"; break; case PDB_LocType::Constant: - OS << "constant: [" << Symbol.getValue() << "]"; + Printer << "constant: "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() + << "[" << Symbol.getValue() << "]"; break; default: - OS << "data(unexpected type=" << LocType << ")"; + Printer << "data(unexpected type=" << LocType << ")"; } - OS << " " << Symbol.getName(); + Printer << " "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } -void CompilandDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, - int Indent) { +void CompilandDumper::dump(const PDBSymbolFunc &Symbol) { if (Symbol.getLength() == 0) return; + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; - FunctionDumper Dumper; - Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent); + Printer.NewLine(); + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, FunctionDumper::PointerType::None); } -void CompilandDumper::dump(const PDBSymbolLabel &Symbol, raw_ostream &OS, - int Indent) { - OS << newline(Indent); - OS << "label [" << format_hex(Symbol.getRelativeVirtualAddress(), 10) << "] " - << Symbol.getName(); +void CompilandDumper::dump(const PDBSymbolLabel &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + Printer << "label "; + WithColor(Printer, PDB_ColorItem::Address).get() + << "[" << format_hex(Symbol.getRelativeVirtualAddress(), 10) << "] "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } -void CompilandDumper::dump(const PDBSymbolThunk &Symbol, raw_ostream &OS, - int Indent) { - OS << newline(Indent) << "thunk "; +void CompilandDumper::dump(const PDBSymbolThunk &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + Printer << "thunk "; PDB_ThunkOrdinal Ordinal = Symbol.getThunkOrdinal(); uint32_t RVA = Symbol.getRelativeVirtualAddress(); if (Ordinal == PDB_ThunkOrdinal::TrampIncremental) { - OS << format_hex(RVA, 10); - OS << " -> " << format_hex(Symbol.getTargetRelativeVirtualAddress(), 10); + uint32_t Target = Symbol.getTargetRelativeVirtualAddress(); + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(RVA, 10); + Printer << " -> "; + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10); } else { - OS << "[" << format_hex(RVA, 10); - OS << " - " << format_hex(RVA + Symbol.getLength(), 10) << "]"; + WithColor(Printer, PDB_ColorItem::Address).get() + << "[" << format_hex(RVA, 10) << " - " + << format_hex(RVA + Symbol.getLength(), 10) << "]"; } - OS << " (" << Ordinal << ") "; + Printer << " ("; + WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal; + Printer << ") "; std::string Name = Symbol.getName(); if (!Name.empty()) - OS << Name; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; } -void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) {} +void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {} -void CompilandDumper::dump(const PDBSymbolUnknown &Symbol, raw_ostream &OS, - int Indent) { - OS << newline(Indent); - OS << "unknown (" << Symbol.getSymTag() << ")"; +void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) { + Printer.NewLine(); + Printer << "unknown (" << Symbol.getSymTag() << ")"; } diff --git a/tools/llvm-pdbdump/CompilandDumper.h b/tools/llvm-pdbdump/CompilandDumper.h index abcebc2..0d1d27c 100644 --- a/tools/llvm-pdbdump/CompilandDumper.h +++ b/tools/llvm-pdbdump/CompilandDumper.h @@ -14,25 +14,25 @@ namespace llvm { +class LinePrinter; + class CompilandDumper : public PDBSymDumper { public: - CompilandDumper(); - - void start(const PDBSymbolCompiland &Symbol, raw_ostream &OS, int Indent, - bool Children); - - void dump(const PDBSymbolCompilandDetails &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolCompilandEnv &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolLabel &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolThunk &Symbol, raw_ostream &OS, int Indent) override; - void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolUnknown &Symbol, raw_ostream &OS, - int Indent) override; + CompilandDumper(LinePrinter &P); + + void start(const PDBSymbolCompiland &Symbol, bool Children); + + void dump(const PDBSymbolCompilandDetails &Symbol) override; + void dump(const PDBSymbolCompilandEnv &Symbol) override; + void dump(const PDBSymbolData &Symbol) override; + void dump(const PDBSymbolFunc &Symbol) override; + void dump(const PDBSymbolLabel &Symbol) override; + void dump(const PDBSymbolThunk &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolUnknown &Symbol) override; + +private: + LinePrinter &Printer; }; } diff --git a/tools/llvm-pdbdump/EnumDumper.cpp b/tools/llvm-pdbdump/EnumDumper.cpp new file mode 100644 index 0000000..3514c39 --- /dev/null +++ b/tools/llvm-pdbdump/EnumDumper.cpp @@ -0,0 +1,52 @@ +//===- EnumDumper.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "EnumDumper.h" + +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" + +using namespace llvm; + +EnumDumper::EnumDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} + +void EnumDumper::start(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); + if (!opts::NoEnumDefs) { + auto BuiltinType = Symbol.getUnderlyingType(); + if (BuiltinType->getBuiltinType() != PDB_BuiltinType::Int || + BuiltinType->getLength() != 4) { + Printer << " : "; + BuiltinDumper Dumper(Printer); + Dumper.start(*BuiltinType); + } + Printer << " {"; + Printer.Indent(); + auto EnumValues = Symbol.findAllChildren(); + while (auto EnumValue = EnumValues->getNext()) { + if (EnumValue->getDataKind() != PDB_DataKind::Constant) + continue; + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() + << EnumValue->getName(); + Printer << " = "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() + << EnumValue->getValue(); + } + Printer.Unindent(); + Printer.NewLine(); + Printer << "}"; + } +} diff --git a/tools/llvm-pdbdump/EnumDumper.h b/tools/llvm-pdbdump/EnumDumper.h new file mode 100644 index 0000000..23de061 --- /dev/null +++ b/tools/llvm-pdbdump/EnumDumper.h @@ -0,0 +1,30 @@ +//===- EnumDumper.h - -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMPDBDUMP_ENUMDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_ENUMDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class EnumDumper : public PDBSymDumper { +public: + EnumDumper(LinePrinter &P); + + void start(const PDBSymbolTypeEnum &Symbol); + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/tools/llvm-pdbdump/FunctionDumper.cpp b/tools/llvm-pdbdump/FunctionDumper.cpp index e659830..419f888 100644 --- a/tools/llvm-pdbdump/FunctionDumper.cpp +++ b/tools/llvm-pdbdump/FunctionDumper.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "FunctionDumper.h" +#include "BuiltinDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" @@ -16,7 +18,6 @@ #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" -#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" @@ -29,7 +30,7 @@ using namespace llvm; namespace { template -void dumpClassParentWithScopeOperator(const T &Symbol, llvm::raw_ostream &OS, +void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer, llvm::FunctionDumper &Dumper) { uint32_t ClassParentId = Symbol.getClassParentId(); auto ClassParent = @@ -38,17 +39,19 @@ void dumpClassParentWithScopeOperator(const T &Symbol, llvm::raw_ostream &OS, if (!ClassParent) return; - OS << ClassParent->getName() << "::"; + WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName(); + Printer << "::"; } } -FunctionDumper::FunctionDumper() : PDBSymDumper(true) {} +FunctionDumper::FunctionDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol, - PointerType Pointer, raw_ostream &OS) { + const char *Name, PointerType Pointer) { auto ReturnType = Symbol.getReturnType(); - ReturnType->dump(OS, 0, *this); - OS << " "; + ReturnType->dump(*this); + Printer << " "; uint32_t ClassParentId = Symbol.getClassParentId(); auto ClassParent = Symbol.getSession().getConcreteSymbolById( @@ -63,181 +66,189 @@ void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol, if (Pointer == PointerType::None) { if (ShouldDumpCallingConvention) - OS << CC << " "; - if (ClassParent) - OS << "(" << ClassParent->getName() << "::)"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " "; + if (ClassParent) { + Printer << "("; + WithColor(Printer, PDB_ColorItem::Identifier).get() + << ClassParent->getName(); + Printer << "::)"; + } } else { - OS << "("; + Printer << "("; if (ShouldDumpCallingConvention) - OS << CC << " "; - OS << Symbol.getCallingConvention() << " "; - if (ClassParent) - OS << ClassParent->getName() << "::"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " "; + if (ClassParent) { + WithColor(Printer, PDB_ColorItem::Identifier).get() + << ClassParent->getName(); + Printer << "::"; + } if (Pointer == PointerType::Reference) - OS << "&"; + Printer << "&"; else - OS << "*"; - OS << ")"; + Printer << "*"; + if (Name) + WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; + Printer << ")"; } - OS << "("; + Printer << "("; if (auto ChildEnum = Symbol.getArguments()) { uint32_t Index = 0; while (auto Arg = ChildEnum->getNext()) { - Arg->dump(OS, 0, *this); + Arg->dump(*this); if (++Index < ChildEnum->getChildCount()) - OS << ", "; + Printer << ", "; } } - OS << ")"; + Printer << ")"; if (Symbol.isConstType()) - OS << " const"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const"; if (Symbol.isVolatileType()) - OS << " volatile"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile"; } -void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer, - raw_ostream &OS, int Indent) { +void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) { uint32_t FuncStart = Symbol.getRelativeVirtualAddress(); uint32_t FuncEnd = FuncStart + Symbol.getLength(); - OS << newline(Indent); - - OS << "func [" << format_hex(FuncStart, 8); - if (auto DebugStart = Symbol.findOneChild()) - OS << "+" << DebugStart->getRelativeVirtualAddress() - FuncStart; - OS << " - " << format_hex(FuncEnd, 8); - if (auto DebugEnd = Symbol.findOneChild()) - OS << "-" << FuncEnd - DebugEnd->getRelativeVirtualAddress(); - OS << "] "; + Printer << "func ["; + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10); + if (auto DebugStart = Symbol.findOneChild()) { + uint32_t Prologue = DebugStart->getRelativeVirtualAddress() - FuncStart; + WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue; + } + Printer << " - "; + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10); + if (auto DebugEnd = Symbol.findOneChild()) { + uint32_t Epilogue = FuncEnd - DebugEnd->getRelativeVirtualAddress(); + WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue; + } + Printer << "] ("; - if (Symbol.hasFramePointer()) - OS << "(" << Symbol.getLocalBasePointerRegisterId() << ")"; - else - OS << "(FPO)"; + if (Symbol.hasFramePointer()) { + WithColor(Printer, PDB_ColorItem::Register).get() + << Symbol.getLocalBasePointerRegisterId(); + } else { + WithColor(Printer, PDB_ColorItem::Register).get() << "FPO"; + } + Printer << ") "; - OS << " "; if (Symbol.isVirtual() || Symbol.isPureVirtual()) - OS << "virtual "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual "; auto Signature = Symbol.getSignature(); if (!Signature) { - OS << Symbol.getName(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); if (Pointer == PointerType::Pointer) - OS << "*"; + Printer << "*"; else if (Pointer == FunctionDumper::PointerType::Reference) - OS << "&"; + Printer << "&"; return; } auto ReturnType = Signature->getReturnType(); - ReturnType->dump(OS, 0, *this); - OS << " "; + ReturnType->dump(*this); + Printer << " "; auto ClassParent = Symbol.getClassParent(); PDB_CallingConv CC = Signature->getCallingConvention(); if (Pointer != FunctionDumper::PointerType::None) - OS << "("; + Printer << "("; if ((ClassParent && CC != PDB_CallingConv::Thiscall) || - (!ClassParent && CC != PDB_CallingConv::NearStdcall)) - OS << Signature->getCallingConvention() << " "; - OS << Symbol.getName(); + (!ClassParent && CC != PDB_CallingConv::NearStdcall)) { + WithColor(Printer, PDB_ColorItem::Keyword).get() + << Signature->getCallingConvention() << " "; + } + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); if (Pointer != FunctionDumper::PointerType::None) { if (Pointer == PointerType::Pointer) - OS << "*"; + Printer << "*"; else if (Pointer == FunctionDumper::PointerType::Reference) - OS << "&"; - OS << ")"; + Printer << "&"; + Printer << ")"; } - OS << "("; + Printer << "("; if (auto Arguments = Symbol.getArguments()) { uint32_t Index = 0; while (auto Arg = Arguments->getNext()) { auto ArgType = Arg->getType(); - ArgType->dump(OS, 0, *this); - OS << " " << Arg->getName(); + ArgType->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " + << Arg->getName(); if (++Index < Arguments->getChildCount()) - OS << ", "; + Printer << ", "; } } - OS << ")"; + Printer << ")"; if (Symbol.isConstType()) - OS << " const"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const"; if (Symbol.isVolatileType()) - OS << " volatile"; + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile"; if (Symbol.isPureVirtual()) - OS << " = 0"; + Printer << " = 0"; } -void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS, - int Indent) { +void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) { uint32_t ElementTypeId = Symbol.getTypeId(); auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId); if (!ElementType) return; - ElementType->dump(OS, 0, *this); - OS << "[" << Symbol.getLength() << "]"; + ElementType->dump(*this); + Printer << "["; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength(); + Printer << "]"; } -void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) { - PDB_BuiltinType Type = Symbol.getBuiltinType(); - OS << Type; - if (Type == PDB_BuiltinType::UInt || Type == PDB_BuiltinType::Int) - OS << (8 * Symbol.getLength()) << "_t"; +void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); } -void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) { - dumpClassParentWithScopeOperator(Symbol, OS, *this); - OS << Symbol.getName(); +void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) { + dumpClassParentWithScopeOperator(Symbol, Printer, *this); + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } -void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol, - raw_ostream &OS, int Indent) { +void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) { // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill // through to the real thing and dump it. - Symbol.defaultDump(OS, Indent); uint32_t TypeId = Symbol.getTypeId(); auto Type = Symbol.getSession().getSymbolById(TypeId); if (!Type) return; - Type->dump(OS, 0, *this); + Type->dump(*this); } -void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) { - dumpClassParentWithScopeOperator(Symbol, OS, *this); - OS << Symbol.getName(); +void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + dumpClassParentWithScopeOperator(Symbol, Printer, *this); + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } -void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) { +void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) { uint32_t PointeeId = Symbol.getTypeId(); auto PointeeType = Symbol.getSession().getSymbolById(PointeeId); if (!PointeeType) return; if (auto FuncSig = dyn_cast(PointeeType.get())) { - FunctionDumper NestedDumper; + FunctionDumper NestedDumper(Printer); PointerType Pointer = Symbol.isReference() ? PointerType::Reference : PointerType::Pointer; - NestedDumper.start(*FuncSig, Pointer, OS); + NestedDumper.start(*FuncSig, nullptr, Pointer); } else { if (Symbol.isConstType()) - OS << "const "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; if (Symbol.isVolatileType()) - OS << "volatile "; - PointeeType->dump(OS, Indent, *this); - OS << (Symbol.isReference() ? "&" : "*"); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; + PointeeType->dump(*this); + Printer << (Symbol.isReference() ? "&" : "*"); } } -void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) { - OS << Symbol.getName(); +void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } diff --git a/tools/llvm-pdbdump/FunctionDumper.h b/tools/llvm-pdbdump/FunctionDumper.h index f9338cb..19a0014 100644 --- a/tools/llvm-pdbdump/FunctionDumper.h +++ b/tools/llvm-pdbdump/FunctionDumper.h @@ -14,31 +14,28 @@ namespace llvm { +class LinePrinter; + class FunctionDumper : public PDBSymDumper { public: - FunctionDumper(); + FunctionDumper(LinePrinter &P); enum class PointerType { None, Pointer, Reference }; - void start(const PDBSymbolTypeFunctionSig &Symbol, PointerType Pointer, - raw_ostream &OS); - void start(const PDBSymbolFunc &Symbol, PointerType Pointer, raw_ostream &OS, - int Indent); - - void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeFunctionArg &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) override; + void start(const PDBSymbolTypeFunctionSig &Symbol, const char *Name, + PointerType Pointer); + void start(const PDBSymbolFunc &Symbol, PointerType Pointer); + + void dump(const PDBSymbolTypeArray &Symbol) override; + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionArg &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + LinePrinter &Printer; }; } diff --git a/tools/llvm-pdbdump/LinePrinter.cpp b/tools/llvm-pdbdump/LinePrinter.cpp new file mode 100644 index 0000000..6bbc403 --- /dev/null +++ b/tools/llvm-pdbdump/LinePrinter.cpp @@ -0,0 +1,124 @@ +//===- LinePrinter.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LinePrinter.h" + +#include "llvm-pdbdump.h" + +#include "llvm/Support/Regex.h" + +#include + +using namespace llvm; + +LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream) + : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) { + SetFilters(TypeFilters, opts::ExcludeTypes.begin(), opts::ExcludeTypes.end()); + SetFilters(SymbolFilters, opts::ExcludeSymbols.begin(), + opts::ExcludeSymbols.end()); + SetFilters(CompilandFilters, opts::ExcludeCompilands.begin(), + opts::ExcludeCompilands.end()); +} + +void LinePrinter::Indent() { CurrentIndent += IndentSpaces; } + +void LinePrinter::Unindent() { + CurrentIndent = std::max(0, CurrentIndent - IndentSpaces); +} + +void LinePrinter::NewLine() { + OS << "\n"; + OS.indent(CurrentIndent); +} + +bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName) { + if (TypeName.empty()) + return false; + + for (auto &Expr : TypeFilters) { + if (Expr.match(TypeName)) + return true; + } + return false; +} + +bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { + if (SymbolName.empty()) + return false; + + for (auto &Expr : SymbolFilters) { + if (Expr.match(SymbolName)) + return true; + } + return false; +} + +bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) { + if (CompilandName.empty()) + return false; + + for (auto &Expr : CompilandFilters) { + if (Expr.match(CompilandName)) + return true; + } + return false; +} + +WithColor::WithColor(LinePrinter &P, PDB_ColorItem C) : OS(P.OS) { + if (C == PDB_ColorItem::None) + OS.resetColor(); + else { + raw_ostream::Colors Color; + bool Bold; + translateColor(C, Color, Bold); + OS.changeColor(Color, Bold); + } +} + +WithColor::~WithColor() { OS.resetColor(); } + +void WithColor::translateColor(PDB_ColorItem C, raw_ostream::Colors &Color, + bool &Bold) const { + switch (C) { + case PDB_ColorItem::Address: + Color = raw_ostream::YELLOW; + Bold = true; + return; + case PDB_ColorItem::Keyword: + Color = raw_ostream::MAGENTA; + Bold = true; + return; + case PDB_ColorItem::Register: + case PDB_ColorItem::Offset: + Color = raw_ostream::YELLOW; + Bold = false; + return; + case PDB_ColorItem::Type: + Color = raw_ostream::CYAN; + Bold = true; + return; + case PDB_ColorItem::Identifier: + Color = raw_ostream::CYAN; + Bold = false; + return; + case PDB_ColorItem::Path: + Color = raw_ostream::CYAN; + Bold = false; + return; + case PDB_ColorItem::SectionHeader: + Color = raw_ostream::RED; + Bold = true; + return; + case PDB_ColorItem::LiteralValue: + Color = raw_ostream::GREEN; + Bold = true; + default: + return; + } +} diff --git a/tools/llvm-pdbdump/LinePrinter.h b/tools/llvm-pdbdump/LinePrinter.h new file mode 100644 index 0000000..c2a3ab6 --- /dev/null +++ b/tools/llvm-pdbdump/LinePrinter.h @@ -0,0 +1,89 @@ +//===- LinePrinter.h ------------------------------------------ *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H +#define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Regex.h" + +#include + +namespace llvm { + +class LinePrinter { + friend class WithColor; + +public: + LinePrinter(int Indent, raw_ostream &Stream); + + void Indent(); + void Unindent(); + void NewLine(); + + raw_ostream &getStream() { return OS; } + int getIndentLevel() const { return CurrentIndent; } + + bool IsTypeExcluded(llvm::StringRef TypeName); + bool IsSymbolExcluded(llvm::StringRef SymbolName); + bool IsCompilandExcluded(llvm::StringRef CompilandName); + +private: + template + void SetFilters(std::list &List, Iter Begin, Iter End) { + List.clear(); + for (; Begin != End; ++Begin) + List.push_back(StringRef(*Begin)); + } + + raw_ostream &OS; + int IndentSpaces; + int CurrentIndent; + + std::list CompilandFilters; + std::list TypeFilters; + std::list SymbolFilters; +}; + +template +inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { + Printer.getStream() << Item; + return Printer.getStream(); +} + +enum class PDB_ColorItem { + None, + Address, + Type, + Keyword, + Offset, + Identifier, + Path, + SectionHeader, + LiteralValue, + Register, +}; + +class WithColor { +public: + WithColor(LinePrinter &P, PDB_ColorItem C); + ~WithColor(); + + raw_ostream &get() { return OS; } + +private: + void translateColor(PDB_ColorItem C, raw_ostream::Colors &Color, + bool &Bold) const; + raw_ostream &OS; +}; +} + +#endif diff --git a/tools/llvm-pdbdump/TypeDumper.cpp b/tools/llvm-pdbdump/TypeDumper.cpp index 3131e9f..88c0bd6 100644 --- a/tools/llvm-pdbdump/TypeDumper.cpp +++ b/tools/llvm-pdbdump/TypeDumper.cpp @@ -9,88 +9,89 @@ #include "TypeDumper.h" +#include "BuiltinDumper.h" #include "ClassDefinitionDumper.h" -#include "FunctionDumper.h" +#include "EnumDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "TypedefDumper.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" -#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" using namespace llvm; -TypeDumper::TypeDumper(bool Inline, bool ClassDefs) - : PDBSymDumper(true), InlineDump(Inline), FullClassDefs(ClassDefs) {} +TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} -void TypeDumper::start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent) { +void TypeDumper::start(const PDBSymbolExe &Exe) { auto Enums = Exe.findAllChildren(); - OS << newline(Indent) << "Enums: (" << Enums->getChildCount() << " items)"; + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums"; + Printer << ": (" << Enums->getChildCount() << " items)"; + Printer.Indent(); while (auto Enum = Enums->getNext()) - Enum->dump(OS, Indent + 2, *this); - - auto FuncSigs = Exe.findAllChildren(); - OS << newline(Indent); - OS << "Function Signatures: (" << FuncSigs->getChildCount() << " items)"; - while (auto Sig = FuncSigs->getNext()) - Sig->dump(OS, Indent + 2, *this); + Enum->dump(*this); + Printer.Unindent(); auto Typedefs = Exe.findAllChildren(); - OS << newline(Indent) << "Typedefs: (" << Typedefs->getChildCount() - << " items)"; + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs"; + Printer << ": (" << Typedefs->getChildCount() << " items)"; + Printer.Indent(); while (auto Typedef = Typedefs->getNext()) - Typedef->dump(OS, Indent + 2, *this); + Typedef->dump(*this); + Printer.Unindent(); auto Classes = Exe.findAllChildren(); - OS << newline(Indent) << "Classes: (" << Classes->getChildCount() - << " items)"; + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes"; + Printer << ": (" << Classes->getChildCount() << " items)"; + Printer.Indent(); while (auto Class = Classes->getNext()) - Class->dump(OS, Indent + 2, *this); + Class->dump(*this); + Printer.Unindent(); } -void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) { +void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) { if (Symbol.getUnmodifiedTypeId() != 0) return; + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + // Dump member enums when dumping their class definition. + if (Symbol.isNested()) + return; - if (!InlineDump) - OS << newline(Indent); - - OS << "enum " << Symbol.getName(); -} - -void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS, - int Indent) { - if (!InlineDump) - OS << newline(Indent); - - FunctionDumper Dumper; - Dumper.start(Symbol, FunctionDumper::PointerType::None, OS); + Printer.NewLine(); + EnumDumper Dumper(Printer); + Dumper.start(Symbol); } -void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) { - if (!InlineDump) - OS << newline(Indent); +void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; - TypedefDumper Dumper; - Dumper.start(Symbol, OS, Indent); + Printer.NewLine(); + TypedefDumper Dumper(Printer); + Dumper.start(Symbol); } -void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) { +void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) { if (Symbol.getUnmodifiedTypeId() != 0) return; - if (!InlineDump) - OS << newline(Indent); + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); - if (FullClassDefs) { - ClassDefinitionDumper Dumper; - Dumper.start(Symbol, OS, Indent); + if (opts::NoClassDefs) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "class "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } else { - OS << "class " << Symbol.getName(); + ClassDefinitionDumper Dumper(Printer); + Dumper.start(Symbol); } } diff --git a/tools/llvm-pdbdump/TypeDumper.h b/tools/llvm-pdbdump/TypeDumper.h index d96c24c..5c0832e 100644 --- a/tools/llvm-pdbdump/TypeDumper.h +++ b/tools/llvm-pdbdump/TypeDumper.h @@ -14,24 +14,20 @@ namespace llvm { +class LinePrinter; + class TypeDumper : public PDBSymDumper { public: - TypeDumper(bool Inline, bool ClassDefs); + TypeDumper(LinePrinter &P); - void start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent); + void start(const PDBSymbolExe &Exe); - void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; private: - bool InlineDump; - bool FullClassDefs; + LinePrinter &Printer; }; } diff --git a/tools/llvm-pdbdump/TypedefDumper.cpp b/tools/llvm-pdbdump/TypedefDumper.cpp index 6eea6b6..a6b5c53 100644 --- a/tools/llvm-pdbdump/TypedefDumper.cpp +++ b/tools/llvm-pdbdump/TypedefDumper.cpp @@ -9,12 +9,13 @@ #include "TypedefDumper.h" +#include "BuiltinDumper.h" #include "FunctionDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" -#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" @@ -23,39 +24,34 @@ using namespace llvm; -TypedefDumper::TypedefDumper() : PDBSymDumper(true) {} +TypedefDumper::TypedefDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} -void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) { - OS << "typedef "; +void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef "; uint32_t TargetId = Symbol.getTypeId(); if (auto TypeSymbol = Symbol.getSession().getSymbolById(TargetId)) - TypeSymbol->dump(OS, 0, *this); - OS << " " << Symbol.getName(); + TypeSymbol->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " + << Symbol.getName(); } -void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS, - int Indent) {} +void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol) {} -void TypedefDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) { - PDB_BuiltinType Type = Symbol.getBuiltinType(); - OS << Type; - if (Type == PDB_BuiltinType::UInt || Type == PDB_BuiltinType::Int) - OS << (8 * Symbol.getLength()) << "_t"; +void TypedefDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); } -void TypedefDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) { - OS << "enum " << Symbol.getName(); +void TypedefDumper::dump(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum "; + WithColor(Printer, PDB_ColorItem::Type).get() << " " << Symbol.getName(); } -void TypedefDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) { +void TypedefDumper::dump(const PDBSymbolTypePointer &Symbol) { if (Symbol.isConstType()) - OS << "const "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; if (Symbol.isVolatileType()) - OS << "volatile "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; uint32_t PointeeId = Symbol.getTypeId(); auto PointeeType = Symbol.getSession().getSymbolById(PointeeId); if (!PointeeType) @@ -64,21 +60,20 @@ void TypedefDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, FunctionDumper::PointerType Pointer = FunctionDumper::PointerType::Pointer; if (Symbol.isReference()) Pointer = FunctionDumper::PointerType::Reference; - FunctionDumper NestedDumper; - NestedDumper.start(*FuncSig, Pointer, OS); + FunctionDumper NestedDumper(Printer); + NestedDumper.start(*FuncSig, nullptr, Pointer); } else { - PointeeType->dump(OS, Indent, *this); - OS << ((Symbol.isReference()) ? "&" : "*"); + PointeeType->dump(*this); + Printer << ((Symbol.isReference()) ? "&" : "*"); } } -void TypedefDumper::dump(const PDBSymbolTypeFunctionSig &Symbol, - raw_ostream &OS, int Indent) { - FunctionDumper Dumper; - Dumper.start(Symbol, FunctionDumper::PointerType::None, OS); +void TypedefDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) { + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, nullptr, FunctionDumper::PointerType::None); } -void TypedefDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) { - OS << "class " << Symbol.getName(); +void TypedefDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "class "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } diff --git a/tools/llvm-pdbdump/TypedefDumper.h b/tools/llvm-pdbdump/TypedefDumper.h index e6211a8..8cd578c 100644 --- a/tools/llvm-pdbdump/TypedefDumper.h +++ b/tools/llvm-pdbdump/TypedefDumper.h @@ -14,24 +14,23 @@ namespace llvm { +class LinePrinter; + class TypedefDumper : public PDBSymDumper { public: - TypedefDumper(); - - void start(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, int Indent); - - void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) override; + TypedefDumper(LinePrinter &P); + + void start(const PDBSymbolTypeTypedef &Symbol); + + void dump(const PDBSymbolTypeArray &Symbol) override; + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionSig &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + LinePrinter &Printer; }; } diff --git a/tools/llvm-pdbdump/VariableDumper.cpp b/tools/llvm-pdbdump/VariableDumper.cpp index 913cfee..030610c 100644 --- a/tools/llvm-pdbdump/VariableDumper.cpp +++ b/tools/llvm-pdbdump/VariableDumper.cpp @@ -9,13 +9,16 @@ #include "VariableDumper.h" +#include "BuiltinDumper.h" +#include "LinePrinter.h" #include "llvm-pdbdump.h" #include "FunctionDumper.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" -#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" @@ -25,96 +28,143 @@ using namespace llvm; -VariableDumper::VariableDumper() : PDBSymDumper(true) {} +VariableDumper::VariableDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} -void VariableDumper::start(const PDBSymbolData &Var, raw_ostream &OS, - int Indent) { - OS << newline(Indent); - OS << "data "; +void VariableDumper::start(const PDBSymbolData &Var) { + if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated) + return; + if (Printer.IsSymbolExcluded(Var.getName())) + return; auto VarType = Var.getType(); switch (auto LocType = Var.getLocationType()) { case PDB_LocType::Static: - OS << "[" << format_hex(Var.getRelativeVirtualAddress(), 10) << "] "; - OS << "static "; - dumpSymbolTypeAndName(*VarType, Var.getName(), OS); + Printer.NewLine(); + Printer << "data ["; + WithColor(Printer, PDB_ColorItem::Address).get() + << format_hex(Var.getRelativeVirtualAddress(), 10); + Printer << "] "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "static "; + dumpSymbolTypeAndName(*VarType, Var.getName()); break; case PDB_LocType::Constant: - OS << "const "; - dumpSymbolTypeAndName(*VarType, Var.getName(), OS); - OS << "[" << Var.getValue() << "]"; + if (isa(*VarType)) + break; + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + Printer << " = "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue(); break; case PDB_LocType::ThisRel: - OS << "+" << format_hex(Var.getOffset(), 4) << " "; - dumpSymbolTypeAndName(*VarType, Var.getName(), OS); + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Offset).get() + << "+" << format_hex(Var.getOffset(), 4) << " "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + break; + case PDB_LocType::BitField: + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Offset).get() + << "+" << format_hex(Var.getOffset(), 4) << " "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + Printer << " : "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength(); break; default: + Printer.NewLine(); + Printer << "data "; + Printer << "unknown(" << LocType << ") "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName(); break; - OS << "unknown(" << LocType << ") " << Var.getName(); } } -void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) { - OS << Symbol.getBuiltinType(); +void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); } -void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) { - OS << Symbol.getName(); +void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } -void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol, - raw_ostream &OS, int Indent) {} +void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {} -void VariableDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) { +void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) { auto PointeeType = Symbol.getPointeeType(); if (!PointeeType) return; if (auto Func = dyn_cast(PointeeType.get())) { - FunctionDumper NestedDumper; + FunctionDumper NestedDumper(Printer); FunctionDumper::PointerType Pointer = Symbol.isReference() ? FunctionDumper::PointerType::Reference : FunctionDumper::PointerType::Pointer; - NestedDumper.start(*Func, Pointer, OS, Indent); + NestedDumper.start(*Func, Pointer); } else { if (Symbol.isConstType()) - OS << "const "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; if (Symbol.isVolatileType()) - OS << "volatile "; - PointeeType->dump(OS, Indent, *this); - OS << (Symbol.isReference() ? "&" : "*"); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; + PointeeType->dump(*this); + Printer << (Symbol.isReference() ? "&" : "*"); } } -void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) { - OS << "typedef " << Symbol.getName(); +void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } -void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) { - OS << Symbol.getName(); +void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type, - StringRef Name, raw_ostream &OS) { + StringRef Name) { if (auto *ArrayType = dyn_cast(&Type)) { std::string IndexSpec; raw_string_ostream IndexStream(IndexSpec); std::unique_ptr ElementType = ArrayType->getElementType(); while (auto NestedArray = dyn_cast(ElementType.get())) { - IndexStream << "[" << NestedArray->getCount() << "]"; + IndexStream << "["; + IndexStream << NestedArray->getCount(); + IndexStream << "]"; ElementType = NestedArray->getElementType(); } IndexStream << "[" << ArrayType->getCount() << "]"; - ElementType->dump(OS, 0, *this); - OS << " " << Name << IndexStream.str(); + ElementType->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; + Printer << IndexStream.str(); } else { - Type.dump(OS, 0, *this); - OS << " " << Name; + if (!tryDumpFunctionPointer(Type, Name)) { + Type.dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; + } + } +} + +bool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type, + StringRef Name) { + // Function pointers come across as pointers to function signatures. But the + // signature carries no name, so we have to handle this case separately. + if (auto *PointerType = dyn_cast(&Type)) { + auto PointeeType = PointerType->getPointeeType(); + if (auto *FunctionSig = + dyn_cast(PointeeType.get())) { + FunctionDumper Dumper(Printer); + FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer; + if (PointerType->isReference()) + PT = FunctionDumper::PointerType::Reference; + std::string NameStr(Name.begin(), Name.end()); + Dumper.start(*FunctionSig, NameStr.c_str(), PT); + return true; + } } + return false; } diff --git a/tools/llvm-pdbdump/VariableDumper.h b/tools/llvm-pdbdump/VariableDumper.h index e6e71fa..db8d8ea 100644 --- a/tools/llvm-pdbdump/VariableDumper.h +++ b/tools/llvm-pdbdump/VariableDumper.h @@ -15,28 +15,26 @@ namespace llvm { +class LinePrinter; + class VariableDumper : public PDBSymDumper { public: - VariableDumper(); - - void start(const PDBSymbolData &Var, raw_ostream &OS, int Indent); - - void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent) override; - void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent) override; + VariableDumper(LinePrinter &P); + + void start(const PDBSymbolData &Var); + + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionSig &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; private: - void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name, - raw_ostream &OS); + void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name); + bool tryDumpFunctionPointer(const PDBSymbol &Type, StringRef Name); + + LinePrinter &Printer; }; } diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index e33e715..78535ec 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -15,7 +15,10 @@ #include "llvm-pdbdump.h" #include "CompilandDumper.h" +#include "FunctionDumper.h" +#include "LinePrinter.h" #include "TypeDumper.h" +#include "VariableDumper.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" @@ -25,7 +28,10 @@ #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/FileSystem.h" @@ -50,53 +56,164 @@ cl::list InputFilenames(cl::Positional, cl::desc(""), cl::OneOrMore); -cl::opt DumpCompilands("compilands", cl::desc("Display compilands")); -cl::opt DumpSymbols("symbols", - cl::desc("Display symbols (implies --compilands")); -cl::opt DumpTypes("types", cl::desc("Display types")); -cl::opt DumpClassDefs("class-definitions", - cl::desc("Display full class definitions")); +cl::OptionCategory TypeCategory("Symbol Type Options"); +cl::OptionCategory FilterCategory("Filtering Options"); + +cl::opt Compilands("compilands", cl::desc("Display compilands"), + cl::cat(TypeCategory)); +cl::opt Symbols("symbols", cl::desc("Display symbols for each compiland"), + cl::cat(TypeCategory)); +cl::opt Globals("globals", cl::desc("Dump global symbols"), + cl::cat(TypeCategory)); +cl::opt Types("types", cl::desc("Display types"), cl::cat(TypeCategory)); +cl::opt + All("all", cl::desc("Implies all other options in 'Symbol Types' category"), + cl::cat(TypeCategory)); + +cl::list + ExcludeTypes("exclude-types", + cl::desc("Exclude types by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list + ExcludeSymbols("exclude-symbols", + cl::desc("Exclude symbols by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list + ExcludeCompilands("exclude-compilands", + cl::desc("Exclude compilands by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::opt ExcludeCompilerGenerated( + "no-compiler-generated", + cl::desc("Don't show compiler generated types and symbols"), + cl::cat(FilterCategory)); +cl::opt + ExcludeSystemLibraries("no-system-libs", + cl::desc("Don't show symbols from system libraries"), + cl::cat(FilterCategory)); +cl::opt NoClassDefs("no-class-definitions", + cl::desc("Don't display full class definitions"), + cl::cat(FilterCategory)); +cl::opt NoEnumDefs("no-enum-definitions", + cl::desc("Don't display full enum definitions"), + cl::cat(FilterCategory)); } static void dumpInput(StringRef Path) { - std::unique_ptr 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 Session; + PDB_ErrorCode Error = + llvm::createPDBReader(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; } + 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) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() + << "---COMPILANDS---"; + Printer.Indent(); + auto Compilands = GlobalScope->findAllChildren(); + CompilandDumper Dumper(Printer); + while (auto Compiland = Compilands->getNext()) + Dumper.start(*Compiland, false); + Printer.Unindent(); + } - if (opts::DumpTypes) { - outs() << "\nDumping types"; - TypeDumper Dumper(false, opts::DumpClassDefs); - Dumper.start(*GlobalScope, outs(), 2); + if (opts::Types) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; + Printer.Indent(); + TypeDumper Dumper(Printer); + Dumper.start(*GlobalScope); + Printer.Unindent(); } - if (opts::DumpSymbols || opts::DumpCompilands) { - outs() << "\nDumping compilands"; + if (opts::Symbols) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---"; + Printer.Indent(); auto Compilands = GlobalScope->findAllChildren(); - CompilandDumper Dumper; + CompilandDumper Dumper(Printer); while (auto Compiland = Compilands->getNext()) - Dumper.start(*Compiland, outs(), 2, opts::DumpSymbols); + Dumper.start(*Compiland, true); + Printer.Unindent(); + } + + if (opts::Globals) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---"; + Printer.Indent(); + { + FunctionDumper Dumper(Printer); + auto Functions = GlobalScope->findAllChildren(); + while (auto Function = Functions->getNext()) { + Printer.NewLine(); + Dumper.start(*Function, FunctionDumper::PointerType::None); + } + } + { + auto Vars = GlobalScope->findAllChildren(); + VariableDumper Dumper(Printer); + while (auto Var = Vars->getNext()) + Dumper.start(*Var); + } + { + auto Thunks = GlobalScope->findAllChildren(); + CompilandDumper Dumper(Printer); + while (auto Thunk = Thunks->getNext()) + Dumper.dump(*Thunk); + } + Printer.Unindent(); } outs().flush(); } @@ -118,6 +235,20 @@ 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; + } + 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); diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index 74a1718..586a9ea 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -10,19 +10,23 @@ #ifndef LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H #define LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H +#include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" -namespace llvm { -struct newline { - newline(int IndentWidth) : Width(IndentWidth) {} - int Width; -}; +namespace opts { +extern llvm::cl::opt Compilands; +extern llvm::cl::opt Symbols; +extern llvm::cl::opt Globals; +extern llvm::cl::opt Types; +extern llvm::cl::opt All; -inline raw_ostream &operator<<(raw_ostream &OS, const newline &Indent) { - OS << "\n"; - OS.indent(Indent.Width); - return OS; -} +extern llvm::cl::opt ExcludeCompilerGenerated; + +extern llvm::cl::opt NoClassDefs; +extern llvm::cl::opt NoEnumDefs; +extern llvm::cl::list ExcludeTypes; +extern llvm::cl::list ExcludeSymbols; +extern llvm::cl::list ExcludeCompilands; } #endif \ No newline at end of file -- cgit v1.1