Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -410,6 +410,7 @@ // Add an Info stream. auto &InfoBuilder = Builder.getInfoBuilder(); InfoBuilder.setAge(DI ? DI->PDB70.Age : 0); + InfoBuilder.setSignature(time(nullptr)); llvm::SmallString<128> NativePath(Path.begin(), Path.end()); llvm::sys::fs::make_absolute(NativePath); @@ -425,7 +426,7 @@ // Add an empty DBI stream. pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - DbiBuilder.setVersionHeader(pdb::PdbDbiV110); + DbiBuilder.setVersionHeader(pdb::PdbDbiV70); // It's not entirely clear what this is, but the * Linker * module uses it. uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); Index: lld/trunk/test/COFF/Inputs/pdb-diff.cpp =================================================================== --- lld/trunk/test/COFF/Inputs/pdb-diff.cpp +++ lld/trunk/test/COFF/Inputs/pdb-diff.cpp @@ -0,0 +1,10 @@ +// Build with cl: +// cl.exe /Z7 pdb-diff.cpp /link /debug /pdb:pdb-diff-cl.pdb +// /nodefaultlib /entry:main +// Build with lld (after running the above cl command): +// lld-link.exe /debug /pdb:pdb-diff-lld.pdb /nodefaultlib +// /entry:main pdb-diff.obj + +void *__purecall = 0; + +int main() { return 42; } Index: lld/trunk/test/COFF/pdb-diff.test =================================================================== --- lld/trunk/test/COFF/pdb-diff.test +++ lld/trunk/test/COFF/pdb-diff.test @@ -0,0 +1,200 @@ +This test verifies that we produce PDBs compatible with MSVC in various ways. +We check in a cl-generated object file, PDB, and original source which serve +as the "baseline" for us to measure against. Then we link the same object +file with LLD and compare the two PDBs. Since the baseline object file and +PDB are already checked in, we just run LLD on the object file. + +RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj +RUN: llvm-pdbutil diff -result -values=false %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s + +CHECK: ---------------------- +CHECK-NEXT: | MSF Super Block | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: | File | | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: | Block Size | I | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: | Block Count | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: | Unknown 1 | I | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: | Directory Size | +CHECK-NEXT: |----------------+---| +CHECK-NEXT: ------------------------------------ +CHECK-NEXT: | Stream Directory | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | File | | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Stream Count | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Old MSF Directory | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | PDB Stream | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | TPI Stream | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | DBI Stream | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | IPI Stream | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Section Header Data | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Named Stream "/names" | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Named Stream "/LinkInfo" | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Named Stream "/src/heade..." | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Module "{{.*}}pdb-diff.obj" | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Module "* Linker *" | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | TPI Hash | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | IPI Hash | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Global Symbol Hash | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Public Symbol Hash | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Public Symbol Records | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Module "{{.*}}pdb-diff.obj" | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | New FPO Data | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: ------------------------------------ +CHECK-NEXT: | String Table | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | File | | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Number of Strings | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Hash Version | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Byte Size | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Signature | I | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | Empty Strings | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | {{.*}}pdb-diff.cpp | {{[EI]}} | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | $T0 $ebp = $...p $T0 8 + = | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: | d:\src\llvm-...er internal) | D | +CHECK-NEXT: |------------------------------+---| +CHECK-NEXT: ---------------------------- +CHECK-NEXT: | PDB Stream | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | File | | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Stream Size | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Age | I | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Guid | D | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Signature | D | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Version | I | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Features (set) | I | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Feature | I | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Named Stream Size | D | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | Named Streams (map) | D | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | /names | I | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | /LinkInfo | E | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: | /src/headerblock | D | +CHECK-NEXT: |----------------------+---| +CHECK-NEXT: ---------------------------------------------- +CHECK-NEXT: | DBI Stream | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | File | | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Dbi Version | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Age | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Machine | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Flags | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Build Major | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Build Minor | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Build Number | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | PDB DLL Version | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | PDB DLL RBLD | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (FPO) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (Exception) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (Fixup) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (OmapToSrc) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (OmapFromSrc) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (SectionHdr) | {{[EI]}} | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (TokenRidMap) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (Xdata) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (Pdata) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (NewFPO) | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | DBG (SectionHdrOrig) | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Globals Stream | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Publics Stream | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Symbol Records | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Has CTypes | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Is Incrementally Linked | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Is Stripped | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Module Count | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Source File Count | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: |Module "{{.*}}Inputs/pdb-diff.obj"| +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Modi | D | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | Module "* Linker *" | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Modi | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Obj File Name | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Debug Stream | {{[EI]}} | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - C11 Byte Size | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - C13 Byte Size | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - # of files | I | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Pdb File Path Index | {{[EI]}} | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Source File Name Index | {{[EI]}} | +CHECK-NEXT: |----------------------------------------+---| +CHECK-NEXT: | - Symbol Byte Size | D | +CHECK-NEXT: |----------------------------------------+---| Index: lld/trunk/test/COFF/pdb-source-lines.test =================================================================== --- lld/trunk/test/COFF/pdb-source-lines.test +++ lld/trunk/test/COFF/pdb-source-lines.test @@ -23,7 +23,7 @@ RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s CHECK-LABEL: DbiStream: -CHECK-NEXT: VerHeader: V110 +CHECK-NEXT: VerHeader: V70 CHECK-NEXT: Age: 1 CHECK-NEXT: BuildNumber: 0 CHECK-NEXT: PdbDllVersion: 0 Index: lld/trunk/test/COFF/pdb.test =================================================================== --- lld/trunk/test/COFF/pdb.test +++ lld/trunk/test/COFF/pdb.test @@ -30,7 +30,7 @@ # CHECK-NEXT: Features: [ VC140 ] # CHECK-NEXT: Version: VC70 # CHECK-NEXT: DbiStream: -# CHECK-NEXT: VerHeader: V110 +# CHECK-NEXT: VerHeader: V70 # CHECK-NEXT: Age: 1 # CHECK-NEXT: BuildNumber: 0 # CHECK-NEXT: PdbDllVersion: 0 Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -78,7 +78,7 @@ private: struct DebugStream { ArrayRef Data; - uint16_t StreamNumber = 0; + uint16_t StreamNumber = kInvalidStreamIndex; }; Error finalize(); Index: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -252,6 +252,9 @@ return Error::success(); uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr); + if (StreamNum == kInvalidStreamIndex) + return Error::success(); + if (StreamNum >= Pdb.getNumStreams()) return make_error(raw_error_code::no_stream); Index: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -51,7 +51,7 @@ Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type, ArrayRef Data) { - if (DbgStreams[(int)Type].StreamNumber) + if (DbgStreams[(int)Type].StreamNumber != kInvalidStreamIndex) return make_error(raw_error_code::duplicate_entry, "The specified stream type already exists"); auto ExpectedIndex = Msf.addStream(Data.size()); Index: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp @@ -385,8 +385,11 @@ bool PDBFile::hasPDBGlobalsStream() { auto DbiS = getPDBDbiStream(); - if (!DbiS) + if (!DbiS) { + consumeError(DbiS.takeError()); return false; + } + return DbiS->getGlobalSymbolStreamIndex() < getNumStreams(); } @@ -396,8 +399,10 @@ bool PDBFile::hasPDBPublicsStream() { auto DbiS = getPDBDbiStream(); - if (!DbiS) + if (!DbiS) { + consumeError(DbiS.takeError()); return false; + } return DbiS->getPublicSymbolStreamIndex() < getNumStreams(); } Index: llvm/trunk/tools/llvm-pdbutil/Diff.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/Diff.cpp +++ llvm/trunk/tools/llvm-pdbutil/Diff.cpp @@ -108,7 +108,8 @@ } Error DiffStyle::diffSuperBlock() { - DiffPrinter D(2, "MSF Super Block", 16, 20, outs()); + DiffPrinter D(2, "MSF Super Block", 16, 20, opts::diff::PrintResultColumn, + opts::diff::PrintValueColumns, outs()); D.printExplicit("File", DiffResult::UNSPECIFIED, shortFilePath(File1.getFilePath(), 18), shortFilePath(File2.getFilePath(), 18)); @@ -121,7 +122,8 @@ } Error DiffStyle::diffStreamDirectory() { - DiffPrinter D(2, "Stream Directory", 30, 20, outs()); + DiffPrinter D(2, "Stream Directory", 30, 20, opts::diff::PrintResultColumn, + opts::diff::PrintValueColumns, outs()); D.printExplicit("File", DiffResult::UNSPECIFIED, shortFilePath(File1.getFilePath(), 18), shortFilePath(File2.getFilePath(), 18)); @@ -163,7 +165,8 @@ } Error DiffStyle::diffStringTable() { - DiffPrinter D(2, "String Table", 30, 20, outs()); + DiffPrinter D(2, "String Table", 30, 20, opts::diff::PrintResultColumn, + opts::diff::PrintValueColumns, outs()); D.printExplicit("File", DiffResult::UNSPECIFIED, shortFilePath(File1.getFilePath(), 18), shortFilePath(File2.getFilePath(), 18)); @@ -251,7 +254,8 @@ Error DiffStyle::diffFreePageMap() { return Error::success(); } Error DiffStyle::diffInfoStream() { - DiffPrinter D(2, "PDB Stream", 22, 40, outs()); + DiffPrinter D(2, "PDB Stream", 22, 40, opts::diff::PrintResultColumn, + opts::diff::PrintValueColumns, outs()); D.printExplicit("File", DiffResult::UNSPECIFIED, shortFilePath(File1.getFilePath(), 38), shortFilePath(File2.getFilePath(), 38)); @@ -345,10 +349,11 @@ } Error DiffStyle::diffDbiStream() { - DiffPrinter D(2, "DBI Stream", 40, 30, outs()); + DiffPrinter D(2, "DBI Stream", 40, 30, opts::diff::PrintResultColumn, + opts::diff::PrintValueColumns, outs()); D.printExplicit("File", DiffResult::UNSPECIFIED, - shortFilePath(File1.getFilePath(), 38), - shortFilePath(File2.getFilePath(), 38)); + shortFilePath(File1.getFilePath(), 28), + shortFilePath(File2.getFilePath(), 28)); auto ExpectedDbi1 = File1.getPDBDbiStream(); auto ExpectedDbi2 = File2.getPDBDbiStream(); Index: llvm/trunk/tools/llvm-pdbutil/DiffPrinter.h =================================================================== --- llvm/trunk/tools/llvm-pdbutil/DiffPrinter.h +++ llvm/trunk/tools/llvm-pdbutil/DiffPrinter.h @@ -51,7 +51,8 @@ class DiffPrinter { public: DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth, - uint32_t FieldWidth, raw_ostream &Stream); + uint32_t FieldWidth, bool Result, bool Values, + raw_ostream &Stream); ~DiffPrinter(); template struct Identical {}; @@ -138,15 +139,17 @@ void printFullRow(StringRef Text); private: - void printSame(StringRef Property, StringRef Value); - void printDifferent(StringRef Property, StringRef Left, StringRef Right); + uint32_t tableWidth() const; void printHeaderRow(); void printSeparatorRow(); void newLine(char InitialChar = '|'); - void printField(StringRef Value, DiffResult C, AlignStyle Style, - uint32_t Width); + void printValue(StringRef Value, DiffResult C, AlignStyle Style, + uint32_t Width, bool Force); + void printResult(DiffResult Result); + bool PrintResult; + bool PrintValues; uint32_t Indent; uint32_t PropertyWidth; uint32_t FieldWidth; Index: llvm/trunk/tools/llvm-pdbutil/DiffPrinter.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/DiffPrinter.cpp +++ llvm/trunk/tools/llvm-pdbutil/DiffPrinter.cpp @@ -22,35 +22,60 @@ DiffPrinter::DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth, uint32_t FieldWidth, - raw_ostream &Stream) - : Indent(Indent), PropertyWidth(PropertyWidth), FieldWidth(FieldWidth), - OS(Stream) { + bool Result, bool Fields, raw_ostream &Stream) + : PrintResult(Result), PrintValues(Fields), Indent(Indent), + PropertyWidth(PropertyWidth), FieldWidth(FieldWidth), OS(Stream) { printHeaderRow(); printFullRow(Header); } DiffPrinter::~DiffPrinter() {} +uint32_t DiffPrinter::tableWidth() const { + // `|` + uint32_t W = 1; + + // `|` + W += PropertyWidth + 1; + + if (PrintResult) { + // ` I |` + W += 4; + } + + if (PrintValues) { + // `||` + W += 2 * (FieldWidth + 1); + } + return W; +} + void DiffPrinter::printFullRow(StringRef Text) { newLine(); - printField(Text, DiffResult::UNSPECIFIED, AlignStyle::Center, - PropertyWidth + 1 + FieldWidth + 1 + FieldWidth); + printValue(Text, DiffResult::UNSPECIFIED, AlignStyle::Center, + tableWidth() - 2, true); printSeparatorRow(); } void DiffPrinter::printSeparatorRow() { newLine(); OS << formatv("{0}", fmt_repeat('-', PropertyWidth)); - OS << '+'; - OS << formatv("{0}", fmt_repeat('-', FieldWidth)); - OS << '+'; - OS << formatv("{0}", fmt_repeat('-', FieldWidth)); + if (PrintResult) { + OS << '+'; + OS << formatv("{0}", fmt_repeat('-', 3)); + } + if (PrintValues) { + OS << '+'; + OS << formatv("{0}", fmt_repeat('-', FieldWidth)); + OS << '+'; + OS << formatv("{0}", fmt_repeat('-', FieldWidth)); + } OS << '|'; } void DiffPrinter::printHeaderRow() { newLine('-'); - OS << formatv("{0}", fmt_repeat('-', PropertyWidth + 2 * FieldWidth + 3)); + OS << formatv("{0}", fmt_repeat('-', tableWidth() - 1)); } void DiffPrinter::newLine(char InitialChar) { @@ -61,34 +86,40 @@ void DiffPrinter::printExplicit(StringRef Property, DiffResult C, StringRef Left, StringRef Right) { newLine(); - printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right, - PropertyWidth); - printField(Left, C, AlignStyle::Center, FieldWidth); - printField(Right, C, AlignStyle::Center, FieldWidth); + printValue(Property, DiffResult::UNSPECIFIED, AlignStyle::Right, + PropertyWidth, true); + printResult(C); + printValue(Left, C, AlignStyle::Center, FieldWidth, false); + printValue(Right, C, AlignStyle::Center, FieldWidth, false); printSeparatorRow(); } -void DiffPrinter::printSame(StringRef Property, StringRef Value) { - newLine(); - printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right, - PropertyWidth); - printField(Value, DiffResult::IDENTICAL, AlignStyle::Center, - FieldWidth + 1 + FieldWidth); - printSeparatorRow(); +void DiffPrinter::printResult(DiffResult Result) { + if (!PrintResult) + return; + switch (Result) { + case DiffResult::DIFFERENT: + printValue("D", Result, AlignStyle::Center, 3, true); + break; + case DiffResult::EQUIVALENT: + printValue("E", Result, AlignStyle::Center, 3, true); + break; + case DiffResult::IDENTICAL: + printValue("I", Result, AlignStyle::Center, 3, true); + break; + case DiffResult::UNSPECIFIED: + printValue(" ", Result, AlignStyle::Center, 3, true); + break; + default: + llvm_unreachable("unreachable!"); + } } -void DiffPrinter::printDifferent(StringRef Property, StringRef Left, - StringRef Right) { - newLine(); - printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right, - PropertyWidth); - printField(Left, DiffResult::DIFFERENT, AlignStyle::Center, FieldWidth); - printField(Right, DiffResult::DIFFERENT, AlignStyle::Center, FieldWidth); - printSeparatorRow(); -} +void DiffPrinter::printValue(StringRef Value, DiffResult C, AlignStyle Style, + uint32_t Width, bool Force) { + if (!Force && !PrintValues) + return; -void DiffPrinter::printField(StringRef Value, DiffResult C, AlignStyle Style, - uint32_t Width) { if (Style == AlignStyle::Right) --Width; Index: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h =================================================================== --- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h +++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h @@ -168,6 +168,11 @@ extern llvm::cl::list DumpModuleSubsections; extern llvm::cl::opt DumpModuleSyms; } // namespace pdb2yaml + +namespace diff { +extern llvm::cl::opt PrintValueColumns; +extern llvm::cl::opt PrintResultColumn; +} // namespace diff } #endif Index: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -284,6 +284,15 @@ } namespace diff { +cl::opt PrintValueColumns( + "values", cl::init(true), + cl::desc("Print one column for each PDB with the field value"), + cl::Optional, cl::sub(DiffSubcommand)); +cl::opt + PrintResultColumn("result", cl::init(false), + cl::desc("Print a column with the result status"), + cl::Optional, cl::sub(DiffSubcommand)); + cl::list InputFilenames(cl::Positional, cl::desc(" "), cl::OneOrMore, cl::sub(DiffSubcommand)); @@ -1079,6 +1088,11 @@ if (opts::pdb2yaml::DumpModules) opts::pdb2yaml::DbiStream = true; } + if (opts::DiffSubcommand) { + if (!opts::diff::PrintResultColumn && !opts::diff::PrintValueColumns) { + llvm::errs() << "WARNING: No diff columns specified\n"; + } + } llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);