--- /dev/null
+; RUN: llvm-pdbdump -lines %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=LINE_NUMS %s
+
+; LINE_NUMS: llvm\test\debuginfo\pdb\inputs\symbolformat-fpo.cpp
+; LINE_NUMS: Line 5, Address: [0x000011a0 - 0x000011a5] (6 bytes)
+; LINE_NUMS: Line 6, Address: [0x000011a6 - 0x000011a6] (1 bytes)
+; LINE_NUMS: llvm\test\debuginfo\pdb\inputs\symbolformat.cpp
+; LINE_NUMS: Line 6, Address: [0x00001060 - 0x00001066] (7 bytes)
+; LINE_NUMS: Line 72, Address: [0x000010d0 - 0x000010d1] (2 bytes)
+; LINE_NUMS: Line 73, Address: [0x000010d2 - 0x000010d5] (4 bytes)
+; LINE_NUMS: Line 28, Address: [0x00001170 - 0x0000117a] (11 bytes)
+; LINE_NUMS: Line 21, Address: [0x00001180 - 0x0000118a] (11 bytes)
+; LINE_NUMS: Line 20, Address: [0x00001190 - 0x0000119a] (11 bytes)
\ No newline at end of file
#include "llvm-pdbdump.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {}
-void CompilandDumper::start(const PDBSymbolCompiland &Symbol, bool Children) {
+void CompilandDumper::start(const PDBSymbolCompiland &Symbol,
+ CompilandDumpFlags opts) {
std::string FullName = Symbol.getName();
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(*this);
- Printer.Unindent();
+ if (opts & Flags::Lines) {
+ const IPDBSession &Session = Symbol.getSession();
+ auto Files = Session.getSourceFilesForCompiland(Symbol);
+ Printer.Indent();
+ while (auto File = Files->getNext()) {
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Path).get() << File->getFileName();
+
+ auto Lines = Session.findLineNumbers(Symbol, *File);
+ Printer.Indent();
+ while (auto Line = Lines->getNext()) {
+ Printer.NewLine();
+ uint32_t LineStart = Line->getLineNumber();
+ uint32_t LineEnd = Line->getLineNumberEnd();
+
+ Printer << "Line ";
+ PDB_ColorItem StatementColor = Line->isStatement()
+ ? PDB_ColorItem::Keyword
+ : PDB_ColorItem::LiteralValue;
+ WithColor(Printer, StatementColor).get() << LineStart;
+ if (LineStart != LineEnd)
+ WithColor(Printer, StatementColor).get() << " - " << LineEnd;
+
+ Printer << ", Address: ";
+ if (Line->getLength() > 0) {
+ uint64_t AddrStart = Line->getVirtualAddress();
+ uint64_t AddrEnd = AddrStart + Line->getLength() - 1;
+ WithColor(Printer, PDB_ColorItem::Address).get()
+ << "[" << format_hex(AddrStart, 10) << " - "
+ << format_hex(AddrEnd, 10) << "]";
+ Printer << " (" << Line->getLength() << " bytes)";
+ } else {
+ uint64_t AddrStart = Line->getVirtualAddress();
+ WithColor(Printer, PDB_ColorItem::Address).get()
+ << "[" << format_hex(AddrStart, 10) << "] ";
+ Printer << "(0 bytes)";
+ }
+ }
+ Printer.Unindent();
+ }
+ Printer.Unindent();
+ }
+
+ if (opts & Flags::Children) {
+ auto ChildrenEnum = Symbol.findAllChildren();
+ Printer.Indent();
+ while (auto Child = ChildrenEnum->getNext())
+ Child->dump(*this);
+ Printer.Unindent();
+ }
}
void CompilandDumper::dump(const PDBSymbolData &Symbol) {
class LinePrinter;
+typedef int CompilandDumpFlags;
class CompilandDumper : public PDBSymDumper {
public:
+ enum Flags { None = 0x0, Children = 0x1, Symbols = 0x2, Lines = 0x4 };
+
CompilandDumper(LinePrinter &P);
- void start(const PDBSymbolCompiland &Symbol, bool Children);
+ void start(const PDBSymbolCompiland &Symbol, CompilandDumpFlags flags);
void dump(const PDBSymbolCompilandDetails &Symbol) override;
void dump(const PDBSymbolCompilandEnv &Symbol) override;
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> Lines("lines", cl::desc("Line tables"), cl::cat(TypeCategory));
cl::opt<bool>
All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
cl::cat(TypeCategory));
Printer.Indent();
auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
CompilandDumper Dumper(Printer);
+ CompilandDumpFlags options = CompilandDumper::Flags::None;
+ if (opts::Lines)
+ options = options | CompilandDumper::Flags::Lines;
while (auto Compiland = Compilands->getNext())
- Dumper.start(*Compiland, false);
+ Dumper.start(*Compiland, options);
Printer.Unindent();
}
ExternalSymbolDumper Dumper(Printer);
Dumper.start(*GlobalScope);
}
+ if (opts::Lines) {
+ Printer.NewLine();
+ }
outs().flush();
}
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
+ if (opts::Lines)
+ opts::Compilands = true;
+
if (opts::All) {
opts::Compilands = true;
opts::Symbols = true;
opts::Globals = true;
opts::Types = true;
opts::Externals = true;
+ opts::Lines = true;
}
+
+ // When adding filters for excluded compilands and types, we need to remember
+ // that these are regexes. So special characters such as * and \ need to be
+ // escaped in the regex. In the case of a literal \, this means it needs to
+ // be escaped again in the C++. So matching a single \ in the input requires
+ // 4 \es in the C++.
if (opts::ExcludeCompilerGenerated) {
opts::ExcludeTypes.push_back("__vc_attributes");
- opts::ExcludeCompilands.push_back("* Linker *");
+ opts::ExcludeCompilands.push_back("\\* Linker \\*");
}
if (opts::ExcludeSystemLibraries) {
opts::ExcludeCompilands.push_back(
- "f:\\binaries\\Intermediate\\vctools\\crt_bld");
+ "f:\\\\binaries\\\\Intermediate\\\\vctools\\\\crt_bld");
+ opts::ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt");
+ opts::ExcludeCompilands.push_back("d:\\\\th.obj.x86fre\\\\minkernel");
}
#if defined(HAVE_DIA_SDK)