<div dir="ltr">Test coverage?</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Mar 15, 2017 at 3:31 PM Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br class="gmail_msg">
Date: Wed Mar 15 17:19:30 2017<br class="gmail_msg">
New Revision: 297901<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=297901&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=297901&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
[llvm-pdbdump] Add support for diffing the String Table.<br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h<br class="gmail_msg">
    llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp<br class="gmail_msg">
    llvm/trunk/tools/llvm-pdbdump/Diff.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h?rev=297901&r1=297900&r2=297901&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h?rev=297901&r1=297900&r2=297901&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h Wed Mar 15 17:19:30 2017<br class="gmail_msg">
@@ -30,6 +30,8 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   Error load(BinaryStreamReader &Stream);<br class="gmail_msg">
<br class="gmail_msg">
+  uint32_t getByteSize() const;<br class="gmail_msg">
+<br class="gmail_msg">
   uint32_t getNameCount() const { return NameCount; }<br class="gmail_msg">
   uint32_t getHashVersion() const { return HashVersion; }<br class="gmail_msg">
   uint32_t getSignature() const { return Signature; }<br class="gmail_msg">
@@ -42,9 +44,10 @@ public:<br class="gmail_msg">
 private:<br class="gmail_msg">
   BinaryStreamRef NamesBuffer;<br class="gmail_msg">
   FixedStreamArray<support::ulittle32_t> IDs;<br class="gmail_msg">
-  uint32_t Signature;<br class="gmail_msg">
-  uint32_t HashVersion;<br class="gmail_msg">
-  uint32_t NameCount;<br class="gmail_msg">
+  uint32_t ByteSize = 0;<br class="gmail_msg">
+  uint32_t Signature = 0;<br class="gmail_msg">
+  uint32_t HashVersion = 0;<br class="gmail_msg">
+  uint32_t NameCount = 0;<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
 } // end namespace pdb<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp?rev=297901&r1=297900&r2=297901&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp?rev=297901&r1=297900&r2=297901&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp Wed Mar 15 17:19:30 2017<br class="gmail_msg">
@@ -20,9 +20,11 @@ using namespace llvm;<br class="gmail_msg">
 using namespace llvm::support;<br class="gmail_msg">
 using namespace llvm::pdb;<br class="gmail_msg">
<br class="gmail_msg">
-StringTable::StringTable() : Signature(0), HashVersion(0), NameCount(0) {}<br class="gmail_msg">
+StringTable::StringTable() {}<br class="gmail_msg">
<br class="gmail_msg">
 Error StringTable::load(BinaryStreamReader &Stream) {<br class="gmail_msg">
+  ByteSize = Stream.getLength();<br class="gmail_msg">
+<br class="gmail_msg">
   const StringTableHeader *H;<br class="gmail_msg">
   if (auto EC = Stream.readObject(H))<br class="gmail_msg">
     return EC;<br class="gmail_msg">
@@ -56,9 +58,18 @@ Error StringTable::load(BinaryStreamRead<br class="gmail_msg">
<br class="gmail_msg">
   if (auto EC = Stream.readInteger(NameCount))<br class="gmail_msg">
     return EC;<br class="gmail_msg">
+<br class="gmail_msg">
+  if (Stream.bytesRemaining() > 0)<br class="gmail_msg">
+    return make_error<RawError>(raw_error_code::stream_too_long,<br class="gmail_msg">
+      "Unexpected bytes found in string table");<br class="gmail_msg">
+<br class="gmail_msg">
   return Error::success();<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+uint32_t StringTable::getByteSize() const {<br class="gmail_msg">
+  return ByteSize;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 StringRef StringTable::getStringForID(uint32_t ID) const {<br class="gmail_msg">
   if (ID == IDs[0])<br class="gmail_msg">
     return StringRef();<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/tools/llvm-pdbdump/Diff.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/Diff.cpp?rev=297901&r1=297900&r2=297901&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/Diff.cpp?rev=297901&r1=297900&r2=297901&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/tools/llvm-pdbdump/Diff.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/tools/llvm-pdbdump/Diff.cpp Wed Mar 15 17:19:30 2017<br class="gmail_msg">
@@ -14,6 +14,7 @@<br class="gmail_msg">
<br class="gmail_msg">
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"<br class="gmail_msg">
 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"<br class="gmail_msg">
+#include "llvm/DebugInfo/PDB/Native/StringTable.h"<br class="gmail_msg">
<br class="gmail_msg">
 #include "llvm/Support/FormatAdapters.h"<br class="gmail_msg">
 #include "llvm/Support/FormatVariadic.h"<br class="gmail_msg">
@@ -21,6 +22,48 @@<br class="gmail_msg">
 using namespace llvm;<br class="gmail_msg">
 using namespace llvm::pdb;<br class="gmail_msg">
<br class="gmail_msg">
+template<typename R><br class="gmail_msg">
+using ValueOfRange = llvm::detail::ValueOfRange<R>;<br class="gmail_msg">
+<br class="gmail_msg">
+template<typename Range, typename Comp><br class="gmail_msg">
+static void set_differences(Range &&R1, Range &&R2,<br class="gmail_msg">
+    SmallVectorImpl<ValueOfRange<Range>> *OnlyLeft,<br class="gmail_msg">
+    SmallVectorImpl<ValueOfRange<Range>> *OnlyRight,<br class="gmail_msg">
+    SmallVectorImpl<ValueOfRange<Range>> *Intersection, Comp Comparator) {<br class="gmail_msg">
+<br class="gmail_msg">
+  std::sort(R1.begin(), R1.end(), Comparator);<br class="gmail_msg">
+  std::sort(R2.begin(), R2.end(), Comparator);<br class="gmail_msg">
+<br class="gmail_msg">
+  if (OnlyLeft) {<br class="gmail_msg">
+    OnlyLeft->reserve(R1.size());<br class="gmail_msg">
+    auto End = std::set_difference(R1.begin(), R1.end(), R2.begin(), R2.end(),<br class="gmail_msg">
+      OnlyLeft->begin(), Comparator);<br class="gmail_msg">
+    OnlyLeft->set_size(std::distance(OnlyLeft->begin(), End));<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (OnlyRight) {<br class="gmail_msg">
+    OnlyLeft->reserve(R2.size());<br class="gmail_msg">
+    auto End = std::set_difference(R2.begin(), R2.end(), R1.begin(), R1.end(),<br class="gmail_msg">
+      OnlyRight->begin(), Comparator);<br class="gmail_msg">
+    OnlyRight->set_size(std::distance(OnlyRight->begin(), End));<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (Intersection) {<br class="gmail_msg">
+    Intersection->reserve(std::min(R1.size(), R2.size()));<br class="gmail_msg">
+    auto End = std::set_intersection(R1.begin(), R1.end(), R2.begin(),<br class="gmail_msg">
+      R2.end(), Intersection->begin(), Comparator);<br class="gmail_msg">
+    Intersection->set_size(std::distance(Intersection->begin(), End));<br class="gmail_msg">
+  }<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+template<typename Range><br class="gmail_msg">
+static void set_differences(Range &&R1, Range &&R2,<br class="gmail_msg">
+  SmallVectorImpl<ValueOfRange<Range>> *OnlyLeft,<br class="gmail_msg">
+  SmallVectorImpl<ValueOfRange<Range>> *OnlyRight,<br class="gmail_msg">
+  SmallVectorImpl<ValueOfRange<Range>> *Intersection) {<br class="gmail_msg">
+  std::less<ValueOfRange<Range>> Comp;<br class="gmail_msg">
+  set_differences(std::forward<Range>(R1), std::forward<Range>(R2), OnlyLeft, OnlyRight, Intersection, Comp);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+<br class="gmail_msg">
 DiffStyle::DiffStyle(PDBFile &File1, PDBFile &File2)<br class="gmail_msg">
     : File1(File1), File2(File2) {}<br class="gmail_msg">
<br class="gmail_msg">
@@ -162,26 +205,12 @@ Error DiffStyle::diffStreamDirectory() {<br class="gmail_msg">
     auto Comparator = [](const value_type &I1, const value_type &I2) {<br class="gmail_msg">
       return I1.value() < I2.value();<br class="gmail_msg">
     };<br class="gmail_msg">
-    std::sort(PI.begin(), PI.end(), Comparator);<br class="gmail_msg">
-    std::sort(QI.begin(), QI.end(), Comparator);<br class="gmail_msg">
<br class="gmail_msg">
     decltype(PI) OnlyP;<br class="gmail_msg">
     decltype(QI) OnlyQ;<br class="gmail_msg">
     decltype(PI) Common;<br class="gmail_msg">
<br class="gmail_msg">
-    OnlyP.reserve(P.size());<br class="gmail_msg">
-    OnlyQ.reserve(Q.size());<br class="gmail_msg">
-    Common.reserve(Q.size());<br class="gmail_msg">
-<br class="gmail_msg">
-    auto PEnd = std::set_difference(PI.begin(), PI.end(), QI.begin(), QI.end(),<br class="gmail_msg">
-                                    OnlyP.begin(), Comparator);<br class="gmail_msg">
-    auto QEnd = std::set_difference(QI.begin(), QI.end(), PI.begin(), PI.end(),<br class="gmail_msg">
-                                    OnlyQ.begin(), Comparator);<br class="gmail_msg">
-    auto ComEnd = std::set_intersection(PI.begin(), PI.end(), QI.begin(),<br class="gmail_msg">
-                                        QI.end(), Common.begin(), Comparator);<br class="gmail_msg">
-    OnlyP.set_size(std::distance(OnlyP.begin(), PEnd));<br class="gmail_msg">
-    OnlyQ.set_size(std::distance(OnlyQ.begin(), QEnd));<br class="gmail_msg">
-    Common.set_size(std::distance(Common.begin(), ComEnd));<br class="gmail_msg">
+    set_differences(PI, QI, &OnlyP, &OnlyQ, &Common, Comparator);<br class="gmail_msg">
<br class="gmail_msg">
     if (!OnlyP.empty()) {<br class="gmail_msg">
       HasDifferences = true;<br class="gmail_msg">
@@ -238,7 +267,98 @@ Error DiffStyle::diffStreamDirectory() {<br class="gmail_msg">
   return Error::success();<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
-Error DiffStyle::diffStringTable() { return Error::success(); }<br class="gmail_msg">
+Error DiffStyle::diffStringTable() {<br class="gmail_msg">
+  auto ExpectedST1 = File1.getStringTable();<br class="gmail_msg">
+  auto ExpectedST2 = File2.getStringTable();<br class="gmail_msg">
+  outs() << "String Table: Searching for differences...\n";<br class="gmail_msg">
+  bool Has1 = !!ExpectedST1;<br class="gmail_msg">
+  bool Has2 = !!ExpectedST2;<br class="gmail_msg">
+  if (!(Has1 && Has2)) {<br class="gmail_msg">
+    // If one has a string table and the other doesn't, we can print less output.<br class="gmail_msg">
+    if (Has1 != Has2) {<br class="gmail_msg">
+      if (Has1) {<br class="gmail_msg">
+        outs() << formatv("  {0}: ({1} strings)\n", File1.getFilePath(), ExpectedST1->getNameCount());<br class="gmail_msg">
+        outs() << formatv("  {0}: (string table not present)\n", File2.getFilePath());<br class="gmail_msg">
+      } else {<br class="gmail_msg">
+        outs() << formatv("  {0}: (string table not present)\n", File1.getFilePath());<br class="gmail_msg">
+        outs() << formatv("  {0}: ({1})\n", File2.getFilePath(), ExpectedST2->getNameCount());<br class="gmail_msg">
+      }<br class="gmail_msg">
+    }<br class="gmail_msg">
+    consumeError(ExpectedST1.takeError());<br class="gmail_msg">
+    consumeError(ExpectedST2.takeError());<br class="gmail_msg">
+    return Error::success();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  bool HasDiff = false;<br class="gmail_msg">
+  auto &ST1 = *ExpectedST1;<br class="gmail_msg">
+  auto &ST2 = *ExpectedST2;<br class="gmail_msg">
+<br class="gmail_msg">
+  HasDiff |= diffAndPrint("Stream Size", File1, File2, ST1.getByteSize(), ST2.getByteSize());<br class="gmail_msg">
+  HasDiff |= diffAndPrint("Hash Version", File1, File2, ST1.getHashVersion(), ST1.getHashVersion());<br class="gmail_msg">
+  HasDiff |= diffAndPrint("Signature", File1, File2, ST1.getSignature(), ST1.getSignature());<br class="gmail_msg">
+<br class="gmail_msg">
+  // Both have a valid string table, dive in and compare individual strings.<br class="gmail_msg">
+<br class="gmail_msg">
+  auto IdList1 = ST1.name_ids();<br class="gmail_msg">
+  auto IdList2 = ST2.name_ids();<br class="gmail_msg">
+  if (opts::diff::Pedantic) {<br class="gmail_msg">
+    // In pedantic mode, we compare index by index (i.e. the strings are in the same order<br class="gmail_msg">
+    // in both tables.<br class="gmail_msg">
+    uint32_t Max = std::max(IdList1.size(), IdList2.size());<br class="gmail_msg">
+    for (uint32_t I = 0; I < Max; ++I) {<br class="gmail_msg">
+      Optional<uint32_t> Id1, Id2;<br class="gmail_msg">
+      StringRef S1, S2;<br class="gmail_msg">
+      if (I < IdList1.size()) {<br class="gmail_msg">
+        Id1 = IdList1[I];<br class="gmail_msg">
+        S1 = ST1.getStringForID(*Id1);<br class="gmail_msg">
+      }<br class="gmail_msg">
+      if (I < IdList2.size()) {<br class="gmail_msg">
+        Id2 = IdList2[I];<br class="gmail_msg">
+        S2 = ST2.getStringForID(*Id2);<br class="gmail_msg">
+      }<br class="gmail_msg">
+      if (Id1 == Id2 && S1 == S2)<br class="gmail_msg">
+        continue;<br class="gmail_msg">
+<br class="gmail_msg">
+      std::string OutId1 = Id1 ? formatv("{0}", *Id1).str() : "(index not present)";<br class="gmail_msg">
+      std::string OutId2 = Id2 ? formatv("{0}", *Id2).str() : "(index not present)";<br class="gmail_msg">
+      outs() << formatv("  String {0}\n", I);<br class="gmail_msg">
+      outs() << formatv("    {0}: Hash - {1}, Value - {2}\n", File1.getFilePath(), OutId1, S1);<br class="gmail_msg">
+      outs() << formatv("    {0}: Hash - {1}, Value - {2}\n", File2.getFilePath(), OutId2, S2);<br class="gmail_msg">
+      HasDiff = true;<br class="gmail_msg">
+    }<br class="gmail_msg">
+  } else {<br class="gmail_msg">
+    std::vector<StringRef> Strings1, Strings2;<br class="gmail_msg">
+    Strings1.reserve(IdList1.size());<br class="gmail_msg">
+    Strings2.reserve(IdList2.size());<br class="gmail_msg">
+    for (auto ID : IdList1)<br class="gmail_msg">
+      Strings1.push_back(ST1.getStringForID(ID));<br class="gmail_msg">
+    for (auto ID : IdList2)<br class="gmail_msg">
+      Strings2.push_back(ST2.getStringForID(ID));<br class="gmail_msg">
+<br class="gmail_msg">
+    SmallVector<StringRef, 64> OnlyP;<br class="gmail_msg">
+    SmallVector<StringRef, 64> OnlyQ;<br class="gmail_msg">
+<br class="gmail_msg">
+    set_differences(Strings1, Strings2, &OnlyP, &OnlyQ, nullptr);<br class="gmail_msg">
+<br class="gmail_msg">
+    if (!OnlyP.empty()) {<br class="gmail_msg">
+      HasDiff = true;<br class="gmail_msg">
+      outs() << formatv("  {0} String(s) only in ({1})\n",<br class="gmail_msg">
+        OnlyP.size(), File1.getFilePath());<br class="gmail_msg">
+      for (auto Item : OnlyP)<br class="gmail_msg">
+        outs() << formatv("    {2}\n", Item);<br class="gmail_msg">
+    }<br class="gmail_msg">
+    if (!OnlyQ.empty()) {<br class="gmail_msg">
+      HasDiff = true;<br class="gmail_msg">
+      outs() << formatv("  {0} String(s) only in ({1})\n",<br class="gmail_msg">
+        OnlyQ.size(), File2.getFilePath());<br class="gmail_msg">
+      for (auto Item : OnlyQ)<br class="gmail_msg">
+        outs() << formatv("    {2}\n", Item);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+  if (!HasDiff)<br class="gmail_msg">
+    outs() << "String Table: No differences detected!\n";<br class="gmail_msg">
+  return Error::success();<br class="gmail_msg">
+}<br class="gmail_msg">
<br class="gmail_msg">
 Error DiffStyle::diffFreePageMap() { return Error::success(); }<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
llvm-commits mailing list<br class="gmail_msg">
<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg">
</blockquote></div>