<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 6, 2016 at 10:29 PM, Zachary Turner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br>
Date: Tue Jun  7 00:28:55 2016<br>
New Revision: 271982<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=271982&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=271982&view=rev</a><br>
Log:<br>
[pdb] Use MappedBlockStream to parse the PDB directory.<br>
<br>
In order to efficiently write PDBs, we need to be able to make a<br>
StreamWriter class similar to a StreamReader, which can transparently deal<br>
with writing to discontiguous streams, and we need to use this for all<br>
writing, similar to how we use StreamReader for all reading.<br>
<br>
Most discontiguous streams are the typical numbered streams that appear in<br>
a PDB file and are described by the directory, but the exception to this,<br>
that until now has been parsed by hand, is the directory itself.<br>
MappedBlockStream works by querying the directory to find out which blocks<br>
a stream occupies and various other things, so naturally the same logic<br>
could not possibly work to describe the blocks that the directory itself<br>
resided on.<br>
<br>
To solve this, I've introduced an abstraction IPDBStreamData, which allows<br>
the client to query for the list of blocks occupied by the stream, as well<br>
as the stream length. I provide two implementations of this: one which<br>
queries the directory (for indexed streams), and one which queries the<br>
super block (for the directory stream).<br>
<br>
This has the side benefit of vastly simplifying the code to parse the<br>
directory. Whereas before a mini state machine was rolled by hand, now we<br>
simply use FixedStreamArray to read out the stream sizes, then build a<br>
vector of FixedStreamArrays for the stream map, all in just a few lines of<br>
code.<br>
<br>
Reviewed By: ruiu<br>
Differential Revision: <a href="http://reviews.llvm.org/D21046" rel="noreferrer" target="_blank">http://reviews.llvm.org/D21046</a><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej<br>
Modified:<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h<br>
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp<br>
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h Tue Jun  7 00:28:55 2016<br>
@@ -224,6 +224,8 @@ public:<br>
     return FixedStreamArrayIterator<T>(*this, size());<br>
   }<br>
<br>
+  StreamRef getUnderlyingStream() const { return Stream; }<br>
+<br>
 private:<br>
   StreamRef Stream;<br>
 };<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h Tue Jun  7 00:28:55 2016<br>
@@ -52,6 +52,20 @@ public:<br>
     return Error::success();<br>
   }<br>
<br>
+  template <typename T><br>
+  Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {<br>
+    ArrayRef<uint8_t> Bytes;<br>
+    if (NumElements == 0) {<br>
+      Array = ArrayRef<T>();<br>
+      return Error::success();<br>
+    }<br>
+<br>
+    if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))<br></blockquote><div><br></div><div>Can't this overflow?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      return EC;<br>
+    Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);<br>
+    return Error::success();<br>
+  }<br>
+<br>
   template <typename T, typename U><br>
   Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {<br>
     StreamRef S;<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h Tue Jun  7 00:28:55 2016<br>
@@ -12,6 +12,7 @@<br>
<br>
 #include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
 #include "llvm/Support/Endian.h"<br>
<br>
 #include <stdint.h><br>
@@ -28,7 +29,8 @@ public:<br>
<br>
   virtual uint32_t getNumStreams() const = 0;<br>
   virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const = 0;<br>
-  virtual ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const = 0;<br>
+  virtual ArrayRef<support::ulittle32_t><br>
+  getStreamBlockList(uint32_t StreamIndex) const = 0;<br>
<br>
   virtual StringRef getBlockData(uint32_t BlockIndex,<br>
                                  uint32_t NumBytes) const = 0;<br>
<br>
Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h?rev=271982&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h?rev=271982&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h (added)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h Tue Jun  7 00:28:55 2016<br>
@@ -0,0 +1,38 @@<br>
+//===- IPDBStreamData.h - Base interface for PDB Stream Data ----*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H<br>
+#define LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H<br>
+<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/Support/Endian.h"<br>
+<br>
+namespace llvm {<br>
+namespace pdb {<br>
+/// IPDBStream abstracts the notion of PDB stream data.  Although we already<br>
+/// have another stream abstraction (namely in the form of StreamInterface<br>
+/// and MappedBlockStream), they assume that the stream data is referenced<br>
+/// the same way.  Namely, by looking in the directory to get the list of<br>
+/// stream blocks, and by looking in the array of stream lengths to get the<br>
+/// length.  This breaks down for the directory itself, however, since its<br>
+/// length and list of blocks are stored elsewhere.  By abstracting the<br>
+/// notion of stream data further, we can use a MappedBlockStream to read<br>
+/// from the directory itself, or from an indexed stream which references<br>
+/// the directory.<br>
+class IPDBStreamData {<br>
+public:<br>
+  virtual ~IPDBStreamData() {}<br>
+<br>
+  virtual uint32_t getLength() = 0;<br>
+  virtual ArrayRef<support::ulittle32_t> getStreamBlocks() = 0;<br>
+};<br>
+}<br>
+}<br>
+<br>
+#endif<br>
<br>
Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h?rev=271982&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h?rev=271982&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h (added)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h Tue Jun  7 00:28:55 2016<br>
@@ -0,0 +1,34 @@<br>
+//===- IndexedStreamData.h - Standard PDB Stream Data -----------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H<br>
+#define LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H<br>
+<br>
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"<br>
+<br>
+namespace llvm {<br>
+namespace pdb {<br>
+class IPDBFile;<br>
+<br>
+class IndexedStreamData : public IPDBStreamData {<br>
+public:<br>
+  IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File);<br>
+  virtual ~IndexedStreamData() {}<br>
+<br>
+  uint32_t getLength() override;<br>
+  ArrayRef<support::ulittle32_t> getStreamBlocks() override;<br>
+<br>
+private:<br>
+  uint32_t StreamIdx;<br>
+  const IPDBFile &File;<br>
+};<br>
+}<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h Tue Jun  7 00:28:55 2016<br>
@@ -24,7 +24,7 @@ namespace pdb {<br>
 class PDBFile;<br>
 class InfoStream {<br>
 public:<br>
-  InfoStream(PDBFile &File);<br>
+  InfoStream(const PDBFile &File);<br>
<br>
   Error reload();<br>
<br>
@@ -36,10 +36,7 @@ public:<br>
   uint32_t getNamedStreamIndex(llvm::StringRef Name) const;<br>
   iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;<br>
<br>
-  PDBFile &getFile() { return Pdb; }<br>
-<br>
 private:<br>
-  PDBFile &Pdb;<br>
   MappedBlockStream Stream;<br>
<br>
   // PDB file format version.  We only support VC70.  See the enumeration<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h Tue Jun  7 00:28:55 2016<br>
@@ -14,6 +14,7 @@<br>
 #include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamInterface.h"<br>
 #include "llvm/Support/Allocator.h"<br>
+#include "llvm/Support/Endian.h"<br>
 #include "llvm/Support/Error.h"<br>
 #include <cstdint><br>
 #include <vector><br>
@@ -22,15 +23,16 @@ namespace llvm {<br>
 namespace pdb {<br>
<br>
 class IPDBFile;<br>
+class IPDBStreamData;<br>
<br>
 class MappedBlockStream : public codeview::StreamInterface {<br>
 public:<br>
-  MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File);<br>
+  MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &File);<br>
<br>
   Error readBytes(uint32_t Offset, uint32_t Size,<br>
                   ArrayRef<uint8_t> &Buffer) const override;<br>
<br>
-  uint32_t getLength() const override { return StreamLength; }<br>
+  uint32_t getLength() const override;<br>
<br>
   uint32_t getNumBytesCopied() const;<br>
<br>
@@ -39,11 +41,11 @@ private:<br>
   bool tryReadContiguously(uint32_t Offset, uint32_t Size,<br>
                            ArrayRef<uint8_t> &Buffer) const;<br>
<br>
-  uint32_t StreamLength;<br>
-  std::vector<uint32_t> BlockList;<br>
+  const IPDBFile &Pdb;<br>
+  std::unique_ptr<IPDBStreamData> Data;<br>
+<br>
   mutable llvm::BumpPtrAllocator Pool;<br>
   mutable DenseMap<uint32_t, uint8_t *> CacheMap;<br>
-  const IPDBFile &Pdb;<br>
 };<br>
<br>
 } // end namespace pdb<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h Tue Jun  7 00:28:55 2016<br>
@@ -26,7 +26,7 @@ class ModInfo;<br>
<br>
 class ModStream {<br>
 public:<br>
-  ModStream(PDBFile &File, const ModInfo &Module);<br>
+  ModStream(const PDBFile &File, const ModInfo &Module);<br>
   ~ModStream();<br>
<br>
   Error reload();<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Tue Jun  7 00:28:55 2016<br>
@@ -11,6 +11,7 @@<br>
 #define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H<br>
<br>
 #include "llvm/ADT/DenseMap.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"<br>
 #include "llvm/Support/Endian.h"<br>
 #include "llvm/Support/Error.h"<br>
@@ -48,11 +49,12 @@ public:<br>
<br>
   uint32_t getNumStreams() const override;<br>
   uint32_t getStreamByteSize(uint32_t StreamIndex) const override;<br>
-  ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const override;<br>
+  ArrayRef<support::ulittle32_t><br>
+  getStreamBlockList(uint32_t StreamIndex) const override;<br>
<br>
   StringRef getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const override;<br>
<br>
-  ArrayRef<support::ulittle32_t> getDirectoryBlockArray();<br>
+  ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;<br>
<br>
   Error parseFileHeaders();<br>
   Error parseStreamData();<br>
@@ -81,6 +83,7 @@ private:<br>
   std::unique_ptr<TpiStream> Ipi;<br>
   std::unique_ptr<PublicsStream> Publics;<br>
   std::unique_ptr<SymbolStream> Symbols;<br>
+  std::unique_ptr<MappedBlockStream> DirectoryStream;<br>
   std::unique_ptr<MappedBlockStream> StringTableStream;<br>
   std::unique_ptr<NameHashTable> StringTable;<br>
 };<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h Tue Jun  7 00:28:55 2016<br>
@@ -22,7 +22,7 @@ class PDBFile;<br>
<br>
 class SymbolStream {<br>
 public:<br>
-  SymbolStream(PDBFile &File, uint32_t StreamNum);<br>
+  SymbolStream(const PDBFile &File, uint32_t StreamNum);<br>
   ~SymbolStream();<br>
   Error reload();<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h Tue Jun  7 00:28:55 2016<br>
@@ -31,7 +31,7 @@ class TpiStream {<br>
   struct HeaderInfo;<br>
<br>
 public:<br>
-  TpiStream(PDBFile &File, uint32_t StreamIdx);<br>
+  TpiStream(const PDBFile &File, uint32_t StreamIdx);<br>
   ~TpiStream();<br>
   Error reload();<br>
<br>
@@ -50,7 +50,7 @@ public:<br>
   iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;<br>
<br>
 private:<br>
-  PDBFile &Pdb;<br>
+  const PDBFile &Pdb;<br>
   MappedBlockStream Stream;<br>
   HashFunctionType HashFunction;<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Tue Jun  7 00:28:55 2016<br>
@@ -30,6 +30,7 @@ endif()<br>
 add_pdb_impl_folder(Raw<br>
   Raw/DbiStream.cpp<br>
   Raw/EnumTables.cpp<br>
+  Raw/IndexedStreamData.cpp<br>
   Raw/InfoStream.cpp<br>
   Raw/MappedBlockStream.cpp<br>
   Raw/ModInfo.cpp<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -12,6 +12,7 @@<br>
 #include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"<br>
@@ -93,7 +94,9 @@ Error loadSectionContribs(FixedStreamArr<br>
 }<br>
<br>
 DbiStream::DbiStream(PDBFile &File)<br>
-    : Pdb(File), Stream(StreamDBI, File), Header(nullptr) {<br>
+    : Pdb(File),<br>
+      Stream(llvm::make_unique<IndexedStreamData>(StreamDBI, File), File),<br>
+      Header(nullptr) {<br>
   static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");<br>
 }<br>
<br>
@@ -290,7 +293,8 @@ Error DbiStream::initializeSectionContri<br>
 // Initializes this->SectionHeaders.<br>
 Error DbiStream::initializeSectionHeadersData() {<br>
   uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);<br>
-  SectionHeaderStream.reset(new MappedBlockStream(StreamNum, Pdb));<br>
+  SectionHeaderStream.reset(new MappedBlockStream(<br>
+      llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));<br>
<br>
   size_t StreamLen = SectionHeaderStream->getLength();<br>
   if (StreamLen % sizeof(object::coff_section))<br>
@@ -308,7 +312,8 @@ Error DbiStream::initializeSectionHeader<br>
 // Initializes this->Fpos.<br>
 Error DbiStream::initializeFpoRecords() {<br>
   uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);<br>
-  FpoStream.reset(new MappedBlockStream(StreamNum, Pdb));<br>
+  FpoStream.reset(new MappedBlockStream(<br>
+      llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));<br>
<br>
   size_t StreamLen = FpoStream->getLength();<br>
   if (StreamLen % sizeof(object::FpoData))<br>
<br>
Added: llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp?rev=271982&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp?rev=271982&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp (added)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp Tue Jun  7 00:28:55 2016<br>
@@ -0,0 +1,25 @@<br>
+//===- IndexedStreamData.cpp - Standard PDB Stream Data ---------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"<br>
+<br>
+using namespace llvm;<br>
+using namespace llvm::pdb;<br>
+<br>
+IndexedStreamData::IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File)<br>
+    : StreamIdx(StreamIdx), File(File) {}<br>
+<br>
+uint32_t IndexedStreamData::getLength() {<br>
+  return File.getStreamByteSize(StreamIdx);<br>
+}<br>
+<br>
+ArrayRef<support::ulittle32_t> IndexedStreamData::getStreamBlocks() {<br>
+  return File.getStreamBlockList(StreamIdx);<br>
+}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -11,6 +11,7 @@<br>
 #include "llvm/ADT/BitVector.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"<br>
@@ -18,7 +19,8 @@<br>
 using namespace llvm;<br>
 using namespace llvm::pdb;<br>
<br>
-InfoStream::InfoStream(PDBFile &File) : Pdb(File), Stream(StreamPDB, File) {}<br>
+InfoStream::InfoStream(const PDBFile &File)<br>
+    : Stream(llvm::make_unique<IndexedStreamData>(StreamPDB, File), File) {}<br>
<br>
 Error InfoStream::reload() {<br>
   codeview::StreamReader Reader(Stream);<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -8,28 +8,23 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"<br>
<br>
 using namespace llvm;<br>
 using namespace llvm::pdb;<br>
<br>
-MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File)<br>
-    : Pdb(File) {<br>
-  if (StreamIdx >= Pdb.getNumStreams()) {<br>
-    StreamLength = 0;<br>
-  } else {<br>
-    StreamLength = Pdb.getStreamByteSize(StreamIdx);<br>
-    BlockList = Pdb.getStreamBlockList(StreamIdx);<br>
-  }<br>
-}<br>
+MappedBlockStream::MappedBlockStream(std::unique_ptr<IPDBStreamData> Data,<br>
+                                     const IPDBFile &Pdb)<br>
+    : Pdb(Pdb), Data(std::move(Data)) {}<br>
<br>
 Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,<br>
                                    ArrayRef<uint8_t> &Buffer) const {<br>
   // Make sure we aren't trying to read beyond the end of the stream.<br>
-  if (Size > StreamLength)<br>
+  if (Size > Data->getLength())<br>
     return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
-  if (Offset > StreamLength - Size)<br>
+  if (Offset > Data->getLength() - Size)<br>
     return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
<br>
   if (tryReadContiguously(Offset, Size, Buffer))<br>
@@ -57,6 +52,8 @@ Error MappedBlockStream::readBytes(uint3<br>
   return Error::success();<br>
 }<br>
<br>
+uint32_t MappedBlockStream::getLength() const { return Data->getLength(); }<br>
+<br>
 bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,<br>
                                             ArrayRef<uint8_t> &Buffer) const {<br>
   // Attempt to fulfill the request with a reference directly into the stream.<br>
@@ -72,6 +69,7 @@ bool MappedBlockStream::tryReadContiguou<br>
       llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /<br>
       Pdb.getBlockSize();<br>
<br>
+  auto BlockList = Data->getStreamBlocks();<br>
   uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;<br>
   uint32_t E = BlockList[BlockNum];<br>
   for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {<br>
@@ -93,14 +91,15 @@ Error MappedBlockStream::readBytes(uint3<br>
   uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();<br>
<br>
   // Make sure we aren't trying to read beyond the end of the stream.<br>
-  if (Buffer.size() > StreamLength)<br>
+  if (Buffer.size() > Data->getLength())<br>
     return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
-  if (Offset > StreamLength - Buffer.size())<br>
+  if (Offset > Data->getLength() - Buffer.size())<br>
     return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
<br>
   uint32_t BytesLeft = Buffer.size();<br>
   uint32_t BytesWritten = 0;<br>
   uint8_t *WriteBuffer = Buffer.data();<br>
+  auto BlockList = Data->getStreamBlocks();<br>
   while (BytesLeft > 0) {<br>
     uint32_t StreamBlockAddr = BlockList[BlockNum];<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -10,6 +10,7 @@<br>
 #include "llvm/DebugInfo/PDB/Raw/ModStream.h"<br>
<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"<br>
@@ -18,8 +19,10 @@<br>
 using namespace llvm;<br>
 using namespace llvm::pdb;<br>
<br>
-ModStream::ModStream(PDBFile &File, const ModInfo &Module)<br>
-    : Mod(Module), Stream(Module.getModuleStreamIndex(), File) {}<br>
+ModStream::ModStream(const PDBFile &File, const ModInfo &Module)<br>
+    : Mod(Module), Stream(llvm::make_unique<IndexedStreamData>(<br>
+                              Module.getModuleStreamIndex(), File),<br>
+                          File) {}<br>
<br>
 ModStream::~ModStream() {}<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Tue Jun  7 00:28:55 2016<br>
@@ -8,8 +8,12 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
+<br>
 #include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"<br>
@@ -49,13 +53,28 @@ struct SuperBlock {<br>
   // This contains the block # of the block map.<br>
   support::ulittle32_t BlockMapAddr;<br>
 };<br>
+<br>
+class DirectoryStreamData : public IPDBStreamData {<br>
+public:<br>
+  DirectoryStreamData(const PDBFile &File) : File(File) {}<br>
+<br>
+  virtual uint32_t getLength() { return File.getNumDirectoryBytes(); }<br>
+  virtual llvm::ArrayRef<llvm::support::ulittle32_t> getStreamBlocks() {<br>
+    return File.getDirectoryBlockArray();<br>
+  }<br>
+<br>
+private:<br>
+  const PDBFile &File;<br>
+};<br>
+<br>
+typedef codeview::FixedStreamArray<support::ulittle32_t> ulittle_array;<br>
 }<br>
<br>
 struct llvm::pdb::PDBFileContext {<br>
   std::unique_ptr<MemoryBuffer> Buffer;<br>
   const SuperBlock *SB;<br>
-  std::vector<uint32_t> StreamSizes;<br>
-  DenseMap<uint32_t, std::vector<uint32_t>> StreamMap;<br>
+  ArrayRef<support::ulittle32_t> StreamSizes;<br>
+  std::vector<ulittle_array> StreamMap;<br>
 };<br>
<br>
 static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,<br>
@@ -109,10 +128,14 @@ uint32_t PDBFile::getStreamByteSize(uint<br>
   return Context->StreamSizes[StreamIndex];<br>
 }<br>
<br>
-llvm::ArrayRef<uint32_t><br>
+ArrayRef<support::ulittle32_t><br>
 PDBFile::getStreamBlockList(uint32_t StreamIndex) const {<br>
-  auto &Data = Context->StreamMap[StreamIndex];<br>
-  return llvm::ArrayRef<uint32_t>(Data);<br>
+  auto Result = Context->StreamMap[StreamIndex];<br>
+  codeview::StreamReader Reader(Result.getUnderlyingStream());<br>
+  ArrayRef<support::ulittle32_t> Array;<br>
+  if (auto EC = Reader.readArray(Array, Result.size()))<br>
+    return ArrayRef<support::ulittle32_t>();<br>
+  return Array;<br>
 }<br>
<br>
 StringRef PDBFile::getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const {<br>
@@ -184,113 +207,44 @@ Error PDBFile::parseFileHeaders() {<br>
<br>
 Error PDBFile::parseStreamData() {<br>
   assert(Context && Context->SB);<br>
+  if (DirectoryStream)<br>
+    return Error::success();<br>
<br>
-  bool SeenNumStreams = false;<br>
+  // bool SeenNumStreams = false;<br>
   uint32_t NumStreams = 0;<br>
-  uint32_t StreamIdx = 0;<br>
-  uint64_t DirectoryBytesRead = 0;<br>
+  // uint32_t StreamIdx = 0;<br>
+  // uint64_t DirectoryBytesRead = 0;<br></blockquote><div><br></div><div>Commented out code?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
-  MemoryBufferRef M = *Context->Buffer;<br>
   const SuperBlock *SB = Context->SB;<br>
<br>
-  auto DirectoryBlocks = getDirectoryBlockArray();<br>
-<br>
-  // The structure of the directory is as follows:<br>
-  //    struct PDBDirectory {<br>
-  //      uint32_t NumStreams;<br>
-  //      uint32_t StreamSizes[NumStreams];<br>
-  //      uint32_t StreamMap[NumStreams][];<br>
-  //    };<br>
-  //<br>
-  //  Empty streams don't consume entries in the StreamMap.<br>
-  for (uint32_t DirectoryBlockAddr : DirectoryBlocks) {<br>
-    uint64_t DirectoryBlockOffset =<br>
-        blockToOffset(DirectoryBlockAddr, SB->BlockSize);<br>
-    auto DirectoryBlock =<br>
-        makeArrayRef(reinterpret_cast<const support::ulittle32_t *>(<br>
-                         M.getBufferStart() + DirectoryBlockOffset),<br>
-                     SB->BlockSize / sizeof(support::ulittle32_t));<br>
-    if (auto EC = checkOffset(M, DirectoryBlock))<br>
-      return EC;<br>
-<br>
-    // We read data out of the directory four bytes at a time.  Depending on<br>
-    // where we are in the directory, the contents may be: the number of streams<br>
-    // in the directory, a stream's size, or a block in the stream map.<br>
-    for (uint32_t Data : DirectoryBlock) {<br>
-      // Don't read beyond the end of the directory.<br>
-      if (DirectoryBytesRead == SB->NumDirectoryBytes)<br>
-        break;<br>
-<br>
-      DirectoryBytesRead += sizeof(Data);<br>
-<br>
-      // This data must be the number of streams if we haven't seen it yet.<br>
-      if (!SeenNumStreams) {<br>
-        NumStreams = Data;<br>
-        SeenNumStreams = true;<br>
-        continue;<br>
-      }<br>
-      // This data must be a stream size if we have not seen them all yet.<br>
-      if (Context->StreamSizes.size() < NumStreams) {<br>
-        // It seems like some streams have their set to -1 when their contents<br>
-        // are not present.  Treat them like empty streams for now.<br>
-        if (Data == UINT32_MAX)<br>
-          Context->StreamSizes.push_back(0);<br>
-        else<br>
-          Context->StreamSizes.push_back(Data);<br>
-        continue;<br>
-      }<br>
-<br>
-      // This data must be a stream block number if we have seen all of the<br>
-      // stream sizes.<br>
-      std::vector<uint32_t> *StreamBlocks = nullptr;<br>
-      // Figure out which stream this block number belongs to.<br>
-      while (StreamIdx < NumStreams) {<br>
-        uint64_t NumExpectedStreamBlocks =<br>
-            bytesToBlocks(Context->StreamSizes[StreamIdx], SB->BlockSize);<br>
-        StreamBlocks = &Context->StreamMap[StreamIdx];<br>
-        if (NumExpectedStreamBlocks > StreamBlocks->size())<br>
-          break;<br>
-        ++StreamIdx;<br>
-      }<br>
-      // It seems this block doesn't belong to any stream?  The stream is either<br>
-      // corrupt or something more mysterious is going on.<br>
-      if (StreamIdx == NumStreams)<br>
-        return make_error<RawError>(raw_error_code::corrupt_file,<br>
-                                    "Orphaned block found?");<br>
-<br>
-      uint64_t BlockOffset = blockToOffset(Data, getBlockSize());<br>
-      if (BlockOffset + getBlockSize() < BlockOffset)<br>
-        return make_error<RawError>(raw_error_code::corrupt_file,<br>
-                                    "Bogus stream block number");<br>
-      if (BlockOffset + getBlockSize() > M.getBufferSize())<br>
-        return make_error<RawError>(raw_error_code::corrupt_file,<br>
-                                    "Stream block number is out of bounds");<br>
-<br>
-      StreamBlocks->push_back(Data);<br>
-    }<br>
-  }<br>
-<br>
-  if (Context->StreamSizes.size() != NumStreams)<br>
-    return make_error<RawError>(<br>
-        raw_error_code::corrupt_file,<br>
-        "The directory has fewer streams then expected");<br>
+  // Normally you can't use a MappedBlockStream without having fully parsed the<br>
+  // PDB file, because it accesses the directory and various other things, which<br>
+  // is exactly what we are attempting to parse.  By specifying a custom<br>
+  // subclass of IPDBStreamData which only accesses the fields that have already<br>
+  // been parsed, we can avoid this and reuse MappedBlockStream.<br>
+  auto SD = llvm::make_unique<DirectoryStreamData>(*this);<br>
+  DirectoryStream = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);<br>
+  codeview::StreamReader Reader(*DirectoryStream);<br>
+  if (auto EC = Reader.readInteger(NumStreams))<br>
+    return EC;<br>
<br>
-  for (uint32_t I = 0; I != NumStreams; ++I) {<br>
+  if (auto EC = Reader.readArray(Context->StreamSizes, NumStreams))<br>
+    return EC;<br>
+  for (uint32_t I = 0; I < NumStreams; ++I) {<br>
     uint64_t NumExpectedStreamBlocks =<br>
-        bytesToBlocks(getStreamByteSize(I), getBlockSize());<br>
-    size_t NumStreamBlocks = getStreamBlockList(I).size();<br>
-    if (NumExpectedStreamBlocks != NumStreamBlocks)<br>
-      return make_error<RawError>(raw_error_code::corrupt_file,<br>
-                                  "The number of stream blocks is not "<br>
-                                  "sufficient for the size of this stream");<br>
+        bytesToBlocks(getStreamByteSize(I), SB->BlockSize);<br>
+    ulittle_array Blocks;<br>
+    if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))<br>
+      return EC;<br>
+    Context->StreamMap.push_back(Blocks);<br>
   }<br>
<br>
   // We should have read exactly SB->NumDirectoryBytes bytes.<br>
-  assert(DirectoryBytesRead == SB->NumDirectoryBytes);<br>
+  assert(Reader.bytesRemaining() == 0);<br>
   return Error::success();<br>
 }<br>
<br>
-llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() {<br>
+llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {<br>
   return makeArrayRef(<br>
       reinterpret_cast<const support::ulittle32_t *>(<br>
           Context->Buffer->getBufferStart() + getBlockMapOffset()),<br>
@@ -371,7 +325,8 @@ Expected<NameHashTable &> PDBFile::getSt<br>
<br>
     if (NameStreamIndex == 0)<br>
       return make_error<RawError>(raw_error_code::no_stream);<br>
-    auto S = llvm::make_unique<MappedBlockStream>(NameStreamIndex, *this);<br>
+    auto SD = llvm::make_unique<IndexedStreamData>(NameStreamIndex, *this);<br>
+    auto S = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);<br>
     codeview::StreamReader Reader(*S);<br>
     auto N = llvm::make_unique<NameHashTable>();<br>
     if (auto EC = N->load(Reader))<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -27,6 +27,7 @@<br>
 #include "llvm/DebugInfo/CodeView/CodeView.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"<br>
@@ -71,7 +72,8 @@ struct PublicsStream::GSIHashHeader {<br>
 };<br>
<br>
 PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)<br>
-    : Pdb(File), StreamNum(StreamNum), Stream(StreamNum, File) {}<br>
+    : Pdb(File), StreamNum(StreamNum),<br>
+      Stream(llvm::make_unique<IndexedStreamData>(StreamNum, File), File) {}<br>
<br>
 PublicsStream::~PublicsStream() {}<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -12,6 +12,7 @@<br>
 #include "llvm/DebugInfo/CodeView/CodeView.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"<br>
@@ -23,8 +24,9 @@ using namespace llvm;<br>
 using namespace llvm::support;<br>
 using namespace llvm::pdb;<br>
<br>
-SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum)<br>
-    : MappedStream(StreamNum, File) {}<br>
+SymbolStream::SymbolStream(const PDBFile &File, uint32_t StreamNum)<br>
+    : MappedStream(llvm::make_unique<IndexedStreamData>(StreamNum, File),<br>
+                   File) {}<br>
<br>
 SymbolStream::~SymbolStream() {}<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Tue Jun  7 00:28:55 2016<br>
@@ -13,6 +13,7 @@<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"<br>
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"<br>
@@ -61,8 +62,10 @@ struct TpiStream::HeaderInfo {<br>
   EmbeddedBuf HashAdjBuffer;<br>
 };<br>
<br>
-TpiStream::TpiStream(PDBFile &File, uint32_t StreamIdx)<br>
-    : Pdb(File), Stream(StreamIdx, File), HashFunction(nullptr) {}<br>
+TpiStream::TpiStream(const PDBFile &File, uint32_t StreamIdx)<br>
+    : Pdb(File),<br>
+      Stream(llvm::make_unique<IndexedStreamData>(StreamIdx, File), File),<br>
+      HashFunction(nullptr) {}<br>
<br>
 TpiStream::~TpiStream() {}<br>
<br>
@@ -101,7 +104,8 @@ Error TpiStream::reload() {<br>
     return EC;<br>
<br>
   // Hash indices, hash values, etc come from the hash stream.<br>
-  HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));<br>
+  HashStream.reset(new MappedBlockStream(<br>
+      llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));<br>
   codeview::StreamReader HSR(*HashStream);<br>
<br>
   uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);<br>
<br>
Added: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej?rev=271982&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej?rev=271982&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej (added)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej Tue Jun  7 00:28:55 2016<br>
@@ -0,0 +1,11 @@<br>
+diff a/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/lib/DebugInfo/PDB/Raw/TpiStream.cpp       (rejected hunks)<br>
+@@ -101,7 +104,8 @@<br>
+     return EC;<br>
+<br>
+   // Hash indices, hash values, etc come from the hash stream.<br>
+-  HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));<br>
++  HashStream.reset(new MappedBlockStream(<br>
++      llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));<br>
+   codeview::StreamReader HSR(*HashStream);<br>
+   uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);<br>
+   HSR.setOffset(Header->HashValueBuffer.Off);<br>
<br>
Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=271982&r1=271981&r2=271982&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=271982&r1=271981&r2=271982&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)<br>
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Tue Jun  7 00:28:55 2016<br>
@@ -17,6 +17,7 @@<br>
 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/EnumTables.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"<br>
+#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModStream.h"<br>
@@ -194,7 +195,8 @@ Error LLVMOutputStyle::dumpStreamData()<br>
       DumpStreamNum >= StreamCount)<br>
     return Error::success();<br>
<br>
-  MappedBlockStream S(DumpStreamNum, File);<br>
+  MappedBlockStream S(llvm::make_unique<IndexedStreamData>(DumpStreamNum, File),<br>
+                      File);<br>
   codeview::StreamReader R(S);<br>
   while (R.bytesRemaining() > 0) {<br>
     ArrayRef<uint8_t> Data;<br>
@@ -244,7 +246,8 @@ Error LLVMOutputStyle::dumpNamedStream()<br>
     DictScope D(P, Name);<br>
     P.printNumber("Index", NameStreamIndex);<br>
<br>
-    MappedBlockStream NameStream(NameStreamIndex, File);<br>
+    MappedBlockStream NameStream(<br>
+        llvm::make_unique<IndexedStreamData>(NameStreamIndex, File), File);<br>
     codeview::StreamReader Reader(NameStream);<br>
<br>
     NameHashTable NameTable;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>