<div dir="ltr">It doesn't compile on my machine. Looks like libstdc++ 4.8 doesn't define is_trivially_constructible.<br><div><br></div><div><div>/ssd/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h:114:22: error: no template named 'is_trivially_constructible' in namespace 'std'; did you mean 'is_trivially_destructible'?</div><div>  static_assert(std::is_trivially_constructible<T>::value,</div><div>                ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~</div><div>                     is_trivially_destructible</div><div>/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:1204:12: note: 'is_trivially_destructible' declared here</div><div>    struct is_trivially_destructible</div><div>           ^</div><div>1 error generated.</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 26, 2016 at 6:54 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: Thu May 26 20:54:44 2016<br>
New Revision: 270951<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=270951&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=270951&view=rev</a><br>
Log:<br>
[codeview,pdb] Try really hard to conserve memory when reading.<br>
<br>
PDBs can be extremely large.  We're already mapping the entire<br>
PDB into the process's address space, but to make matters worse<br>
the blocks of the PDB are not arranged contiguously.  So, when<br>
we have something like an array or a string embedded into the<br>
stream, we have to make a copy.  Since it's convenient to use<br>
traditional data structures to iterate and manipulate these<br>
records, we need the memory to be contiguous.<br>
<br>
As a result of this, we were using roughly twice as much memory<br>
as the file size of the PDB, because every stream was copied<br>
out and re-stitched together contiguously.<br>
<br>
This patch addresses this by improving the MappedBlockStream<br>
to allocate from a BumpPtrAllocator only when a read requires<br>
a discontiguous read.  Furthermore, it introduces some data<br>
structures backed by a stream which can iterate over both<br>
fixed and variable length records of a PDB.  Since everything<br>
is backed by a stream and not a buffer, we can read almost<br>
everything from the PDB with zero copies.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D20654" rel="noreferrer" target="_blank">http://reviews.llvm.org/D20654</a><br>
Reviewed By: ruiu<br>
<br>
Added:<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h<br>
Modified:<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h<br>
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h<br>
    llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp<br>
    llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp<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/ModInfo.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp<br>
    llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.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/llvm-pdbdump.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ByteStream.h Thu May 26 20:54:44 2016<br>
@@ -24,20 +24,18 @@ class StreamReader;<br>
 class ByteStream : public StreamInterface {<br>
 public:<br>
   ByteStream();<br>
-  explicit ByteStream(MutableArrayRef<uint8_t> Bytes);<br>
-  explicit ByteStream(uint32_t Length);<br>
+  explicit ByteStream(MutableArrayRef<uint8_t> Data);<br>
   ~ByteStream() override;<br>
<br>
   void reset();<br>
-  void initialize(MutableArrayRef<uint8_t> Bytes);<br>
-  void initialize(uint32_t Length);<br>
-  Error initialize(StreamReader &Reader, uint32_t Length);<br>
+<br>
+  void load(uint32_t Length);<br>
+  Error load(StreamReader &Reader, uint32_t Length);<br>
<br>
   Error readBytes(uint32_t Offset,<br>
                   MutableArrayRef<uint8_t> Buffer) const override;<br>
-<br>
-  Error getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,<br>
-                    uint32_t Length) const override;<br>
+  Error readBytes(uint32_t Offset, uint32_t Size,<br>
+                  ArrayRef<uint8_t> &Buffer) const override;<br>
<br>
   uint32_t getLength() const override;<br>
<br>
<br>
Added: 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=270951&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h?rev=270951&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h (added)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h Thu May 26 20:54:44 2016<br>
@@ -0,0 +1,188 @@<br>
+//===- StreamArray.h - Array backed by an arbitrary stream ----------------===//<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_CODEVIEW_STREAMARRAY_H<br>
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H<br>
+<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
+<br>
+#include <functional><br>
+<br>
+namespace llvm {<br>
+namespace codeview {<br>
+<br>
+/// VarStreamArray represents an array of variable length records backed by a<br>
+/// stream.  This could be a contiguous sequence of bytes in memory, it could<br>
+/// be a file on disk, or it could be a PDB stream where bytes are stored as<br>
+/// discontiguous blocks in a file.  Usually it is desirable to treat arrays<br>
+/// as contiguous blocks of memory, but doing so with large PDB files, for<br>
+/// example, could mean allocating huge amounts of memory just to allow<br>
+/// re-ordering of stream data to be contiguous before iterating over it.  By<br>
+/// abstracting this out, we need not duplicate this memory, and we can<br>
+/// iterate over arrays in arbitrarily formatted streams.<br>
+class VarStreamArrayIterator;<br>
+<br>
+class VarStreamArray {<br>
+  friend class VarStreamArrayIterator;<br>
+  typedef std::function<uint32_t(const StreamInterface &)> LengthFuncType;<br>
+<br>
+public:<br>
+  template <typename LengthFunc><br>
+  VarStreamArray(StreamRef Stream, const LengthFunc &Len)<br>
+      : Stream(Stream), Len(Len) {}<br>
+<br>
+  VarStreamArrayIterator begin() const;<br>
+  VarStreamArrayIterator end() const;<br>
+<br>
+private:<br>
+  StreamRef Stream;<br>
+  LengthFuncType Len; // Function used to calculate legth of a record<br>
+};<br>
+<br>
+class VarStreamArrayIterator {<br>
+public:<br>
+  VarStreamArrayIterator(const VarStreamArray &Array)<br>
+      : Array(&Array), IterRef(Array.Stream) {<br>
+    ThisLen = Array.Len(IterRef);<br>
+  }<br>
+  VarStreamArrayIterator() : Array(nullptr), IterRef() {}<br>
+  bool operator==(const VarStreamArrayIterator &R) const {<br>
+    if (Array && R.Array) {<br>
+      // Both have a valid array, make sure they're same.<br>
+      assert(Array == R.Array);<br>
+      return IterRef == R.IterRef;<br>
+    }<br>
+<br>
+    // Both iterators are at the end.<br>
+    if (!Array && !R.Array)<br>
+      return true;<br>
+<br>
+    // One is not at the end and one is.<br>
+    return false;<br>
+  }<br>
+<br>
+  bool operator!=(const VarStreamArrayIterator &R) { return !(*this == R); }<br>
+<br>
+  StreamRef operator*() const {<br>
+    ArrayRef<uint8_t> Result;<br>
+    return IterRef.keep_front(ThisLen);<br>
+  }<br>
+<br>
+  VarStreamArrayIterator &operator++() {<br>
+    if (!Array || IterRef.getLength() == 0)<br>
+      return *this;<br>
+    IterRef = IterRef.drop_front(ThisLen);<br>
+    if (IterRef.getLength() == 0) {<br>
+      Array = nullptr;<br>
+      ThisLen = 0;<br>
+    } else {<br>
+      ThisLen = Array->Len(IterRef);<br>
+    }<br>
+    return *this;<br>
+  }<br>
+<br>
+  VarStreamArrayIterator operator++(int) {<br>
+    VarStreamArrayIterator Original = *this;<br>
+    ++*this;<br>
+    return Original;<br>
+  }<br>
+<br>
+private:<br>
+  const VarStreamArray *Array;<br>
+  uint32_t ThisLen;<br>
+  StreamRef IterRef;<br>
+};<br>
+<br>
+inline VarStreamArrayIterator VarStreamArray::begin() const {<br>
+  return VarStreamArrayIterator(*this);<br>
+}<br>
+inline VarStreamArrayIterator VarStreamArray::end() const {<br>
+  return VarStreamArrayIterator();<br>
+}<br>
+<br>
+template <typename T> class FixedStreamArrayIterator;<br>
+<br>
+template <typename T> class FixedStreamArray {<br>
+  friend class FixedStreamArrayIterator<T>;<br>
+  static_assert(std::is_trivially_constructible<T>::value,<br>
+                "FixedStreamArray must be used with trivial types");<br>
+<br>
+public:<br>
+  FixedStreamArray() : Stream() {}<br>
+  FixedStreamArray(StreamRef Stream) : Stream(Stream) {<br>
+    assert(Stream.getLength() % sizeof(T) == 0);<br>
+  }<br>
+<br>
+  const T &operator[](uint32_t Index) const {<br>
+    assert(Index < size());<br>
+    uint32_t Off = Index * sizeof(T);<br>
+    ArrayRef<uint8_t> Data;<br>
+    if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {<br>
+      assert(false && "Unexpected failure reading from stream");<br>
+      // This should never happen since we asserted that the stream length was<br>
+      // an exact multiple of the element size.<br>
+      consumeError(std::move(EC));<br>
+    }<br>
+    return *reinterpret_cast<const T *>(Data.data());<br>
+  }<br>
+<br>
+  uint32_t size() const { return Stream.getLength() / sizeof(T); }<br>
+<br>
+  FixedStreamArrayIterator<T> begin() const {<br>
+    return FixedStreamArrayIterator<T>(*this, 0);<br>
+  }<br>
+  FixedStreamArrayIterator<T> end() const {<br>
+    return FixedStreamArrayIterator<T>(*this);<br>
+  }<br>
+<br>
+private:<br>
+  StreamRef Stream;<br>
+};<br>
+<br>
+template <typename T> class FixedStreamArrayIterator {<br>
+public:<br>
+  FixedStreamArrayIterator(const FixedStreamArray<T> &Array)<br>
+      : Array(Array), Index(uint32_t(-1)) {}<br>
+  FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)<br>
+      : Array(Array), Index(Index) {}<br>
+<br>
+  bool operator==(const FixedStreamArrayIterator<T> &R) {<br>
+    assert(&Array == &R.Array);<br>
+    return Index == R.Index;<br>
+  }<br>
+<br>
+  bool operator!=(const FixedStreamArrayIterator<T> &R) {<br>
+    return !(*this == R);<br>
+  }<br>
+<br>
+  const T &operator*() const { return Array[Index]; }<br>
+<br>
+  FixedStreamArrayIterator<T> &operator++() {<br>
+    if (Index == uint32_t(-1))<br>
+      return *this;<br>
+    if (++Index >= Array.size())<br>
+      Index = uint32_t(-1);<br>
+    return *this;<br>
+  }<br>
+<br>
+  FixedStreamArrayIterator<T> operator++(int) {<br>
+    FixedStreamArrayIterator<T> Original = *this;<br>
+    ++*this;<br>
+    return Original;<br>
+  }<br>
+<br>
+private:<br>
+  const FixedStreamArray<T> &Array;<br>
+  uint32_t Index;<br>
+};<br>
+<br>
+} // namespace codeview<br>
+} // namespace llvm<br>
+<br>
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamInterface.h Thu May 26 20:54:44 2016<br>
@@ -17,14 +17,21 @@<br>
 namespace llvm {<br>
 namespace codeview {<br>
<br>
+/// StreamInterface abstracts the notion of a data stream.  This way, an<br>
+/// implementation could implement trivial reading from a contiguous memory<br>
+/// buffer or, as in the case of PDB files, reading from a set of possibly<br>
+/// discontiguous blocks.  The implementation is required to return references<br>
+/// to stable memory, so if this is not possible (for example in the case of<br>
+/// a PDB file with discontiguous blocks, it must keep its own pool of temp<br>
+/// storage.<br>
 class StreamInterface {<br>
 public:<br>
   virtual ~StreamInterface() {}<br>
<br>
   virtual Error readBytes(uint32_t Offset,<br>
                           MutableArrayRef<uint8_t> Buffer) const = 0;<br>
-  virtual Error getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,<br>
-                            uint32_t Length) const = 0;<br>
+  virtual Error readBytes(uint32_t Offset, uint32_t Size,<br>
+                          ArrayRef<uint8_t> &Buffer) const = 0;<br>
<br>
   virtual uint32_t getLength() const = 0;<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h Thu May 26 20:54:44 2016<br>
@@ -11,6 +11,8 @@<br>
 #define LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H<br>
<br>
 #include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamInterface.h"<br>
 #include "llvm/Support/Endian.h"<br>
 #include "llvm/Support/Error.h"<br>
@@ -20,18 +22,42 @@<br>
 namespace llvm {<br>
 namespace codeview {<br>
<br>
+class StreamRef;<br>
+<br>
 class StreamReader {<br>
 public:<br>
   StreamReader(const StreamInterface &S);<br>
<br>
+  Error readBytes(uint32_t Size, ArrayRef<uint8_t> &Buffer);<br>
   Error readBytes(MutableArrayRef<uint8_t> Buffer);<br>
+  Error readInteger(uint16_t &Dest);<br>
   Error readInteger(uint32_t &Dest);<br>
-  Error readZeroString(std::string &Dest);<br>
+  Error readZeroString(StringRef &Dest);<br>
+  Error readFixedString(StringRef &Dest, uint32_t Length);<br>
+  Error readStreamRef(StreamRef &Ref);<br>
+  Error readStreamRef(StreamRef &Ref, uint32_t Length);<br>
+<br>
+  template <typename T> Error readObject(const T *&Dest) {<br>
+    ArrayRef<uint8_t> Buffer;<br>
+    if (auto EC = readBytes(sizeof(T), Buffer))<br>
+      return EC;<br>
+    Dest = reinterpret_cast<const T *>(Buffer.data());<br>
+    return Error::success();<br>
+  }<br>
<br>
-  template <typename T> Error readObject(T *Dest) {<br>
-    MutableArrayRef<uint8_t> Buffer(reinterpret_cast<uint8_t *>(Dest),<br>
-                                    sizeof(T));<br>
-    return readBytes(Buffer);<br>
+  template <typename T><br>
+  Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {<br>
+    if (NumItems == 0) {<br>
+      Array = FixedStreamArray<T>();<br>
+      return Error::success();<br>
+    }<br>
+    uint32_t Length = NumItems * sizeof(T);<br>
+    if (Offset + Length > Stream.getLength())<br>
+      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
+    StreamRef View(Stream, Offset, Length);<br>
+    Array = FixedStreamArray<T>(View);<br>
+    Offset += Length;<br>
+    return Error::success();<br>
   }<br>
<br>
   template <typename T> Error readArray(MutableArrayRef<T> Array) {<br>
@@ -40,8 +66,6 @@ public:<br>
     return readBytes(Casted);<br>
   }<br>
<br>
-  Error getArrayRef(ArrayRef<uint8_t> &Array, uint32_t Length);<br>
-<br>
   void setOffset(uint32_t Off) { Offset = Off; }<br>
   uint32_t getOffset() const { return Offset; }<br>
   uint32_t getLength() const { return Stream.getLength(); }<br>
<br>
Added: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h?rev=270951&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h?rev=270951&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h (added)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamRef.h Thu May 26 20:54:44 2016<br>
@@ -0,0 +1,82 @@<br>
+//===- StreamRef.h - A copyable reference to a stream -----------*- 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_CODEVIEW_STREAMREF_H<br>
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H<br>
+<br>
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"<br>
+<br>
+namespace llvm {<br>
+namespace codeview {<br>
+<br>
+class StreamRef : public StreamInterface {<br>
+public:<br>
+  StreamRef() : Stream(nullptr), ViewOffset(0), Length(0) {}<br>
+  StreamRef(const StreamInterface &Stream)<br>
+      : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {}<br>
+  StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)<br>
+      : Stream(&Stream), ViewOffset(Offset), Length(Length) {}<br>
+  StreamRef(const StreamRef &Other)<br>
+      : Stream(Other.Stream), ViewOffset(Other.ViewOffset),<br>
+        Length(Other.Length) {}<br>
+<br>
+  Error readBytes(uint32_t Offset,<br>
+                  MutableArrayRef<uint8_t> Buffer) const override {<br>
+    return Stream->readBytes(ViewOffset + Offset, Buffer);<br>
+  }<br>
+<br>
+  Error readBytes(uint32_t Offset, uint32_t Size,<br>
+                  ArrayRef<uint8_t> &Buffer) const override {<br>
+    return Stream->readBytes(ViewOffset + Offset, Size, Buffer);<br>
+  }<br>
+<br>
+  uint32_t getLength() const override { return Length; }<br>
+  StreamRef drop_front(uint32_t N) const {<br>
+    if (!Stream)<br>
+      return StreamRef();<br>
+<br>
+    N = std::min(N, Length);<br>
+    return StreamRef(*Stream, ViewOffset + N, Length - N);<br>
+  }<br>
+<br>
+  StreamRef keep_front(uint32_t N) const {<br>
+    if (!Stream)<br>
+      return StreamRef();<br>
+    N = std::min(N, Length);<br>
+    return StreamRef(*Stream, ViewOffset, N);<br>
+  }<br>
+<br>
+  bool operator==(const StreamRef &Other) const {<br>
+    if (Stream != Other.Stream)<br>
+      return false;<br>
+    if (ViewOffset != Other.ViewOffset)<br>
+      return false;<br>
+    if (Length != Other.Length)<br>
+      return false;<br>
+    return true;<br>
+  }<br>
+<br>
+  bool operator!=(const StreamRef &Other) const { return !(*this == Other); }<br>
+<br>
+  StreamRef &operator=(const StreamRef &Other) {<br>
+    Stream = Other.Stream;<br>
+    ViewOffset = Other.ViewOffset;<br>
+    Length = Other.Length;<br>
+    return *this;<br>
+  }<br>
+<br>
+private:<br>
+  const StreamInterface *Stream;<br>
+  uint32_t ViewOffset;<br>
+  uint32_t Length;<br>
+};<br>
+}<br>
+}<br>
+<br>
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H<br>
\ No newline at end of file<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Thu May 26 20:54:44 2016<br>
@@ -11,6 +11,8 @@<br>
 #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H<br>
<br>
 #include "llvm/DebugInfo/CodeView/ByteStream.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
 #include "llvm/DebugInfo/PDB/PDBTypes.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
@@ -62,15 +64,16 @@ private:<br>
   std::vector<ModuleInfoEx> ModuleInfos;<br>
   NameHashTable ECNames;<br>
<br>
-  codeview::ByteStream ModInfoSubstream;<br>
-  codeview::ByteStream SecContrSubstream;<br>
-  codeview::ByteStream SecMapSubstream;<br>
-  codeview::ByteStream FileInfoSubstream;<br>
-  codeview::ByteStream TypeServerMapSubstream;<br>
-  codeview::ByteStream ECSubstream;<br>
-  codeview::ByteStream DbgHeader;<br>
+  codeview::StreamRef ModInfoSubstream;<br>
+  codeview::StreamRef SecContrSubstream;<br>
+  codeview::StreamRef SecMapSubstream;<br>
+  codeview::StreamRef FileInfoSubstream;<br>
+  codeview::StreamRef TypeServerMapSubstream;<br>
+  codeview::StreamRef ECSubstream;<br>
<br>
-  std::unique_ptr<HeaderInfo> Header;<br>
+  codeview::FixedStreamArray<support::ulittle16_t> DbgStreams;<br>
+<br>
+  const HeaderInfo *Header;<br>
 };<br>
 }<br>
 }<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h?rev=270951&r1=270950&r2=270951&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 Thu May 26 20:54:44 2016<br>
@@ -11,7 +11,9 @@<br>
 #define LLVM_DEBUGINFO_PDB_RAW_MAPPEDBLOCKSTREAM_H<br>
<br>
 #include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamInterface.h"<br>
+#include "llvm/Support/Allocator.h"<br>
 #include "llvm/Support/Error.h"<br>
 #include <cstdint><br>
 #include <vector><br>
@@ -27,14 +29,19 @@ public:<br>
<br>
   Error readBytes(uint32_t Offset,<br>
                   MutableArrayRef<uint8_t> Buffer) const override;<br>
-  Error getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,<br>
-                    uint32_t Length) const override;<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>
<br>
 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>
+  mutable llvm::BumpPtrAllocator Pool;<br>
+  mutable DenseMap<uint32_t, uint8_t *> CacheMap;<br>
   const PDBFile &Pdb;<br>
 };<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h Thu May 26 20:54:44 2016<br>
@@ -11,6 +11,7 @@<br>
 #define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H<br>
<br>
 #include "llvm/ADT/StringRef.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
 #include <cstdint><br>
 #include <vector><br>
<br>
@@ -22,7 +23,8 @@ private:<br>
   struct FileLayout;<br>
<br>
 public:<br>
-  ModInfo(const uint8_t *Bytes);<br>
+  ModInfo(codeview::StreamRef Stream);<br>
+  ModInfo(const ModInfo &Info);<br>
   ~ModInfo();<br>
<br>
   bool hasECInfo() const;<br>
@@ -38,32 +40,26 @@ public:<br>
   StringRef getModuleName() const;<br>
   StringRef getObjFileName() const;<br>
<br>
+  uint32_t getRecordLength() const;<br>
+<br>
 private:<br>
+  StringRef ModuleName;<br>
+  StringRef ObjFileName;<br>
   const FileLayout *Layout;<br>
 };<br>
<br>
 struct ModuleInfoEx {<br>
-  ModuleInfoEx(ModInfo Module) : Info(Module) {}<br>
+  ModuleInfoEx(codeview::StreamRef Stream) : Info(Stream) {}<br>
+  ModuleInfoEx(const ModuleInfoEx &Ex)<br>
+      : Info(Ex.Info), SourceFiles(Ex.SourceFiles) {}<br>
<br>
   ModInfo Info;<br>
   std::vector<StringRef> SourceFiles;<br>
 };<br>
<br>
-class ModInfoIterator {<br>
-public:<br>
-  ModInfoIterator(const uint8_t *Stream);<br>
-  ModInfoIterator(const ModInfoIterator &Other);<br>
-<br>
-  ModInfo operator*();<br>
-  ModInfoIterator &operator++();<br>
-  ModInfoIterator operator++(int);<br>
-  bool operator==(const ModInfoIterator &Other);<br>
-  bool operator!=(const ModInfoIterator &Other);<br>
-  ModInfoIterator &operator=(const ModInfoIterator &Other);<br>
-<br>
-private:<br>
-  const uint8_t *Bytes;<br>
-};<br>
+inline uint32_t ModInfoRecordLength(const codeview::StreamInterface &Stream) {<br>
+  return ModInfo(Stream).getRecordLength();<br>
+}<br>
<br>
 } // end namespace pdb<br>
 } // end namespace llvm<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=270951&r1=270950&r2=270951&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 Thu May 26 20:54:44 2016<br>
@@ -12,6 +12,7 @@<br>
<br>
 #include "llvm/ADT/iterator_range.h"<br>
 #include "llvm/DebugInfo/CodeView/ByteStream.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
 #include "llvm/Support/Error.h"<br>
@@ -36,9 +37,9 @@ private:<br>
   MappedBlockStream Stream;<br>
<br>
   codeview::ByteStream SymbolsSubstream;<br>
-  codeview::ByteStream LinesSubstream;<br>
-  codeview::ByteStream C13LinesSubstream;<br>
-  codeview::ByteStream GlobalRefsSubstream;<br>
+  codeview::StreamRef LinesSubstream;<br>
+  codeview::StreamRef C13LinesSubstream;<br>
+  codeview::StreamRef GlobalRefsSubstream;<br>
 };<br>
 }<br>
 }<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h Thu May 26 20:54:44 2016<br>
@@ -12,7 +12,7 @@<br>
<br>
 #include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
-#include "llvm/DebugInfo/CodeView/ByteStream.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
 #include "llvm/Support/Error.h"<br>
 #include <cstdint><br>
 #include <vector><br>
@@ -39,7 +39,7 @@ public:<br>
   ArrayRef<uint32_t> name_ids() const;<br>
<br>
 private:<br>
-  codeview::ByteStream NamesBuffer;<br>
+  codeview::StreamRef NamesBuffer;<br>
   std::vector<uint32_t> IDs;<br>
   uint32_t Signature;<br>
   uint32_t HashVersion;<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h Thu May 26 20:54:44 2016<br>
@@ -57,8 +57,8 @@ private:<br>
   std::vector<uint32_t> ThunkMap;<br>
   std::vector<uint32_t> SectionOffsets;<br>
<br>
-  std::unique_ptr<HeaderInfo> Header;<br>
-  std::unique_ptr<GSIHashHeader> HashHdr;<br>
+  const HeaderInfo *Header;<br>
+  const GSIHashHeader *HashHdr;<br>
 };<br>
 }<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=270951&r1=270950&r2=270951&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 Thu May 26 20:54:44 2016<br>
@@ -11,6 +11,7 @@<br>
 #define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H<br>
<br>
 #include "llvm/DebugInfo/CodeView/ByteStream.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
 #include "llvm/DebugInfo/CodeView/TypeStream.h"<br>
 #include "llvm/DebugInfo/PDB/PDBTypes.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"<br>
@@ -48,11 +49,11 @@ private:<br>
   HashFunctionType HashFunction;<br>
<br>
   codeview::ByteStream RecordsBuffer;<br>
-  codeview::ByteStream TypeIndexOffsetBuffer;<br>
-  codeview::ByteStream HashValuesBuffer;<br>
-  codeview::ByteStream HashAdjBuffer;<br>
+  codeview::StreamRef TypeIndexOffsetBuffer;<br>
+  codeview::StreamRef HashValuesBuffer;<br>
+  codeview::StreamRef HashAdjBuffer;<br>
<br>
-  std::unique_ptr<HeaderInfo> Header;<br>
+  const HeaderInfo *Header;<br>
 };<br>
 }<br>
 }<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/CodeView/ByteStream.cpp Thu May 26 20:54:44 2016<br>
@@ -17,31 +17,24 @@ using namespace llvm::codeview;<br>
<br>
 ByteStream::ByteStream() {}<br>
<br>
-ByteStream::ByteStream(MutableArrayRef<uint8_t> Bytes) { initialize(Bytes); }<br>
+ByteStream::ByteStream(MutableArrayRef<uint8_t> Data) : Data(Data) {}<br>
<br>
-ByteStream::ByteStream(uint32_t Length) { initialize(Length); }<br>
-<br>
-ByteStream::~ByteStream() { reset(); }<br>
+ByteStream::~ByteStream() {}<br>
<br>
 void ByteStream::reset() {<br>
   Ownership.reset();<br>
   Data = MutableArrayRef<uint8_t>();<br>
 }<br>
<br>
-void ByteStream::initialize(MutableArrayRef<uint8_t> Bytes) {<br>
-  reset();<br>
-  Data = Bytes;<br>
-}<br>
-<br>
-void ByteStream::initialize(uint32_t Length) {<br>
+void ByteStream::load(uint32_t Length) {<br>
   reset();<br>
   if (Length > 0)<br>
     Data = MutableArrayRef<uint8_t>(new uint8_t[Length], Length);<br>
   Ownership.reset(Data.data());<br>
 }<br>
<br>
-Error ByteStream::initialize(StreamReader &Reader, uint32_t Length) {<br>
-  initialize(Length);<br>
+Error ByteStream::load(StreamReader &Reader, uint32_t Length) {<br>
+  load(Length);<br>
   auto EC = Reader.readBytes(Data);<br>
   if (EC)<br>
     reset();<br>
@@ -52,15 +45,15 @@ Error ByteStream::readBytes(uint32_t Off<br>
                             MutableArrayRef<uint8_t> Buffer) const {<br>
   if (Data.size() < Buffer.size() + Offset)<br>
     return make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
-  ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size());<br>
+  ::memcpy(Buffer.data() + Offset, Data.data(), Buffer.size());<br>
   return Error::success();<br>
 }<br>
<br>
-Error ByteStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,<br>
-                              uint32_t Length) const {<br>
-  if (Data.size() < Length + Offset)<br>
+Error ByteStream::readBytes(uint32_t Offset, uint32_t Size,<br>
+                            ArrayRef<uint8_t> &Buffer) const {<br>
+  if (Data.size() < Buffer.size() + Offset)<br>
     return make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
-  Buffer = Data.slice(Offset, Length);<br>
+  Buffer = Data.slice(Offset, Size);<br>
   return Error::success();<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/CodeView/StreamReader.cpp Thu May 26 20:54:44 2016<br>
@@ -10,12 +10,20 @@<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
<br>
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"<br>
+#include "llvm/DebugInfo/CodeView/StreamRef.h"<br>
<br>
 using namespace llvm;<br>
 using namespace llvm::codeview;<br>
<br>
 StreamReader::StreamReader(const StreamInterface &S) : Stream(S), Offset(0) {}<br>
<br>
+Error StreamReader::readBytes(uint32_t Size, ArrayRef<uint8_t> &Buffer) {<br>
+  if (auto EC = Stream.readBytes(Offset, Size, Buffer))<br>
+    return EC;<br>
+  Offset += Size;<br>
+  return Error::success();<br>
+}<br>
+<br>
 Error StreamReader::readBytes(MutableArrayRef<uint8_t> Buffer) {<br>
   if (auto EC = Stream.readBytes(Offset, Buffer))<br>
     return EC;<br>
@@ -23,29 +31,63 @@ Error StreamReader::readBytes(MutableArr<br>
   return Error::success();<br>
 }<br>
<br>
+Error StreamReader::readInteger(uint16_t &Dest) {<br>
+  const support::ulittle16_t *P;<br>
+  if (auto EC = readObject(P))<br>
+    return EC;<br>
+  Dest = *P;<br>
+  return Error::success();<br>
+}<br>
+<br>
 Error StreamReader::readInteger(uint32_t &Dest) {<br>
-  support::ulittle32_t P;<br>
-  if (auto EC = readObject(&P))<br>
+  const support::ulittle32_t *P;<br>
+  if (auto EC = readObject(P))<br>
     return EC;<br>
-  Dest = P;<br>
+  Dest = *P;<br>
   return Error::success();<br>
 }<br>
<br>
-Error StreamReader::readZeroString(std::string &Dest) {<br>
-  Dest.clear();<br>
-  char C;<br>
+Error StreamReader::readZeroString(StringRef &Dest) {<br>
+  uint32_t Length = 0;<br>
+  // First compute the length of the string by reading 1 byte at a time.<br>
+  uint32_t OriginalOffset = getOffset();<br>
+  const char *C;<br>
   do {<br>
-    if (auto EC = readObject(&C))<br>
+    if (auto EC = readObject(C))<br>
       return EC;<br>
-    if (C != '\0')<br>
-      Dest.push_back(C);<br>
-  } while (C != '\0');<br>
+    if (*C != '\0')<br>
+      ++Length;<br>
+  } while (*C != '\0');<br>
+  // Now go back and request a reference for that many bytes.<br>
+  uint32_t NewOffset = getOffset();<br>
+  setOffset(OriginalOffset);<br>
+<br>
+  ArrayRef<uint8_t> Data;<br>
+  if (auto EC = readBytes(Length, Data))<br>
+    return EC;<br>
+  Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size());<br>
+<br>
+  // Now set the offset back to where it was after we calculated the length.<br>
+  setOffset(NewOffset);<br>
   return Error::success();<br>
 }<br>
<br>
-Error StreamReader::getArrayRef(ArrayRef<uint8_t> &Array, uint32_t Length) {<br>
-  if (auto EC = Stream.getArrayRef(Offset, Array, Length))<br>
+Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) {<br>
+  ArrayRef<uint8_t> Bytes;<br>
+  if (auto EC = readBytes(Length, Bytes))<br>
     return EC;<br>
+  Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size());<br>
+  return Error::success();<br>
+}<br>
+<br>
+Error StreamReader::readStreamRef(StreamRef &Ref) {<br>
+  return readStreamRef(Ref, bytesRemaining());<br>
+}<br>
+<br>
+Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) {<br>
+  if (bytesRemaining() < Length)<br>
+    return make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
+  Ref = StreamRef(Stream, Offset, Length);<br>
   Offset += Length;<br>
   return Error::success();<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Thu May 26 20:54:44 2016<br>
@@ -42,6 +42,7 @@ add_pdb_impl_folder(Raw<br>
   Raw/SymbolStream.cpp<br>
   Raw/TpiStream.cpp)<br>
<br>
+list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/Raw")<br>
 list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")<br>
<br>
 add_llvm_library(LLVMDebugInfoPDB<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Thu May 26 20:54:44 2016<br>
@@ -6,9 +6,9 @@<br>
 // License. See LICENSE.TXT for details.<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
-<br>
 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"<br>
<br>
+#include "llvm/DebugInfo/CodeView/StreamArray.h"<br>
 #include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
@@ -73,7 +73,8 @@ struct DbiStream::HeaderInfo {<br>
   ulittle32_t Reserved; // Pad to 64 bytes<br>
 };<br>
<br>
-DbiStream::DbiStream(PDBFile &File) : Pdb(File), Stream(StreamDBI, File) {<br>
+DbiStream::DbiStream(PDBFile &File)<br>
+    : Pdb(File), Stream(StreamDBI, File), Header(nullptr) {<br>
   static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");<br>
 }<br>
<br>
@@ -82,12 +83,10 @@ DbiStream::~DbiStream() {}<br>
 Error DbiStream::reload() {<br>
   codeview::StreamReader Reader(Stream);<br>
<br>
-  Header.reset(new HeaderInfo());<br>
-<br>
   if (Stream.getLength() < sizeof(HeaderInfo))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "DBI Stream does not contain a header.");<br>
-  if (auto EC = Reader.readObject(Header.get()))<br>
+  if (auto EC = Reader.readObject(Header))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "DBI Stream does not contain a header.");<br>
<br>
@@ -137,30 +136,31 @@ Error DbiStream::reload() {<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "DBI type server substream not aligned.");<br>
<br>
-  if (auto EC = ModInfoSubstream.initialize(Reader, Header->ModiSubstreamSize))<br>
+  if (auto EC =<br>
+          Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))<br>
     return EC;<br>
<br>
   // Since each ModInfo in the stream is a variable length, we have to iterate<br>
   // them to know how many there actually are.<br>
-  auto Range =<br>
-      llvm::make_range(ModInfoIterator(&ModInfoSubstream.data().front()),<br>
-                       ModInfoIterator(&ModInfoSubstream.data().back() + 1));<br>
-  for (auto Info : Range)<br>
-    ModuleInfos.push_back(ModuleInfoEx(Info));<br>
+  codeview::VarStreamArray ModInfoArray(ModInfoSubstream, ModInfoRecordLength);<br>
+  for (auto Info : ModInfoArray) {<br>
+    ModuleInfos.emplace_back(Info);<br>
+  }<br>
<br>
-  if (auto EC =<br>
-          SecContrSubstream.initialize(Reader, Header->SecContrSubstreamSize))<br>
+  if (auto EC = Reader.readStreamRef(SecContrSubstream,<br>
+                                     Header->SecContrSubstreamSize))<br>
     return EC;<br>
-  if (auto EC = SecMapSubstream.initialize(Reader, Header->SectionMapSize))<br>
+  if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize))<br>
     return EC;<br>
-  if (auto EC = FileInfoSubstream.initialize(Reader, Header->FileInfoSize))<br>
+  if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize))<br>
     return EC;<br>
   if (auto EC =<br>
-          TypeServerMapSubstream.initialize(Reader, Header->TypeServerSize))<br>
+          Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize))<br>
     return EC;<br>
-  if (auto EC = ECSubstream.initialize(Reader, Header->ECSubstreamSize))<br>
+  if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize))<br>
     return EC;<br>
-  if (auto EC = DbgHeader.initialize(Reader, Header->OptionalDbgHdrSize))<br>
+  if (auto EC = Reader.readArray(DbgStreams, Header->OptionalDbgHdrSize /<br>
+                                                 sizeof(ulittle16_t)))<br>
     return EC;<br>
<br>
   if (auto EC = initializeFileInfo())<br>
@@ -247,25 +247,30 @@ Error DbiStream::initializeFileInfo() {<br>
   // with the caveat that `NumSourceFiles` cannot be trusted, so<br>
   // it is computed by summing `ModFileCounts`.<br>
   //<br>
-  const uint8_t *Buf = &FileInfoSubstream.data().front();<br>
-  auto FI = reinterpret_cast<const FileInfoSubstreamHeader *>(Buf);<br>
-  Buf += sizeof(FileInfoSubstreamHeader);<br>
+  const FileInfoSubstreamHeader *FH;<br>
+  codeview::StreamReader FISR(FileInfoSubstream);<br>
+  if (auto EC = FISR.readObject(FH))<br>
+    return EC;<br>
+<br>
   // The number of modules in the stream should be the same as reported by<br>
   // the FileInfoSubstreamHeader.<br>
-  if (FI->NumModules != ModuleInfos.size())<br>
+  if (FH->NumModules != ModuleInfos.size())<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "FileInfo substream count doesn't match DBI.");<br>
<br>
+  codeview::FixedStreamArray<ulittle16_t> ModIndexArray;<br>
+  codeview::FixedStreamArray<ulittle16_t> ModFileCountArray;<br>
+  codeview::FixedStreamArray<little32_t> FileNameOffsets;<br>
+<br>
   // First is an array of `NumModules` module indices.  This is not used for the<br>
   // same reason that `NumSourceFiles` is not used.  It's an array of uint16's,<br>
   // but it's possible there are more than 64k source files, which would imply<br>
   // more than 64k modules (e.g. object files) as well.  So we ignore this<br>
   // field.<br>
-  llvm::ArrayRef<ulittle16_t> ModIndexArray(<br>
-      reinterpret_cast<const ulittle16_t *>(Buf), ModuleInfos.size());<br>
-<br>
-  llvm::ArrayRef<ulittle16_t> ModFileCountArray(ModIndexArray.end(),<br>
-                                                ModuleInfos.size());<br>
+  if (auto EC = FISR.readArray(ModIndexArray, ModuleInfos.size()))<br>
+    return EC;<br>
+  if (auto EC = FISR.readArray(ModFileCountArray, ModuleInfos.size()))<br>
+    return EC;<br>
<br>
   // Compute the real number of source files.<br>
   uint32_t NumSourceFiles = 0;<br>
@@ -280,11 +285,13 @@ Error DbiStream::initializeFileInfo() {<br>
   // them in `ModuleInfoEx`.  The value written to and read from the file is<br>
   // not used anyway, it is only there as a way to store the offsets for the<br>
   // purposes of later accessing the names at runtime.<br>
-  llvm::ArrayRef<little32_t> FileNameOffsets(<br>
-      reinterpret_cast<const little32_t *>(ModFileCountArray.end()),<br>
-      NumSourceFiles);<br>
+  if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))<br>
+    return EC;<br>
<br>
-  const char *Names = reinterpret_cast<const char *>(FileNameOffsets.end());<br>
+  codeview::StreamRef NamesBufferRef;<br>
+  if (auto EC = FISR.readStreamRef(NamesBufferRef))<br>
+    return EC;<br>
+  codeview::StreamReader Names(NamesBufferRef);<br>
<br>
   // We go through each ModuleInfo, determine the number N of source files for<br>
   // that module, and then get the next N offsets from the Offsets array, using<br>
@@ -295,8 +302,10 @@ Error DbiStream::initializeFileInfo() {<br>
     uint32_t NumFiles = ModFileCountArray[I];<br>
     ModuleInfos[I].SourceFiles.resize(NumFiles);<br>
     for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) {<br>
-      uint32_t FileIndex = FileNameOffsets[NextFileIndex];<br>
-      ModuleInfos[I].SourceFiles[J] = StringRef(Names + FileIndex);<br>
+      uint32_t FileOffset = FileNameOffsets[NextFileIndex];<br>
+      Names.setOffset(FileOffset);<br>
+      if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J]))<br>
+        return EC;<br>
     }<br>
   }<br>
<br>
@@ -304,13 +313,5 @@ Error DbiStream::initializeFileInfo() {<br>
 }<br>
<br>
 uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {<br>
-  ArrayRef<uint8_t> DbgData;<br>
-  if (auto EC = DbgHeader.getArrayRef(0, DbgData, DbgHeader.getLength())) {<br>
-    consumeError(std::move(EC));<br>
-    return uint32_t(-1);<br>
-  }<br>
-  ArrayRef<ulittle16_t> DebugStreams(<br>
-      reinterpret_cast<const ulittle16_t *>(DbgData.data()),<br>
-      DbgData.size() / sizeof(ulittle16_t));<br>
-  return DebugStreams[static_cast<uint16_t>(Type)];<br>
+  return DbgStreams[static_cast<uint16_t>(Type)];<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp Thu May 26 20:54:44 2016<br>
@@ -29,19 +29,19 @@ Error InfoStream::reload() {<br>
     PDB_UniqueId Guid;<br>
   };<br>
<br>
-  Header H;<br>
-  if (auto EC = Reader.readObject(&H))<br>
+  const Header *H;<br>
+  if (auto EC = Reader.readObject(H))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "PDB Stream does not contain a header.");<br>
<br>
-  if (H.Version < PdbRaw_ImplVer::PdbImplVC70)<br>
+  if (H->Version < PdbRaw_ImplVer::PdbImplVC70)<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Unsupported PDB stream version.");<br>
<br>
-  Version = H.Version;<br>
-  Signature = H.Signature;<br>
-  Age = H.Age;<br>
-  Guid = H.Guid;<br>
+  Version = H->Version;<br>
+  Signature = H->Signature;<br>
+  Age = H->Age;<br>
+  Guid = H->Guid;<br>
<br>
   return NamedStreams.load(Reader);<br>
 }<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp Thu May 26 20:54:44 2016<br>
@@ -23,6 +23,69 @@ MappedBlockStream::MappedBlockStream(uin<br>
   }<br>
 }<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 (Buffer.size() > StreamLength)<br>
+    return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
+  if (Offset > StreamLength - Buffer.size())<br>
+    return make_error<RawError>(raw_error_code::insufficient_buffer);<br>
+<br>
+  if (tryReadContiguously(Offset, Size, Buffer))<br>
+    return Error::success();<br>
+<br>
+  auto CacheIter = CacheMap.find(Offset);<br>
+  if (CacheIter != CacheMap.end()) {<br>
+    // In a more general solution, we would need to guarantee that the<br>
+    // cached allocation is at least the requested size.  In practice, since<br>
+    // these are CodeView / PDB records, we know they are always formatted<br>
+    // the same way and never change, so we should never be requesting two<br>
+    // allocations from the same address with different sizes.<br>
+    Buffer = ArrayRef<uint8_t>(CacheIter->second, Size);<br>
+    return Error::success();<br>
+  }<br>
+<br>
+  // Otherwise allocate a large enough buffer in the pool, memcpy the data<br>
+  // into it, and return an ArrayRef to that.<br>
+  uint8_t *WriteBuffer = Pool.Allocate<uint8_t>(Size);<br>
+<br>
+  if (auto EC = readBytes(Offset, MutableArrayRef<uint8_t>(WriteBuffer, Size)))<br>
+    return EC;<br>
+  CacheMap.insert(std::make_pair(Offset, WriteBuffer));<br>
+  Buffer = ArrayRef<uint8_t>(WriteBuffer, Size);<br>
+  return Error::success();<br>
+}<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>
+  // This can work even if the request crosses a block boundary, provided that<br>
+  // all subsequent blocks are contiguous.  For example, a 10k read with a 4k<br>
+  // block size can be filled with a reference if, from the starting offset,<br>
+  // 3 blocks in a row are contiguous.<br>
+  uint32_t BlockNum = Offset / Pdb.getBlockSize();<br>
+  uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();<br>
+  uint32_t BytesFromFirstBlock =<br>
+      std::min(Size, Pdb.getBlockSize() - OffsetInBlock);<br>
+  uint32_t NumAdditionalBlocks =<br>
+      llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /<br>
+      Pdb.getBlockSize();<br>
+<br>
+  uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;<br>
+  uint32_t E = BlockList[BlockNum];<br>
+  for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {<br>
+    if (BlockList[I + BlockNum] != E)<br>
+      return false;<br>
+  }<br>
+<br>
+  uint32_t FirstBlockAddr = BlockList[BlockNum];<br>
+  StringRef Str = Pdb.getBlockData(FirstBlockAddr, Pdb.getBlockSize());<br>
+  Str = Str.drop_front(OffsetInBlock);<br>
+  Buffer =<br>
+      ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Str.data()), Size);<br>
+  return true;<br>
+}<br>
+<br>
 Error MappedBlockStream::readBytes(uint32_t Offset,<br>
                                    MutableArrayRef<uint8_t> Buffer) const {<br>
   uint32_t BlockNum = Offset / Pdb.getBlockSize();<br>
@@ -54,27 +117,5 @@ Error MappedBlockStream::readBytes(uint3<br>
   }<br>
<br>
   return Error::success();<br>
-}<br>
<br>
-Error MappedBlockStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,<br>
-                                     uint32_t Length) const {<br>
-  uint32_t BlockNum = Offset / Pdb.getBlockSize();<br>
-  uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();<br>
-  uint32_t BytesAvailableInBlock = Pdb.getBlockSize() - OffsetInBlock;<br>
-<br>
-  // If this is the last block in the stream, not all of the data is valid.<br>
-  if (BlockNum == BlockList.size() - 1) {<br>
-    uint32_t AllocatedBytesInBlock = StreamLength % Pdb.getBlockSize();<br>
-    if (AllocatedBytesInBlock < BytesAvailableInBlock)<br>
-      BytesAvailableInBlock = AllocatedBytesInBlock;<br>
-  }<br>
-  if (BytesAvailableInBlock < Length)<br>
-    return make_error<RawError>(raw_error_code::feature_unsupported);<br>
-<br>
-  uint32_t StreamBlockAddr = BlockList[BlockNum];<br>
-  StringRef Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize());<br>
-  Data = Data.substr(OffsetInBlock, Length);<br>
-<br>
-  Buffer = ArrayRef<uint8_t>(Data.bytes_begin(), Data.bytes_end());<br>
-  return Error::success();<br>
 }<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp Thu May 26 20:54:44 2016<br>
@@ -8,6 +8,8 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"<br>
+<br>
+#include "llvm/DebugInfo/CodeView/StreamReader.h"<br>
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"<br>
 #include "llvm/Support/Endian.h"<br>
<br>
@@ -16,6 +18,7 @@ using namespace llvm::pdb;<br>
 using namespace llvm::support;<br>
<br>
 namespace {<br>
+<br>
 struct SCBytes {<br>
   ulittle16_t Section;<br>
   char Padding1[2];<br>
@@ -60,17 +63,29 @@ struct ModInfo::FileLayout {<br>
                              // for now since it is unused.<br>
   ulittle32_t SrcFileNameNI; // Name Index for src file name<br>
   ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB<br>
-  char VarInfo[1];           // Module name followed by Obj File Name<br>
-<br>
-  StringRef getModuleName() const { return StringRef(VarInfo); }<br>
+                             // Null terminated Module name<br>
+                             // Null terminated Obj File Name<br>
+};<br>
<br>
-  StringRef getObjectFileName() const {<br>
-    return StringRef(getModuleName().end() + 1);<br>
+ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) {<br>
+  codeview::StreamReader Reader(Stream);<br>
+  if (auto EC = Reader.readObject(Layout)) {<br>
+    consumeError(std::move(EC));<br>
+    return;<br>
   }<br>
-};<br>
+  if (auto EC = Reader.readZeroString(ModuleName)) {<br>
+    consumeError(std::move(EC));<br>
+    return;<br>
+  }<br>
+  if (auto EC = Reader.readZeroString(ObjFileName)) {<br>
+    consumeError(std::move(EC));<br>
+    return;<br>
+  }<br>
+}<br>
<br>
-ModInfo::ModInfo(const uint8_t *Bytes)<br>
-    : Layout(reinterpret_cast<const FileLayout *>(Bytes)) {}<br>
+ModInfo::ModInfo(const ModInfo &Info)<br>
+    : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName),<br>
+      Layout(Info.Layout) {}<br>
<br>
 ModInfo::~ModInfo() {}<br>
<br>
@@ -100,44 +115,14 @@ uint32_t ModInfo::getPdbFilePathNameInde<br>
   return Layout->PdbFilePathNI;<br>
 }<br>
<br>
-llvm::StringRef ModInfo::getModuleName() const {<br>
-  return Layout->getModuleName();<br>
-}<br>
-<br>
-llvm::StringRef ModInfo::getObjFileName() const {<br>
-  return Layout->getObjectFileName();<br>
-}<br>
-<br>
-ModInfoIterator::ModInfoIterator(const uint8_t *Stream) : Bytes(Stream) {}<br>
-<br>
-ModInfoIterator::ModInfoIterator(const ModInfoIterator &Other)<br>
-    : Bytes(Other.Bytes) {}<br>
-<br>
-ModInfo ModInfoIterator::operator*() { return ModInfo(Bytes); }<br>
-<br>
-ModInfoIterator &ModInfoIterator::operator++() {<br>
-  StringRef Obj = ModInfo(Bytes).getObjFileName();<br>
-  Bytes = Obj.bytes_end() + 1;<br>
-  Bytes = reinterpret_cast<const uint8_t *>(llvm::alignAddr(Bytes, 4));<br>
-<br>
-  return *this;<br>
-}<br>
+StringRef ModInfo::getModuleName() const { return ModuleName; }<br>
<br>
-ModInfoIterator ModInfoIterator::operator++(int) {<br>
-  ModInfoIterator Copy(*this);<br>
-  ++(*this);<br>
-  return Copy;<br>
-}<br>
-<br>
-bool ModInfoIterator::operator==(const ModInfoIterator &Other) {<br>
-  return Bytes == Other.Bytes;<br>
-}<br>
-<br>
-bool ModInfoIterator::operator!=(const ModInfoIterator &Other) {<br>
-  return !(*this == Other);<br>
-}<br>
+StringRef ModInfo::getObjFileName() const { return ObjFileName; }<br>
<br>
-ModInfoIterator &ModInfoIterator::operator=(const ModInfoIterator &Other) {<br>
-  Bytes = Other.Bytes;<br>
-  return *this;<br>
+uint32_t ModInfo::getRecordLength() const {<br>
+  uint32_t M = ModuleName.str().size() + 1;<br>
+  uint32_t O = ObjFileName.str().size() + 1;<br>
+  uint32_t Size = sizeof(FileLayout) + M + O;<br>
+  Size = llvm::alignTo(Size, 4);<br>
+  return Size;<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp Thu May 26 20:54:44 2016<br>
@@ -32,17 +32,17 @@ Error ModStream::reload() {<br>
     return llvm::make_error<RawError>(raw_error_code::corrupt_file,<br>
                                       "Module has both C11 and C13 line info");<br>
<br>
-  if (auto EC = SymbolsSubstream.initialize(Reader, SymbolSize))<br>
+  if (auto EC = SymbolsSubstream.load(Reader, SymbolSize))<br>
     return EC;<br>
-  if (auto EC = LinesSubstream.initialize(Reader, C11Size))<br>
+  if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))<br>
     return EC;<br>
-  if (auto EC = C13LinesSubstream.initialize(Reader, C13Size))<br>
+  if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))<br>
     return EC;<br>
<br>
   uint32_t GlobalRefsSize;<br>
   if (auto EC = Reader.readInteger(GlobalRefsSize))<br>
     return EC;<br>
-  if (auto EC = GlobalRefsSubstream.initialize(Reader, GlobalRefsSize))<br>
+  if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))<br>
     return EC;<br>
   if (Reader.bytesRemaining() > 0)<br>
     return llvm::make_error<RawError>(raw_error_code::corrupt_file,<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/NameHashTable.cpp Thu May 26 20:54:44 2016<br>
@@ -84,28 +84,28 @@ Error NameHashTable::load(codeview::Stre<br>
     support::ulittle32_t ByteSize;<br>
   };<br>
<br>
-  Header H;<br>
-  if (auto EC = Stream.readObject(&H))<br>
+  const Header *H;<br>
+  if (auto EC = Stream.readObject(H))<br>
     return EC;<br>
<br>
-  if (H.Signature != 0xEFFEEFFE)<br>
+  if (H->Signature != 0xEFFEEFFE)<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Invalid hash table signature");<br>
-  if (H.HashVersion != 1 && H.HashVersion != 2)<br>
+  if (H->HashVersion != 1 && H->HashVersion != 2)<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Unsupported hash version");<br>
<br>
-  Signature = H.Signature;<br>
-  HashVersion = H.HashVersion;<br>
-  if (auto EC = NamesBuffer.initialize(Stream, H.ByteSize))<br>
+  Signature = H->Signature;<br>
+  HashVersion = H->HashVersion;<br>
+  if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Invalid hash table byte length");<br>
<br>
-  support::ulittle32_t HashCount;<br>
-  if (auto EC = Stream.readObject(&HashCount))<br>
+  const support::ulittle32_t *HashCount;<br>
+  if (auto EC = Stream.readObject(HashCount))<br>
     return EC;<br>
<br>
-  std::vector<support::ulittle32_t> BucketArray(HashCount);<br>
+  std::vector<support::ulittle32_t> BucketArray(*HashCount);<br>
   if (auto EC = Stream.readArray<support::ulittle32_t>(BucketArray))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Could not read bucket array");<br>
@@ -124,7 +124,15 @@ StringRef NameHashTable::getStringForID(<br>
   if (ID == IDs[0])<br>
     return StringRef();<br>
<br>
-  return StringRef(NamesBuffer.str().begin() + ID);<br>
+  // NamesBuffer is a buffer of null terminated strings back to back.  ID is<br>
+  // the starting offset of the string we're looking for.  So just seek into<br>
+  // the desired offset and a read a null terminated stream from that offset.<br>
+  StringRef Result;<br>
+  codeview::StreamReader NameReader(NamesBuffer);<br>
+  NameReader.setOffset(ID);<br>
+  if (auto EC = NameReader.readZeroString(Result))<br>
+    consumeError(std::move(EC));<br>
+  return Result;<br>
 }<br>
<br>
 uint32_t NameHashTable::getIDForString(StringRef Str) const {<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp Thu May 26 20:54:44 2016<br>
@@ -113,7 +113,7 @@ Error NameMap::load(codeview::StreamRead<br>
     uint32_t StringOffset = StringsOffset + NameOffset;<br>
     uint32_t OldOffset = Stream.getOffset();<br>
     // Pump out our c-string from the stream.<br>
-    std::string Str;<br>
+    StringRef Str;<br>
     Stream.setOffset(StringOffset);<br>
     if (Stream.readZeroString(Str))<br>
       return make_error<RawError>(raw_error_code::corrupt_file,<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp Thu May 26 20:54:44 2016<br>
@@ -107,12 +107,11 @@ Error PublicsStream::reload() {<br>
                                 "Publics Stream does not contain a header.");<br>
<br>
   // Read PSGSIHDR and GSIHashHdr structs.<br>
-  Header.reset(new HeaderInfo());<br>
-  if (Reader.readObject(Header.get()))<br>
+  if (Reader.readObject(Header))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Publics Stream does not contain a header.");<br>
-  HashHdr.reset(new GSIHashHeader());<br>
-  if (Reader.readObject(HashHdr.get()))<br>
+<br>
+  if (Reader.readObject(HashHdr))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Publics Stream does not contain a header.");<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/SymbolStream.cpp Thu May 26 20:54:44 2016<br>
@@ -30,7 +30,7 @@ SymbolStream::~SymbolStream() {}<br>
 Error SymbolStream::reload() {<br>
   codeview::StreamReader Reader(MappedStream);<br>
<br>
-  if (Stream.initialize(Reader, MappedStream.getLength()))<br>
+  if (Stream.load(Reader, MappedStream.getLength()))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "Could not load symbol stream.");<br>
<br>
@@ -40,7 +40,7 @@ Error SymbolStream::reload() {<br>
 iterator_range<codeview::SymbolIterator> SymbolStream::getSymbols() const {<br>
   using codeview::SymbolIterator;<br>
   ArrayRef<uint8_t> Data;<br>
-  if (auto Error = Stream.getArrayRef(0, Data, Stream.getLength())) {<br>
+  if (auto Error = Stream.readBytes(0, Stream.getLength(), Data)) {<br>
     consumeError(std::move(Error));<br>
     return iterator_range<SymbolIterator>(SymbolIterator(), SymbolIterator());<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=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Thu May 26 20:54:44 2016<br>
@@ -68,8 +68,7 @@ Error TpiStream::reload() {<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "TPI Stream does not contain a header.");<br>
<br>
-  Header.reset(new HeaderInfo());<br>
-  if (Reader.readObject(Header.get()))<br>
+  if (Reader.readObject(Header))<br>
     return make_error<RawError>(raw_error_code::corrupt_file,<br>
                                 "TPI Stream does not contain a header.");<br>
<br>
@@ -93,7 +92,7 @@ Error TpiStream::reload() {<br>
   HashFunction = HashBufferV8;<br>
<br>
   // The actual type records themselves come from this stream<br>
-  if (auto EC = RecordsBuffer.initialize(Reader, Header->TypeRecordBytes))<br>
+  if (auto EC = RecordsBuffer.load(Reader, Header->TypeRecordBytes))<br>
     return EC;<br>
<br>
   // Hash indices, hash values, etc come from the hash stream.<br>
@@ -101,16 +100,16 @@ Error TpiStream::reload() {<br>
   codeview::StreamReader HSR(HS);<br>
   HSR.setOffset(Header->HashValueBuffer.Off);<br>
   if (auto EC =<br>
-          HashValuesBuffer.initialize(HSR, Header->HashValueBuffer.Length))<br>
+          HSR.readStreamRef(HashValuesBuffer, Header->HashValueBuffer.Length))<br>
     return EC;<br>
<br>
   HSR.setOffset(Header->HashAdjBuffer.Off);<br>
-  if (auto EC = HashAdjBuffer.initialize(HSR, Header->HashAdjBuffer.Length))<br>
+  if (auto EC = HSR.readStreamRef(HashAdjBuffer, Header->HashAdjBuffer.Length))<br>
     return EC;<br>
<br>
   HSR.setOffset(Header->IndexOffsetBuffer.Off);<br>
-  if (auto EC = TypeIndexOffsetBuffer.initialize(<br>
-          HSR, Header->IndexOffsetBuffer.Length))<br>
+  if (auto EC = HSR.readStreamRef(TypeIndexOffsetBuffer,<br>
+                                  Header->IndexOffsetBuffer.Length))<br>
     return EC;<br>
<br>
   return Error::success();<br>
<br>
Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=270951&r1=270950&r2=270951&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=270951&r1=270950&r2=270951&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)<br>
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Thu May 26 20:54:44 2016<br>
@@ -305,7 +305,7 @@ static Error dumpStreamSummary(ScopedPri<br>
       auto NSIter = NamedStreams.find(StreamIdx);<br>
       if (ModIter != ModStreams.end()) {<br>
         Value = "Module \"";<br>
-        Value += ModIter->second->Info.getModuleName();<br>
+        Value += ModIter->second->Info.getModuleName().str();<br>
         Value += "\"";<br>
       } else if (NSIter != NamedStreams.end()) {<br>
         Value = "Named Stream \"";<br>
@@ -354,7 +354,7 @@ static Error dumpStreamData(ScopedPrinte<br>
     ArrayRef<uint8_t> Data;<br>
     uint32_t BytesToReadInBlock = std::min(<br>
         R.bytesRemaining(), static_cast<uint32_t>(File.getBlockSize()));<br>
-    if (auto EC = R.getArrayRef(Data, BytesToReadInBlock))<br>
+    if (auto EC = R.readBytes(BytesToReadInBlock, Data))<br>
       return EC;<br>
     P.printBinaryBlock(<br>
         "Data",<br>
@@ -455,9 +455,9 @@ static Error dumpDbiStream(ScopedPrinter<br>
     ListScope L(P, "Modules");<br>
     for (auto &Modi : DS.modules()) {<br>
       DictScope DD(P);<br>
-      P.printString("Name", Modi.Info.getModuleName());<br>
+      P.printString("Name", Modi.Info.getModuleName().str());<br>
       P.printNumber("Debug Stream Index", Modi.Info.getModuleStreamIndex());<br>
-      P.printString("Object File Name", Modi.Info.getObjFileName());<br>
+      P.printString("Object File Name", Modi.Info.getObjFileName().str());<br>
       P.printNumber("Num Files", Modi.Info.getNumberOfFiles());<br>
       P.printNumber("Source File Name Idx", Modi.Info.getSourceFileNameIndex());<br>
       P.printNumber("Pdb File Name Idx", Modi.Info.getPdbFilePathNameIndex());<br>
@@ -472,7 +472,7 @@ static Error dumpDbiStream(ScopedPrinter<br>
             to_string(Modi.SourceFiles.size()) + " Contributing Source Files";<br>
         ListScope LL(P, FileListName);<br>
         for (auto File : Modi.SourceFiles)<br>
-          P.printString(File);<br>
+          P.printString(File.str());<br>
       }<br>
       bool HasModuleDI =<br>
           (Modi.Info.getModuleStreamIndex() < File.getNumStreams());<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>