[llvm] r277019 - [pdb] Refactor library to more clearly separate reading/writing

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 12:12:29 PDT 2016


Author: zturner
Date: Thu Jul 28 14:12:28 2016
New Revision: 277019

URL: http://llvm.org/viewvc/llvm-project?rev=277019&view=rev
Log:
[pdb] Refactor library to more clearly separate reading/writing

Reviewed By: amccarth, ruiu
Differential Revision: https://reviews.llvm.org/D22693

Removed:
    llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
    llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h
    llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h
    llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h
    llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h
    llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h
    llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h
    llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h
    llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h
    llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp
    llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp
    llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp
    llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp
    llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
    llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Thu Jul 28 14:12:28 2016
@@ -32,7 +32,7 @@ namespace msf {
 
 template <typename Kind>
 struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
-  Error operator()(StreamRef Stream, uint32_t &Len,
+  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
                    codeview::CVRecord<Kind> &Item) const {
     using namespace codeview;
     const RecordPrefix *Prefix = nullptr;

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h Thu Jul 28 14:12:28 2016
@@ -59,15 +59,15 @@ struct ColumnNumberEntry {
 class ModuleSubstream {
 public:
   ModuleSubstream();
-  ModuleSubstream(ModuleSubstreamKind Kind, msf::StreamRef Data);
-  static Error initialize(msf::StreamRef Stream, ModuleSubstream &Info);
+  ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);
+  static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);
   uint32_t getRecordLength() const;
   ModuleSubstreamKind getSubstreamKind() const;
-  msf::StreamRef getRecordData() const;
+  msf::ReadableStreamRef getRecordData() const;
 
 private:
   ModuleSubstreamKind Kind;
-  msf::StreamRef Data;
+  msf::ReadableStreamRef Data;
 };
 
 typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
@@ -75,7 +75,7 @@ typedef msf::VarStreamArray<ModuleSubstr
 
 namespace msf {
 template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {
-  Error operator()(StreamRef Stream, uint32_t &Length,
+  Error operator()(ReadableStreamRef Stream, uint32_t &Length,
                    codeview::ModuleSubstream &Info) const {
     if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))
       return EC;

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h Thu Jul 28 14:12:28 2016
@@ -38,23 +38,24 @@ class IModuleSubstreamVisitor {
 public:
   virtual ~IModuleSubstreamVisitor() {}
 
-  virtual Error visitUnknown(ModuleSubstreamKind Kind, msf::StreamRef Data) = 0;
-  virtual Error visitSymbols(msf::StreamRef Data);
-  virtual Error visitLines(msf::StreamRef Data,
+  virtual Error visitUnknown(ModuleSubstreamKind Kind,
+                             msf::ReadableStreamRef Data) = 0;
+  virtual Error visitSymbols(msf::ReadableStreamRef Data);
+  virtual Error visitLines(msf::ReadableStreamRef Data,
                            const LineSubstreamHeader *Header,
                            const LineInfoArray &Lines);
-  virtual Error visitStringTable(msf::StreamRef Data);
-  virtual Error visitFileChecksums(msf::StreamRef Data,
+  virtual Error visitStringTable(msf::ReadableStreamRef Data);
+  virtual Error visitFileChecksums(msf::ReadableStreamRef Data,
                                    const FileChecksumArray &Checksums);
-  virtual Error visitFrameData(msf::StreamRef Data);
-  virtual Error visitInlineeLines(msf::StreamRef Data);
-  virtual Error visitCrossScopeImports(msf::StreamRef Data);
-  virtual Error visitCrossScopeExports(msf::StreamRef Data);
-  virtual Error visitILLines(msf::StreamRef Data);
-  virtual Error visitFuncMDTokenMap(msf::StreamRef Data);
-  virtual Error visitTypeMDTokenMap(msf::StreamRef Data);
-  virtual Error visitMergedAssemblyInput(msf::StreamRef Data);
-  virtual Error visitCoffSymbolRVA(msf::StreamRef Data);
+  virtual Error visitFrameData(msf::ReadableStreamRef Data);
+  virtual Error visitInlineeLines(msf::ReadableStreamRef Data);
+  virtual Error visitCrossScopeImports(msf::ReadableStreamRef Data);
+  virtual Error visitCrossScopeExports(msf::ReadableStreamRef Data);
+  virtual Error visitILLines(msf::ReadableStreamRef Data);
+  virtual Error visitFuncMDTokenMap(msf::ReadableStreamRef Data);
+  virtual Error visitTypeMDTokenMap(msf::ReadableStreamRef Data);
+  virtual Error visitMergedAssemblyInput(msf::ReadableStreamRef Data);
+  virtual Error visitCoffSymbolRVA(msf::ReadableStreamRef Data);
 };
 
 Error visitModuleSubstream(const ModuleSubstream &R,
@@ -67,7 +68,7 @@ public:
   VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header)
       : Header(Header) {}
 
-  Error operator()(StreamRef Stream, uint32_t &Len,
+  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
                    codeview::LineColumnEntry &Item) const {
     using namespace codeview;
     const LineFileBlockHeader *BlockHeader;
@@ -104,7 +105,7 @@ private:
 
 template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
 public:
-  Error operator()(StreamRef Stream, uint32_t &Len,
+  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
                    codeview::FileChecksumEntry &Item) const {
     using namespace codeview;
     const FileChecksum *Header;

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h Thu Jul 28 14:12:28 2016
@@ -12,45 +12,147 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/Msf/MsfError.h"
 #include "llvm/DebugInfo/Msf/StreamInterface.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include <cstdint>
 #include <memory>
 #include <type_traits>
 
 namespace llvm {
 namespace msf {
-class StreamReader;
-
-template <bool Writable = false> class ByteStream : public StreamInterface {
-  typedef typename std::conditional<Writable, MutableArrayRef<uint8_t>,
-                                    ArrayRef<uint8_t>>::type ArrayType;
 
+class ByteStream : public ReadableStream {
 public:
   ByteStream() {}
-  explicit ByteStream(ArrayType Data) : Data(Data) {}
-  ~ByteStream() override {}
+  explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override;
+                  ArrayRef<uint8_t> &Buffer) const override {
+    if (Offset > Data.size())
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+    if (Data.size() < Size + Offset)
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+    Buffer = Data.slice(Offset, Size);
+    return Error::success();
+  }
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override;
+                                   ArrayRef<uint8_t> &Buffer) const override {
+    if (Offset >= Data.size())
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+    Buffer = Data.slice(Offset);
+    return Error::success();
+  }
 
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+  uint32_t getLength() const override { return Data.size(); }
 
-  uint32_t getLength() const override;
+  ArrayRef<uint8_t> data() const { return Data; }
 
-  Error commit() const override;
+  StringRef str() const {
+    const char *CharData = reinterpret_cast<const char *>(Data.data());
+    return StringRef(CharData, Data.size());
+  }
 
-  ArrayRef<uint8_t> data() const { return Data; }
-  StringRef str() const;
+protected:
+  ArrayRef<uint8_t> Data;
+};
+
+// MemoryBufferByteStream behaves like a read-only ByteStream, but has its data
+// backed by an llvm::MemoryBuffer.  It also owns the underlying MemoryBuffer.
+class MemoryBufferByteStream : public ByteStream {
+public:
+  explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
+      : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
+                                     Buffer->getBuffer().bytes_end())),
+        MemBuffer(std::move(Buffer)) {}
+
+  std::unique_ptr<MemoryBuffer> MemBuffer;
+};
+
+class MutableByteStream : public WritableStream {
+public:
+  MutableByteStream() {}
+  explicit MutableByteStream(MutableArrayRef<uint8_t> Data)
+      : Data(Data), ImmutableStream(Data) {}
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) const override {
+    return ImmutableStream.readBytes(Offset, Size, Buffer);
+  }
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) const override {
+    return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
+  }
+
+  uint32_t getLength() const override { return ImmutableStream.getLength(); }
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
+    if (Data.size() < Buffer.size())
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+    if (Offset > Buffer.size() - Data.size())
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+
+    uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
+    ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
+    return Error::success();
+  }
+
+  Error commit() const override { return Error::success(); }
+
+  MutableArrayRef<uint8_t> data() const { return Data; }
+
+private:
+  MutableArrayRef<uint8_t> Data;
+  ByteStream ImmutableStream;
+};
+
+// A simple adapter that acts like a ByteStream but holds ownership over
+// and underlying FileOutputBuffer.
+class FileBufferByteStream : public WritableStream {
+private:
+  class StreamImpl : public MutableByteStream {
+  public:
+    StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
+        : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
+                                                     Buffer->getBufferEnd())),
+          FileBuffer(std::move(Buffer)) {}
+
+    Error commit() const override {
+      if (FileBuffer->commit())
+        return llvm::make_error<MsfError>(msf_error_code::not_writable);
+      return Error::success();
+    }
+
+  private:
+    std::unique_ptr<FileOutputBuffer> FileBuffer;
+  };
+
+public:
+  explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
+      : Impl(std::move(Buffer)) {}
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) const override {
+    return Impl.readBytes(Offset, Size, Buffer);
+  }
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) const override {
+    return Impl.readLongestContiguousChunk(Offset, Buffer);
+  }
+
+  uint32_t getLength() const override { return Impl.getLength(); }
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
+    return Impl.writeBytes(Offset, Data);
+  }
+  Error commit() const override { return Impl.commit(); }
 
 private:
-  ArrayType Data;
+  StreamImpl Impl;
 };
 
-extern template class ByteStream<true>;
-extern template class ByteStream<false>;
 
 } // end namespace msf
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h Thu Jul 28 14:12:28 2016
@@ -25,7 +25,7 @@
 namespace llvm {
 namespace msf {
 
-class IMsfFile;
+struct MsfLayout;
 
 /// MappedBlockStream represents data stored in an Msf file into chunks of a
 /// particular size (called the Block Size), and whose chunks may not be
@@ -37,42 +37,102 @@ class IMsfFile;
 /// the Msf.  MappedBlockStream provides methods for reading from and writing
 /// to one of these streams transparently, as if it were a contiguous sequence
 /// of bytes.
-class MappedBlockStream : public StreamInterface {
+class MappedBlockStream : public ReadableStream {
+  friend class WritableMappedBlockStream;
+
 public:
+  static std::unique_ptr<MappedBlockStream>
+  createStream(uint32_t BlockSize, uint32_t NumBlocks,
+               const MsfStreamLayout &Layout, const ReadableStream &MsfData);
+
+  static std::unique_ptr<MappedBlockStream>
+  createIndexedStream(const MsfLayout &Layout, const ReadableStream &MsfData,
+                      uint32_t StreamIndex);
+
+  static std::unique_ptr<MappedBlockStream>
+  createDirectoryStream(const MsfLayout &Layout, const ReadableStream &MsfData);
+
   Error readBytes(uint32_t Offset, uint32_t Size,
                   ArrayRef<uint8_t> &Buffer) const override;
   Error readLongestContiguousChunk(uint32_t Offset,
                                    ArrayRef<uint8_t> &Buffer) const override;
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
 
   uint32_t getLength() const override;
-  Error commit() const override;
 
   uint32_t getNumBytesCopied() const;
 
-  static Expected<std::unique_ptr<MappedBlockStream>>
-  createIndexedStream(uint32_t StreamIdx, const IMsfFile &File);
-  static Expected<std::unique_ptr<MappedBlockStream>>
-  createDirectoryStream(uint32_t Length, ArrayRef<support::ulittle32_t> Blocks,
-                        const IMsfFile &File);
-
   llvm::BumpPtrAllocator &getAllocator() { return Pool; }
 
+  void invalidateCache();
+
+  uint32_t getBlockSize() const { return BlockSize; }
+  uint32_t getNumBlocks() const { return NumBlocks; }
+  uint32_t getStreamLength() const { return StreamLayout.Length; }
+
 protected:
-  MappedBlockStream(const MsfStreamLayout &Layout, const IMsfFile &File);
+  MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
+                    const MsfStreamLayout &StreamLayout,
+                    const ReadableStream &MsfData);
+
+private:
+  const MsfStreamLayout &getStreamLayout() const { return StreamLayout; }
+  void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;
 
   Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const;
   bool tryReadContiguously(uint32_t Offset, uint32_t Size,
                            ArrayRef<uint8_t> &Buffer) const;
 
-  const IMsfFile &Msf;
-  const MsfStreamLayout Layout;
+  const uint32_t BlockSize;
+  const uint32_t NumBlocks;
+  const MsfStreamLayout StreamLayout;
+  const ReadableStream &MsfData;
 
   typedef MutableArrayRef<uint8_t> CacheEntry;
   mutable llvm::BumpPtrAllocator Pool;
   mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
 };
 
+class WritableMappedBlockStream : public WritableStream {
+public:
+  static std::unique_ptr<WritableMappedBlockStream>
+  createStream(uint32_t BlockSize, uint32_t NumBlocks,
+               const MsfStreamLayout &Layout, const WritableStream &MsfData);
+
+  static std::unique_ptr<WritableMappedBlockStream>
+  createIndexedStream(const MsfLayout &Layout, const WritableStream &MsfData,
+                      uint32_t StreamIndex);
+
+  static std::unique_ptr<WritableMappedBlockStream>
+  createDirectoryStream(const MsfLayout &Layout, const WritableStream &MsfData);
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) const override;
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) const override;
+  uint32_t getLength() const override;
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+
+  Error commit() const override;
+
+  const MsfStreamLayout &getStreamLayout() const {
+    return ReadInterface.getStreamLayout();
+  }
+  uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
+  uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
+  uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
+
+protected:
+  WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
+                            const MsfStreamLayout &StreamLayout,
+                            const WritableStream &MsfData);
+
+private:
+  MappedBlockStream ReadInterface;
+
+  const WritableStream &WriteInterface;
+};
+
 } // end namespace pdb
 } // end namespace llvm
 

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h Thu Jul 28 14:12:28 2016
@@ -111,7 +111,7 @@ public:
 
   /// Finalize the layout and build the headers and structures that describe the
   /// MSF layout and can be written directly to the MSF file.
-  Expected<Layout> build();
+  Expected<MsfLayout> build();
 
 private:
   MsfBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h Thu Jul 28 14:12:28 2016
@@ -48,8 +48,8 @@ struct SuperBlock {
   support::ulittle32_t BlockMapAddr;
 };
 
-struct Layout {
-  Layout() : SB(nullptr) {}
+struct MsfLayout {
+  MsfLayout() : SB(nullptr) {}
   const SuperBlock *SB;
   ArrayRef<support::ulittle32_t> DirectoryBlocks;
   ArrayRef<support::ulittle32_t> StreamSizes;

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h Thu Jul 28 14:12:28 2016
@@ -34,7 +34,8 @@ namespace msf {
 template <typename T> struct VarStreamArrayExtractor {
   // Method intentionally deleted.  You must provide an explicit specialization
   // with the following method implemented.
-  Error operator()(StreamRef Stream, uint32_t &Len, T &Item) const = delete;
+  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+                   T &Item) const = delete;
 };
 
 /// VarStreamArray represents an array of variable length records backed by a
@@ -83,8 +84,9 @@ public:
   VarStreamArray() {}
   explicit VarStreamArray(const Extractor &E) : E(E) {}
 
-  explicit VarStreamArray(StreamRef Stream) : Stream(Stream) {}
-  VarStreamArray(StreamRef Stream, const Extractor &E) : Stream(Stream), E(E) {}
+  explicit VarStreamArray(ReadableStreamRef Stream) : Stream(Stream) {}
+  VarStreamArray(ReadableStreamRef Stream, const Extractor &E)
+      : Stream(Stream), E(E) {}
 
   VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
       : Stream(Other.Stream), E(Other.E) {}
@@ -97,10 +99,10 @@ public:
 
   const Extractor &getExtractor() const { return E; }
 
-  StreamRef getUnderlyingStream() const { return Stream; }
+  ReadableStreamRef getUnderlyingStream() const { return Stream; }
 
 private:
-  StreamRef Stream;
+  ReadableStreamRef Stream;
   Extractor E;
 };
 
@@ -189,7 +191,7 @@ private:
   }
 
   ValueType ThisValue;
-  StreamRef IterRef;
+  ReadableStreamRef IterRef;
   const ArrayType *Array{nullptr};
   uint32_t ThisLen{0};
   bool HasError{false};
@@ -204,7 +206,7 @@ template <typename T> class FixedStreamA
 
 public:
   FixedStreamArray() : Stream() {}
-  FixedStreamArray(StreamRef Stream) : Stream(Stream) {
+  FixedStreamArray(ReadableStreamRef Stream) : Stream(Stream) {
     assert(Stream.getLength() % sizeof(T) == 0);
   }
 
@@ -230,10 +232,10 @@ public:
     return FixedStreamArrayIterator<T>(*this, size());
   }
 
-  StreamRef getUnderlyingStream() const { return Stream; }
+  ReadableStreamRef getUnderlyingStream() const { return Stream; }
 
 private:
-  StreamRef Stream;
+  ReadableStreamRef Stream;
 };
 
 template <typename T> class FixedStreamArrayIterator {

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h Thu Jul 28 14:12:28 2016
@@ -17,16 +17,9 @@
 namespace llvm {
 namespace msf {
 
-/// StreamInterface abstracts the notion of a data stream.  This way, an
-/// implementation could implement trivial reading from a contiguous memory
-/// buffer or, as in the case of PDB files, reading from a set of possibly
-/// discontiguous blocks.  The implementation is required to return references
-/// to stable memory, so if this is not possible (for example in the case of
-/// a PDB file with discontiguous blocks, it must keep its own pool of temp
-/// storage.
-class StreamInterface {
+class ReadableStream {
 public:
-  virtual ~StreamInterface() {}
+  virtual ~ReadableStream() {}
 
   // Given an offset into the stream and a number of bytes, attempt to read
   // the bytes and set the output ArrayRef to point to a reference into the
@@ -39,13 +32,18 @@ public:
   virtual Error readLongestContiguousChunk(uint32_t Offset,
                                            ArrayRef<uint8_t> &Buffer) const = 0;
 
+  virtual uint32_t getLength() const = 0;
+};
+
+class WritableStream : public ReadableStream {
+public:
+  virtual ~WritableStream() {}
+
   // Attempt to write the given bytes into the stream at the desired offset.
   // This will always necessitate a copy.  Cannot shrink or grow the stream,
   // only writes into existing allocated space.
   virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;
 
-  virtual uint32_t getLength() const = 0;
-
   virtual Error commit() const = 0;
 };
 

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h Thu Jul 28 14:12:28 2016
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/Msf/MsfError.h"
 #include "llvm/DebugInfo/Msf/StreamArray.h"
 #include "llvm/DebugInfo/Msf/StreamInterface.h"
+#include "llvm/DebugInfo/Msf/StreamRef.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 
@@ -22,11 +23,9 @@
 namespace llvm {
 namespace msf {
 
-class StreamRef;
-
 class StreamReader {
 public:
-  StreamReader(StreamRef Stream);
+  StreamReader(ReadableStreamRef Stream);
 
   Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
   Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
@@ -34,8 +33,8 @@ public:
   Error readInteger(uint32_t &Dest);
   Error readZeroString(StringRef &Dest);
   Error readFixedString(StringRef &Dest, uint32_t Length);
-  Error readStreamRef(StreamRef &Ref);
-  Error readStreamRef(StreamRef &Ref, uint32_t Length);
+  Error readStreamRef(ReadableStreamRef &Ref);
+  Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length);
 
   template <typename T> Error readEnum(T &Dest) {
     typename std::underlying_type<T>::type N;
@@ -72,7 +71,7 @@ public:
 
   template <typename T, typename U>
   Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
-    StreamRef S;
+    ReadableStreamRef S;
     if (auto EC = readStreamRef(S, Size))
       return EC;
     Array = VarStreamArray<T, U>(S, Array.getExtractor());
@@ -90,7 +89,7 @@ public:
       return make_error<MsfError>(msf_error_code::invalid_format);
     if (Offset + Length > Stream.getLength())
       return make_error<MsfError>(msf_error_code::insufficient_buffer);
-    StreamRef View = Stream.slice(Offset, Length);
+    ReadableStreamRef View = Stream.slice(Offset, Length);
     Array = FixedStreamArray<T>(View);
     Offset += Length;
     return Error::success();
@@ -102,7 +101,7 @@ public:
   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
 
 private:
-  StreamRef Stream;
+  ReadableStreamRef Stream;
   uint32_t Offset;
 };
 } // namespace msf

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h Thu Jul 28 14:12:28 2016
@@ -15,17 +15,63 @@
 
 namespace llvm {
 namespace msf {
-
-class StreamRef {
+template <class StreamType, class RefType> class StreamRefBase {
 public:
-  StreamRef() : Stream(nullptr), ViewOffset(0), Length(0) {}
-  StreamRef(const StreamInterface &Stream)
-      : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {}
-  StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)
+  StreamRefBase() : Stream(nullptr), Length(0), ViewOffset(0) {}
+  StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)
       : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
 
+  uint32_t getLength() const { return Length; }
+  const StreamType *getStream() const { return Stream; }
+
+  RefType drop_front(uint32_t N) const {
+    if (!Stream)
+      return RefType();
+
+    N = std::min(N, Length);
+    return RefType(*Stream, ViewOffset + N, Length - N);
+  }
+
+  RefType keep_front(uint32_t N) const {
+    if (!Stream)
+      return RefType();
+    N = std::min(N, Length);
+    return RefType(*Stream, ViewOffset, N);
+  }
+
+  RefType slice(uint32_t Offset, uint32_t Len) const {
+    return drop_front(Offset).keep_front(Len);
+  }
+
+  bool operator==(const RefType &Other) const {
+    if (Stream != Other.Stream)
+      return false;
+    if (ViewOffset != Other.ViewOffset)
+      return false;
+    if (Length != Other.Length)
+      return false;
+    return true;
+  }
+
+protected:
+  const StreamType *Stream;
+  uint32_t ViewOffset;
+  uint32_t Length;
+};
+
+class ReadableStreamRef
+    : public StreamRefBase<ReadableStream, ReadableStreamRef> {
+public:
+  ReadableStreamRef() : StreamRefBase() {}
+  ReadableStreamRef(const ReadableStream &Stream)
+      : StreamRefBase(Stream, 0, Stream.getLength()) {}
+  ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset,
+                    uint32_t Length)
+      : StreamRefBase(Stream, Offset, Length) {}
+
   // Use StreamRef.slice() instead.
-  StreamRef(const StreamRef &S, uint32_t Offset, uint32_t Length) = delete;
+  ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,
+                    uint32_t Length) = delete;
 
   Error readBytes(uint32_t Offset, uint32_t Size,
                   ArrayRef<uint8_t> &Buffer) const {
@@ -53,6 +99,21 @@ public:
       Buffer = Buffer.slice(0, MaxLength);
     return Error::success();
   }
+};
+
+class WritableStreamRef
+    : public StreamRefBase<WritableStream, WritableStreamRef> {
+public:
+  WritableStreamRef() : StreamRefBase() {}
+  WritableStreamRef(const WritableStream &Stream)
+      : StreamRefBase(Stream, 0, Stream.getLength()) {}
+  WritableStreamRef(const WritableStream &Stream, uint32_t Offset,
+                    uint32_t Length)
+      : StreamRefBase(Stream, Offset, Length) {}
+
+  // Use StreamRef.slice() instead.
+  WritableStreamRef(const WritableStreamRef &S, uint32_t Offset,
+                    uint32_t Length) = delete;
 
   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
     if (Data.size() + Offset > Length)
@@ -60,44 +121,9 @@ public:
     return Stream->writeBytes(ViewOffset + Offset, Data);
   }
 
-  uint32_t getLength() const { return Length; }
-
   Error commit() const { return Stream->commit(); }
-
-  StreamRef drop_front(uint32_t N) const {
-    if (!Stream)
-      return StreamRef();
-
-    N = std::min(N, Length);
-    return StreamRef(*Stream, ViewOffset + N, Length - N);
-  }
-
-  StreamRef keep_front(uint32_t N) const {
-    if (!Stream)
-      return StreamRef();
-    N = std::min(N, Length);
-    return StreamRef(*Stream, ViewOffset, N);
-  }
-
-  StreamRef slice(uint32_t Offset, uint32_t Len) const {
-    return drop_front(Offset).keep_front(Len);
-  }
-
-  bool operator==(const StreamRef &Other) const {
-    if (Stream != Other.Stream)
-      return false;
-    if (ViewOffset != Other.ViewOffset)
-      return false;
-    if (Length != Other.Length)
-      return false;
-    return true;
-  }
-
-private:
-  const StreamInterface *Stream;
-  uint32_t ViewOffset;
-  uint32_t Length;
 };
+
 } // namespace msf
 } // namespace llvm
 

Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h Thu Jul 28 14:12:28 2016
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/Msf/MsfError.h"
 #include "llvm/DebugInfo/Msf/StreamArray.h"
 #include "llvm/DebugInfo/Msf/StreamInterface.h"
+#include "llvm/DebugInfo/Msf/StreamRef.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 
@@ -22,19 +23,17 @@
 namespace llvm {
 namespace msf {
 
-class StreamRef;
-
 class StreamWriter {
 public:
-  StreamWriter(StreamRef Stream);
+  StreamWriter(WritableStreamRef Stream);
 
   Error writeBytes(ArrayRef<uint8_t> Buffer);
   Error writeInteger(uint16_t Dest);
   Error writeInteger(uint32_t Dest);
   Error writeZeroString(StringRef Str);
   Error writeFixedString(StringRef Str);
-  Error writeStreamRef(StreamRef Ref);
-  Error writeStreamRef(StreamRef Ref, uint32_t Size);
+  Error writeStreamRef(ReadableStreamRef Ref);
+  Error writeStreamRef(ReadableStreamRef Ref, uint32_t Size);
 
   template <typename T> Error writeEnum(T Num) {
     return writeInteger(
@@ -77,7 +76,7 @@ public:
   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
 
 private:
-  StreamRef Stream;
+  WritableStreamRef Stream;
   uint32_t Offset;
 };
 } // namespace msf

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Thu Jul 28 14:12:28 2016
@@ -12,9 +12,10 @@
 
 #include "llvm/Config/llvm-config.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
-#include <functional>
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
 #include <cstdint>
 #include <cstring>
+#include <functional>
 
 namespace llvm {
 namespace pdb {
@@ -73,13 +74,6 @@ enum class PDB_ReaderType {
   Raw = 1,
 };
 
-/// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but
-/// is abstracted here for the purposes of non-Windows platforms that don't have
-/// the GUID structure defined.
-struct PDB_UniqueId {
-  char Guid[16];
-};
-
 /// An enumeration indicating the type of data contained in this table.
 enum class PDB_TableType {
   Symbols,

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Thu Jul 28 14:12:28 2016
@@ -77,8 +77,6 @@ public:
   msf::FixedStreamArray<SecMapEntry> getSectionMap() const;
   void visitSectionContributions(ISectionContribVisitor &Visitor) const;
 
-  Error commit();
-
 private:
   Error initializeModInfoArray();
   Error initializeSectionContributionData();
@@ -93,14 +91,14 @@ private:
   std::vector<ModuleInfoEx> ModuleInfos;
   NameHashTable ECNames;
 
-  msf::StreamRef ModInfoSubstream;
-  msf::StreamRef SecContrSubstream;
-  msf::StreamRef SecMapSubstream;
-  msf::StreamRef FileInfoSubstream;
-  msf::StreamRef TypeServerMapSubstream;
-  msf::StreamRef ECSubstream;
+  msf::ReadableStreamRef ModInfoSubstream;
+  msf::ReadableStreamRef SecContrSubstream;
+  msf::ReadableStreamRef SecMapSubstream;
+  msf::ReadableStreamRef FileInfoSubstream;
+  msf::ReadableStreamRef TypeServerMapSubstream;
+  msf::ReadableStreamRef ECSubstream;
 
-  msf::StreamRef NamesBuffer;
+  msf::ReadableStreamRef NamesBuffer;
 
   msf::FixedStreamArray<support::ulittle16_t> DbgStreams;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h Thu Jul 28 14:12:28 2016
@@ -23,6 +23,7 @@
 namespace llvm {
 namespace pdb {
 class DbiStream;
+struct DbiStreamHeader;
 class PDBFile;
 
 class DbiStreamBuilder {
@@ -45,9 +46,13 @@ public:
   Error addModuleInfo(StringRef ObjFile, StringRef Module);
   Error addModuleSourceFile(StringRef Module, StringRef File);
 
-  Expected<std::unique_ptr<DbiStream>> build(PDBFile &File);
+  Expected<std::unique_ptr<DbiStream>> build(PDBFile &File,
+                                             const msf::WritableStream &Buffer);
+  Error commit(const msf::MsfLayout &Layout,
+               const msf::WritableStream &Buffer) const;
 
 private:
+  Error finalize();
   uint32_t calculateModiSubstreamSize() const;
   uint32_t calculateFileInfoSubstreamSize() const;
   uint32_t calculateNamesBufferSize() const;
@@ -71,14 +76,16 @@ private:
   uint16_t Flags;
   PDB_Machine MachineType;
 
+  const DbiStreamHeader *Header;
+
   StringMap<std::unique_ptr<ModuleInfo>> ModuleInfos;
   std::vector<ModuleInfo *> ModuleInfoList;
 
   StringMap<uint32_t> SourceFileNames;
 
-  msf::StreamRef NamesBuffer;
-  msf::ByteStream<true> ModInfoBuffer;
-  msf::ByteStream<true> FileInfoBuffer;
+  msf::WritableStreamRef NamesBuffer;
+  msf::MutableByteStream ModInfoBuffer;
+  msf::MutableByteStream FileInfoBuffer;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h Thu Jul 28 14:12:28 2016
@@ -27,18 +27,10 @@ class PDBFile;
 class InfoStream {
   friend class InfoStreamBuilder;
 
-  struct HeaderInfo {
-    support::ulittle32_t Version;
-    support::ulittle32_t Signature;
-    support::ulittle32_t Age;
-    PDB_UniqueId Guid;
-  };
-
 public:
   InfoStream(std::unique_ptr<msf::MappedBlockStream> Stream);
 
   Error reload();
-  Error commit();
 
   PdbRaw_ImplVer getVersion() const;
   uint32_t getSignature() const;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h Thu Jul 28 14:12:28 2016
@@ -19,6 +19,9 @@
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 
 namespace llvm {
+namespace msf {
+class StreamWriter;
+}
 namespace pdb {
 class PDBFile;
 
@@ -37,13 +40,17 @@ public:
 
   uint32_t calculateSerializedLength() const;
 
-  Expected<std::unique_ptr<InfoStream>> build(PDBFile &File);
+  Expected<std::unique_ptr<InfoStream>>
+  build(PDBFile &File, const msf::WritableStream &Buffer);
+
+  Error commit(const msf::MsfLayout &Layout,
+               const msf::WritableStream &Buffer) const;
 
 private:
-  Optional<PdbRaw_ImplVer> Ver;
-  Optional<uint32_t> Sig;
-  Optional<uint32_t> Age;
-  Optional<PDB_UniqueId> Guid;
+  PdbRaw_ImplVer Ver;
+  uint32_t Sig;
+  uint32_t Age;
+  PDB_UniqueId Guid;
 
   NameMapBuilder NamedStreams;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h Thu Jul 28 14:12:28 2016
@@ -29,7 +29,7 @@ public:
   ModInfo(const ModInfo &Info);
   ~ModInfo();
 
-  static Error initialize(msf::StreamRef Stream, ModInfo &Info);
+  static Error initialize(msf::ReadableStreamRef Stream, ModInfo &Info);
 
   bool hasECInfo() const;
   uint16_t getTypeServerIndex() const;
@@ -65,7 +65,7 @@ struct ModuleInfoEx {
 
 namespace msf {
 template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
-  Error operator()(StreamRef Stream, uint32_t &Length,
+  Error operator()(ReadableStreamRef Stream, uint32_t &Length,
                    pdb::ModInfo &Info) const {
     if (auto EC = pdb::ModInfo::initialize(Stream, Info))
       return EC;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h Thu Jul 28 14:12:28 2016
@@ -46,9 +46,9 @@ private:
   std::unique_ptr<msf::MappedBlockStream> Stream;
 
   codeview::CVSymbolArray SymbolsSubstream;
-  msf::StreamRef LinesSubstream;
-  msf::StreamRef C13LinesSubstream;
-  msf::StreamRef GlobalRefsSubstream;
+  msf::ReadableStreamRef LinesSubstream;
+  msf::ReadableStreamRef C13LinesSubstream;
+  msf::ReadableStreamRef GlobalRefsSubstream;
 
   codeview::ModuleSubstreamArray LineInfo;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h Thu Jul 28 14:12:28 2016
@@ -41,7 +41,7 @@ public:
   msf::FixedStreamArray<support::ulittle32_t> name_ids() const;
 
 private:
-  msf::StreamRef NamesBuffer;
+  msf::ReadableStreamRef NamesBuffer;
   msf::FixedStreamArray<support::ulittle32_t> IDs;
   uint32_t Signature;
   uint32_t HashVersion;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h Thu Jul 28 14:12:28 2016
@@ -29,7 +29,6 @@ public:
   NameMap();
 
   Error load(msf::StreamReader &Stream);
-  Error commit(msf::StreamWriter &Writer);
 
   bool tryGetValue(StringRef Name, uint32_t &Value) const;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h Thu Jul 28 14:12:28 2016
@@ -17,6 +17,9 @@
 #include <memory>
 
 namespace llvm {
+namespace msf {
+class StreamWriter;
+}
 namespace pdb {
 class NameMap;
 
@@ -27,6 +30,7 @@ public:
   void addMapping(StringRef Name, uint32_t Mapping);
 
   Expected<std::unique_ptr<NameMap>> build();
+  Error commit(msf::StreamWriter &Writer) const;
 
   uint32_t calculateSerializedLength() const;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Thu Jul 28 14:12:28 2016
@@ -26,7 +26,7 @@ namespace llvm {
 
 namespace msf {
 class MappedBlockStream;
-class StreamInterface;
+class WritableStream;
 }
 
 namespace pdb {
@@ -42,7 +42,7 @@ class PDBFile : public msf::IMsfFile {
   friend PDBFileBuilder;
 
 public:
-  PDBFile(std::unique_ptr<msf::StreamInterface> PdbFileBuffer,
+  PDBFile(std::unique_ptr<msf::ReadableStream> PdbFileBuffer,
           BumpPtrAllocator &Allocator);
   ~PDBFile() override;
 
@@ -68,12 +68,15 @@ public:
                      ArrayRef<uint8_t> Data) const override;
 
   ArrayRef<support::ulittle32_t> getStreamSizes() const {
-    return MsfLayout.StreamSizes;
+    return ContainerLayout.StreamSizes;
   }
   ArrayRef<ArrayRef<support::ulittle32_t>> getStreamMap() const {
-    return MsfLayout.StreamMap;
+    return ContainerLayout.StreamMap;
   }
 
+  const msf::MsfLayout &getMsfLayout() const { return ContainerLayout; }
+  const msf::ReadableStream &getMsfBuffer() const { return *Buffer; }
+
   ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
 
   Error parseFileHeaders();
@@ -87,14 +90,12 @@ public:
   Expected<SymbolStream &> getPDBSymbolStream();
   Expected<NameHashTable &> getStringTable();
 
-  Error commit();
-
 private:
   BumpPtrAllocator &Allocator;
 
-  std::unique_ptr<msf::StreamInterface> Buffer;
+  std::unique_ptr<msf::ReadableStream> Buffer;
 
-  msf::Layout MsfLayout;
+  msf::MsfLayout ContainerLayout;
 
   std::unique_ptr<InfoStream> Info;
   std::unique_ptr<DbiStream> Dbi;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h Thu Jul 28 14:12:28 2016
@@ -24,7 +24,6 @@
 namespace llvm {
 namespace msf {
 class MsfBuilder;
-class StreamInterface;
 }
 namespace pdb {
 class DbiStreamBuilder;
@@ -43,10 +42,12 @@ public:
   DbiStreamBuilder &getDbiBuilder();
 
   Expected<std::unique_ptr<PDBFile>>
-  build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer);
+  build(std::unique_ptr<msf::WritableStream> PdbFileBuffer);
+
+  Error commit(const msf::WritableStream &Buffer);
 
 private:
-  Expected<msf::Layout> finalizeMsfLayout() const;
+  Expected<msf::MsfLayout> finalizeMsfLayout() const;
 
   BumpPtrAllocator &Allocator;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h Thu Jul 28 14:12:28 2016
@@ -259,6 +259,21 @@ struct ModuleInfoHeader {
   /// char ObjFileName[];
 };
 
+/// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but
+/// is abstracted here for the purposes of non-Windows platforms that don't have
+/// the GUID structure defined.
+struct PDB_UniqueId {
+  char Guid[16];
+};
+
+/// The header preceeding the global PDB Stream (Stream 1)
+struct InfoStreamHeader {
+  support::ulittle32_t Version;
+  support::ulittle32_t Signature;
+  support::ulittle32_t Age;
+  PDB_UniqueId Guid;
+};
+
 } // namespace pdb
 } // namespace llvm
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Thu Jul 28 14:12:28 2016
@@ -475,7 +475,7 @@ void CodeViewDebug::emitTypeInformation(
           // comments. The MSVC linker doesn't do much type record validation,
           // so the first link of an invalid type record can succeed while
           // subsequent links will fail with LNK1285.
-          ByteStream<> Stream({Record.bytes_begin(), Record.bytes_end()});
+          ByteStream Stream({Record.bytes_begin(), Record.bytes_end()});
           CVTypeArray Types;
           StreamReader Reader(Stream);
           Error E = Reader.readArray(Types, Reader.getLength());

Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp Thu Jul 28 14:12:28 2016
@@ -17,10 +17,12 @@ using namespace llvm::msf;
 
 ModuleSubstream::ModuleSubstream() : Kind(ModuleSubstreamKind::None) {}
 
-ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind, StreamRef Data)
+ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind,
+                                 ReadableStreamRef Data)
     : Kind(Kind), Data(Data) {}
 
-Error ModuleSubstream::initialize(StreamRef Stream, ModuleSubstream &Info) {
+Error ModuleSubstream::initialize(ReadableStreamRef Stream,
+                                  ModuleSubstream &Info) {
   const ModuleSubsectionHeader *Header;
   StreamReader Reader(Stream);
   if (auto EC = Reader.readObject(Header))
@@ -40,4 +42,4 @@ uint32_t ModuleSubstream::getRecordLengt
 
 ModuleSubstreamKind ModuleSubstream::getSubstreamKind() const { return Kind; }
 
-StreamRef ModuleSubstream::getRecordData() const { return Data; }
+ReadableStreamRef ModuleSubstream::getRecordData() const { return Data; }

Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp Thu Jul 28 14:12:28 2016
@@ -15,46 +15,47 @@ using namespace llvm;
 using namespace llvm::codeview;
 using namespace llvm::msf;
 
-Error IModuleSubstreamVisitor::visitSymbols(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitSymbols(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::Symbols, Data);
 }
-Error IModuleSubstreamVisitor::visitLines(StreamRef Data,
+Error IModuleSubstreamVisitor::visitLines(ReadableStreamRef Data,
                                           const LineSubstreamHeader *Header,
                                           const LineInfoArray &Lines) {
   return visitUnknown(ModuleSubstreamKind::Lines, Data);
 }
-Error IModuleSubstreamVisitor::visitStringTable(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitStringTable(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::StringTable, Data);
 }
 Error IModuleSubstreamVisitor::visitFileChecksums(
-    StreamRef Data, const FileChecksumArray &Checksums) {
+    ReadableStreamRef Data, const FileChecksumArray &Checksums) {
   return visitUnknown(ModuleSubstreamKind::FileChecksums, Data);
 }
-Error IModuleSubstreamVisitor::visitFrameData(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitFrameData(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::FrameData, Data);
 }
-Error IModuleSubstreamVisitor::visitInlineeLines(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitInlineeLines(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::InlineeLines, Data);
 }
-Error IModuleSubstreamVisitor::visitCrossScopeImports(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeImports(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CrossScopeExports, Data);
 }
-Error IModuleSubstreamVisitor::visitCrossScopeExports(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeExports(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CrossScopeImports, Data);
 }
-Error IModuleSubstreamVisitor::visitILLines(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitILLines(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::ILLines, Data);
 }
-Error IModuleSubstreamVisitor::visitFuncMDTokenMap(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitFuncMDTokenMap(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::FuncMDTokenMap, Data);
 }
-Error IModuleSubstreamVisitor::visitTypeMDTokenMap(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitTypeMDTokenMap(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::TypeMDTokenMap, Data);
 }
-Error IModuleSubstreamVisitor::visitMergedAssemblyInput(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitMergedAssemblyInput(
+    ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::MergedAssemblyInput, Data);
 }
-Error IModuleSubstreamVisitor::visitCoffSymbolRVA(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCoffSymbolRVA(ReadableStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CoffSymbolRVA, Data);
 }
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Thu Jul 28 14:12:28 2016
@@ -681,7 +681,7 @@ Error CVTypeDumper::dump(const CVTypeArr
 }
 
 Error CVTypeDumper::dump(ArrayRef<uint8_t> Data) {
-  msf::ByteStream<> Stream(Data);
+  msf::ByteStream Stream(Data);
   CVTypeArray Types;
   msf::StreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Types, Reader.getLength()))

Removed: llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp?rev=277018&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp (removed)
@@ -1,79 +0,0 @@
-//===- ByteStream.cpp - Reads stream data from a byte sequence ------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/Msf/ByteStream.h"
-#include "llvm/DebugInfo/Msf/MsfError.h"
-#include "llvm/DebugInfo/Msf/StreamReader.h"
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::msf;
-
-static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,
-                        ArrayRef<uint8_t> Dest) {
-  return make_error<MsfError>(msf_error_code::not_writable,
-                              "ByteStream is immutable.");
-}
-
-static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,
-                        MutableArrayRef<uint8_t> Dest) {
-  if (Dest.size() < Src.size())
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  if (Offset > Src.size() - Dest.size())
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
-  ::memcpy(Dest.data() + Offset, Src.data(), Src.size());
-  return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::readBytes(uint32_t Offset, uint32_t Size,
-                                      ArrayRef<uint8_t> &Buffer) const {
-  if (Offset > Data.size())
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  if (Data.size() < Size + Offset)
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  Buffer = Data.slice(Offset, Size);
-  return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::readLongestContiguousChunk(
-    uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
-  if (Offset >= Data.size())
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  Buffer = Data.slice(Offset);
-  return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::writeBytes(uint32_t Offset,
-                                       ArrayRef<uint8_t> Buffer) const {
-  return ::writeBytes(Offset, Buffer, Data);
-}
-
-template <bool Writable> uint32_t ByteStream<Writable>::getLength() const {
-  return Data.size();
-}
-
-template <bool Writable> Error ByteStream<Writable>::commit() const {
-  return Error::success();
-}
-
-template <bool Writable> StringRef ByteStream<Writable>::str() const {
-  const char *CharData = reinterpret_cast<const char *>(Data.data());
-  return StringRef(CharData, Data.size());
-}
-
-namespace llvm {
-namespace msf {
-template class ByteStream<true>;
-template class ByteStream<false>;
-}
-}

Modified: llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt Thu Jul 28 14:12:28 2016
@@ -1,5 +1,4 @@
 add_llvm_library(LLVMDebugInfoMsf
-  ByteStream.cpp
   MappedBlockStream.cpp
   MsfBuilder.cpp
   MsfCommon.cpp

Modified: llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp Thu Jul 28 14:12:28 2016
@@ -10,6 +10,7 @@
 #include "llvm/DebugInfo/Msf/MappedBlockStream.h"
 
 #include "llvm/DebugInfo/Msf/IMsfFile.h"
+#include "llvm/DebugInfo/Msf/MsfCommon.h"
 #include "llvm/DebugInfo/Msf/MsfError.h"
 #include "llvm/DebugInfo/Msf/MsfStreamLayout.h"
 
@@ -17,13 +18,11 @@ using namespace llvm;
 using namespace llvm::msf;
 
 namespace {
-// This exists so that we can use make_unique (which requires a public default
-// constructor, while still keeping the constructor of MappedBlockStream
-// protected, forcing users to go through the `create` interface.
-class MappedBlockStreamImpl : public MappedBlockStream {
+template <typename Base> class MappedBlockStreamImpl : public Base {
 public:
-  MappedBlockStreamImpl(const MsfStreamLayout &Layout, const IMsfFile &File)
-      : MappedBlockStream(Layout, File) {}
+  template <typename... Args>
+  MappedBlockStreamImpl(Args &&... Params)
+      : Base(std::forward<Args>(Params)...) {}
 };
 }
 
@@ -33,16 +32,46 @@ static Interval intersect(const Interval
                         std::min(I1.second, I2.second));
 }
 
-MappedBlockStream::MappedBlockStream(const MsfStreamLayout &Layout,
-                                     const IMsfFile &File)
-    : Msf(File), Layout(Layout) {}
+MappedBlockStream::MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
+                                     const MsfStreamLayout &Layout,
+                                     const ReadableStream &MsfData)
+    : BlockSize(BlockSize), NumBlocks(NumBlocks), StreamLayout(Layout),
+      MsfData(MsfData) {}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks,
+                                const MsfStreamLayout &Layout,
+                                const ReadableStream &MsfData) {
+  return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+      BlockSize, NumBlocks, Layout, MsfData);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createIndexedStream(const MsfLayout &Layout,
+                                       const ReadableStream &MsfData,
+                                       uint32_t StreamIndex) {
+  MsfStreamLayout SL;
+  SL.Blocks = Layout.StreamMap[StreamIndex];
+  SL.Length = Layout.StreamSizes[StreamIndex];
+  return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+      Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createDirectoryStream(const MsfLayout &Layout,
+                                         const ReadableStream &MsfData) {
+  MsfStreamLayout SL;
+  SL.Blocks = Layout.DirectoryBlocks;
+  SL.Length = Layout.SB->NumDirectoryBytes;
+  return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
 
 Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
                                    ArrayRef<uint8_t> &Buffer) const {
   // Make sure we aren't trying to read beyond the end of the stream.
-  if (Size > Layout.Length)
+  if (Size > StreamLayout.Length)
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  if (Offset > Layout.Length - Size)
+  if (Offset > StreamLayout.Length - Size)
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
 
   if (tryReadContiguously(Offset, Size, Buffer))
@@ -120,33 +149,33 @@ Error MappedBlockStream::readBytes(uint3
 Error MappedBlockStream::readLongestContiguousChunk(
     uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
   // Make sure we aren't trying to read beyond the end of the stream.
-  if (Offset >= Layout.Length)
+  if (Offset >= StreamLayout.Length)
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  uint32_t First = Offset / Msf.getBlockSize();
+  uint32_t First = Offset / BlockSize;
   uint32_t Last = First;
 
-  while (Last < Msf.getBlockCount() - 1) {
-    if (Layout.Blocks[Last] != Layout.Blocks[Last + 1] - 1)
+  while (Last < NumBlocks - 1) {
+    if (StreamLayout.Blocks[Last] != StreamLayout.Blocks[Last + 1] - 1)
       break;
     ++Last;
   }
 
-  uint32_t OffsetInFirstBlock = Offset % Msf.getBlockSize();
-  uint32_t BytesFromFirstBlock = Msf.getBlockSize() - OffsetInFirstBlock;
+  uint32_t OffsetInFirstBlock = Offset % BlockSize;
+  uint32_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;
   uint32_t BlockSpan = Last - First + 1;
-  uint32_t ByteSpan =
-      BytesFromFirstBlock + (BlockSpan - 1) * Msf.getBlockSize();
-  auto Result = Msf.getBlockData(Layout.Blocks[First], Msf.getBlockSize());
-  if (!Result)
-    return Result.takeError();
-  Buffer = Result->drop_front(OffsetInFirstBlock);
-  Buffer = ArrayRef<uint8_t>(Buffer.data(), ByteSpan);
+  uint32_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;
+
+  ArrayRef<uint8_t> BlockData;
+  uint32_t MsfOffset = blockToOffset(StreamLayout.Blocks[First], BlockSize);
+  if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))
+    return EC;
+
+  BlockData = BlockData.drop_front(OffsetInFirstBlock);
+  Buffer = ArrayRef<uint8_t>(BlockData.data(), ByteSpan);
   return Error::success();
 }
 
-uint32_t MappedBlockStream::getLength() const { return Layout.Length; }
-
-Error MappedBlockStream::commit() const { return Error::success(); }
+uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; }
 
 bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
                                             ArrayRef<uint8_t> &Buffer) const {
@@ -155,57 +184,60 @@ bool MappedBlockStream::tryReadContiguou
   // all subsequent blocks are contiguous.  For example, a 10k read with a 4k
   // block size can be filled with a reference if, from the starting offset,
   // 3 blocks in a row are contiguous.
-  uint32_t BlockNum = Offset / Msf.getBlockSize();
-  uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
-  uint32_t BytesFromFirstBlock =
-      std::min(Size, Msf.getBlockSize() - OffsetInBlock);
+  uint32_t BlockNum = Offset / BlockSize;
+  uint32_t OffsetInBlock = Offset % BlockSize;
+  uint32_t BytesFromFirstBlock = std::min(Size, BlockSize - OffsetInBlock);
   uint32_t NumAdditionalBlocks =
-      llvm::alignTo(Size - BytesFromFirstBlock, Msf.getBlockSize()) /
-      Msf.getBlockSize();
+      llvm::alignTo(Size - BytesFromFirstBlock, BlockSize) / BlockSize;
 
   uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
-  uint32_t E = Layout.Blocks[BlockNum];
+  uint32_t E = StreamLayout.Blocks[BlockNum];
   for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
-    if (Layout.Blocks[I + BlockNum] != E)
+    if (StreamLayout.Blocks[I + BlockNum] != E)
       return false;
   }
 
-  uint32_t FirstBlockAddr = Layout.Blocks[BlockNum];
-  auto Result = Msf.getBlockData(FirstBlockAddr, Msf.getBlockSize());
-  if (!Result) {
-    consumeError(Result.takeError());
+  // Read out the entire block where the requested offset starts.  Then drop
+  // bytes from the beginning so that the actual starting byte lines up with
+  // the requested starting byte.  Then, since we know this is a contiguous
+  // cross-block span, explicitly resize the ArrayRef to cover the entire
+  // request length.
+  ArrayRef<uint8_t> BlockData;
+  uint32_t FirstBlockAddr = StreamLayout.Blocks[BlockNum];
+  uint32_t MsfOffset = blockToOffset(FirstBlockAddr, BlockSize);
+  if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData)) {
+    consumeError(std::move(EC));
     return false;
   }
-  auto Data = Result->drop_front(OffsetInBlock);
-  Buffer = ArrayRef<uint8_t>(Data.data(), Size);
+  BlockData = BlockData.drop_front(OffsetInBlock);
+  Buffer = ArrayRef<uint8_t>(BlockData.data(), Size);
   return true;
 }
 
 Error MappedBlockStream::readBytes(uint32_t Offset,
                                    MutableArrayRef<uint8_t> Buffer) const {
-  uint32_t BlockNum = Offset / Msf.getBlockSize();
-  uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
+  uint32_t BlockNum = Offset / BlockSize;
+  uint32_t OffsetInBlock = Offset % BlockSize;
 
   // Make sure we aren't trying to read beyond the end of the stream.
-  if (Buffer.size() > Layout.Length)
+  if (Buffer.size() > StreamLayout.Length)
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
-  if (Offset > Layout.Length - Buffer.size())
+  if (Offset > StreamLayout.Length - Buffer.size())
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
 
   uint32_t BytesLeft = Buffer.size();
   uint32_t BytesWritten = 0;
   uint8_t *WriteBuffer = Buffer.data();
   while (BytesLeft > 0) {
-    uint32_t StreamBlockAddr = Layout.Blocks[BlockNum];
+    uint32_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];
 
-    auto Result = Msf.getBlockData(StreamBlockAddr, Msf.getBlockSize());
-    if (!Result)
-      return Result.takeError();
-
-    auto Data = *Result;
-    const uint8_t *ChunkStart = Data.data() + OffsetInBlock;
-    uint32_t BytesInChunk =
-        std::min(BytesLeft, Msf.getBlockSize() - OffsetInBlock);
+    ArrayRef<uint8_t> BlockData;
+    uint32_t Offset = blockToOffset(StreamBlockAddr, BlockSize);
+    if (auto EC = MsfData.readBytes(Offset, BlockSize, BlockData))
+      return EC;
+
+    const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;
+    uint32_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
     ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);
 
     BytesWritten += BytesInChunk;
@@ -217,36 +249,14 @@ Error MappedBlockStream::readBytes(uint3
   return Error::success();
 }
 
-Error MappedBlockStream::writeBytes(uint32_t Offset,
-                                    ArrayRef<uint8_t> Buffer) const {
-  // Make sure we aren't trying to write beyond the end of the stream.
-  if (Buffer.size() > Layout.Length)
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
-  if (Offset > Layout.Length - Buffer.size())
-    return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
-  uint32_t BlockNum = Offset / Msf.getBlockSize();
-  uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
-
-  uint32_t BytesLeft = Buffer.size();
-  uint32_t BytesWritten = 0;
-  while (BytesLeft > 0) {
-    uint32_t StreamBlockAddr = Layout.Blocks[BlockNum];
-    uint32_t BytesToWriteInChunk =
-        std::min(BytesLeft, Msf.getBlockSize() - OffsetInBlock);
-
-    const uint8_t *Chunk = Buffer.data() + BytesWritten;
-    ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
-    if (auto EC = Msf.setBlockData(StreamBlockAddr, OffsetInBlock, ChunkData))
-      return EC;
+uint32_t MappedBlockStream::getNumBytesCopied() const {
+  return static_cast<uint32_t>(Pool.getBytesAllocated());
+}
 
-    BytesLeft -= BytesToWriteInChunk;
-    BytesWritten += BytesToWriteInChunk;
-    ++BlockNum;
-    OffsetInBlock = 0;
-  }
+void MappedBlockStream::invalidateCache() { CacheMap.shrink_and_clear(); }
 
+void MappedBlockStream::fixCacheAfterWrite(uint32_t Offset,
+                                           ArrayRef<uint8_t> Data) const {
   // If this write overlapped a read which previously came from the pool,
   // someone may still be holding a pointer to that alloc which is now invalid.
   // Compute the overlapping range and update the cache entry, so any
@@ -254,7 +264,7 @@ Error MappedBlockStream::writeBytes(uint
   for (const auto &MapEntry : CacheMap) {
     // If the end of the written extent precedes the beginning of the cached
     // extent, ignore this map entry.
-    if (Offset + BytesWritten < MapEntry.first)
+    if (Offset + Data.size() < MapEntry.first)
       continue;
     for (const auto &Alloc : MapEntry.second) {
       // If the end of the cached extent precedes the beginning of the written
@@ -263,7 +273,7 @@ Error MappedBlockStream::writeBytes(uint
         continue;
 
       // If we get here, they are guaranteed to overlap.
-      Interval WriteInterval = std::make_pair(Offset, Offset + BytesWritten);
+      Interval WriteInterval = std::make_pair(Offset, Offset + Data.size());
       Interval CachedInterval =
           std::make_pair(MapEntry.first, MapEntry.first + Alloc.size());
       // If they overlap, we need to write the new data into the overlapping
@@ -276,35 +286,95 @@ Error MappedBlockStream::writeBytes(uint
           AbsoluteDifference(WriteInterval.first, Intersection.first);
       uint32_t DestOffset =
           AbsoluteDifference(CachedInterval.first, Intersection.first);
-      ::memcpy(Alloc.data() + DestOffset, Buffer.data() + SrcOffset, Length);
+      ::memcpy(Alloc.data() + DestOffset, Data.data() + SrcOffset, Length);
     }
   }
+}
 
-  return Error::success();
+WritableMappedBlockStream::WritableMappedBlockStream(
+    uint32_t BlockSize, uint32_t NumBlocks, const MsfStreamLayout &Layout,
+    const WritableStream &MsfData)
+    : ReadInterface(BlockSize, NumBlocks, Layout, MsfData),
+      WriteInterface(MsfData) {}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks,
+                                        const MsfStreamLayout &Layout,
+                                        const WritableStream &MsfData) {
+  return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
+      BlockSize, NumBlocks, Layout, MsfData);
 }
 
-uint32_t MappedBlockStream::getNumBytesCopied() const {
-  return static_cast<uint32_t>(Pool.getBytesAllocated());
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createIndexedStream(const MsfLayout &Layout,
+                                               const WritableStream &MsfData,
+                                               uint32_t StreamIndex) {
+  MsfStreamLayout SL;
+  SL.Blocks = Layout.StreamMap[StreamIndex];
+  SL.Length = Layout.StreamSizes[StreamIndex];
+  return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createDirectoryStream(
+    const MsfLayout &Layout, const WritableStream &MsfData) {
+  MsfStreamLayout SL;
+  SL.Blocks = Layout.DirectoryBlocks;
+  SL.Length = Layout.SB->NumDirectoryBytes;
+  return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
+                                           ArrayRef<uint8_t> &Buffer) const {
+  return ReadInterface.readBytes(Offset, Size, Buffer);
+}
+
+Error WritableMappedBlockStream::readLongestContiguousChunk(
+    uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
+  return ReadInterface.readLongestContiguousChunk(Offset, Buffer);
 }
 
-Expected<std::unique_ptr<MappedBlockStream>>
-MappedBlockStream::createIndexedStream(uint32_t StreamIdx,
-                                       const IMsfFile &File) {
-  if (StreamIdx >= File.getNumStreams())
-    return make_error<MsfError>(msf_error_code::no_stream);
-  MsfStreamLayout L;
-  L.Blocks = File.getStreamBlockList(StreamIdx);
-  L.Length = File.getStreamByteSize(StreamIdx);
-  return llvm::make_unique<MappedBlockStreamImpl>(L, File);
-}
-
-Expected<std::unique_ptr<MappedBlockStream>>
-MappedBlockStream::createDirectoryStream(uint32_t Length,
-                                         ArrayRef<support::ulittle32_t> Blocks,
-                                         const IMsfFile &File) {
-  MsfStreamLayout L;
-  L.Blocks = Blocks;
-  L.Length = Length;
+uint32_t WritableMappedBlockStream::getLength() const {
+  return ReadInterface.getLength();
+}
+
+Error WritableMappedBlockStream::writeBytes(uint32_t Offset,
+                                            ArrayRef<uint8_t> Buffer) const {
+  // Make sure we aren't trying to write beyond the end of the stream.
+  if (Buffer.size() > getStreamLength())
+    return make_error<MsfError>(msf_error_code::insufficient_buffer);
+
+  if (Offset > getStreamLayout().Length - Buffer.size())
+    return make_error<MsfError>(msf_error_code::insufficient_buffer);
+
+  uint32_t BlockNum = Offset / getBlockSize();
+  uint32_t OffsetInBlock = Offset % getBlockSize();
+
+  uint32_t BytesLeft = Buffer.size();
+  uint32_t BytesWritten = 0;
+  while (BytesLeft > 0) {
+    uint32_t StreamBlockAddr = getStreamLayout().Blocks[BlockNum];
+    uint32_t BytesToWriteInChunk =
+        std::min(BytesLeft, getBlockSize() - OffsetInBlock);
+
+    const uint8_t *Chunk = Buffer.data() + BytesWritten;
+    ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
+    uint32_t MsfOffset = blockToOffset(StreamBlockAddr, getBlockSize());
+    MsfOffset += OffsetInBlock;
+    if (auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))
+      return EC;
+
+    BytesLeft -= BytesToWriteInChunk;
+    BytesWritten += BytesToWriteInChunk;
+    ++BlockNum;
+    OffsetInBlock = 0;
+  }
+
+  ReadInterface.fixCacheAfterWrite(Offset, Buffer);
+
+  return Error::success();
+}
 
-  return llvm::make_unique<MappedBlockStreamImpl>(L, File);
+Error WritableMappedBlockStream::commit() const {
+  return WriteInterface.commit();
 }

Modified: llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp Thu Jul 28 14:12:28 2016
@@ -1,4 +1,3 @@
-//===- MSFBuilder.cpp - MSF Directory & Metadata Builder --------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -218,9 +217,9 @@ uint32_t MsfBuilder::computeDirectoryByt
   return Size;
 }
 
-Expected<Layout> MsfBuilder::build() {
+Expected<MsfLayout> MsfBuilder::build() {
   SuperBlock *SB = Allocator.Allocate<SuperBlock>();
-  Layout L;
+  MsfLayout L;
   L.SB = SB;
 
   std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));

Modified: llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp Thu Jul 28 14:12:28 2016
@@ -15,7 +15,7 @@
 using namespace llvm;
 using namespace llvm::msf;
 
-StreamReader::StreamReader(StreamRef S) : Stream(S), Offset(0) {}
+StreamReader::StreamReader(ReadableStreamRef S) : Stream(S), Offset(0) {}
 
 Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) {
   if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer))
@@ -80,11 +80,11 @@ Error StreamReader::readFixedString(Stri
   return Error::success();
 }
 
-Error StreamReader::readStreamRef(StreamRef &Ref) {
+Error StreamReader::readStreamRef(ReadableStreamRef &Ref) {
   return readStreamRef(Ref, bytesRemaining());
 }
 
-Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) {
+Error StreamReader::readStreamRef(ReadableStreamRef &Ref, uint32_t Length) {
   if (bytesRemaining() < Length)
     return make_error<MsfError>(msf_error_code::insufficient_buffer);
   Ref = Stream.slice(Offset, Length);

Modified: llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp Thu Jul 28 14:12:28 2016
@@ -16,7 +16,7 @@
 using namespace llvm;
 using namespace llvm::msf;
 
-StreamWriter::StreamWriter(StreamRef S) : Stream(S), Offset(0) {}
+StreamWriter::StreamWriter(WritableStreamRef S) : Stream(S), Offset(0) {}
 
 Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
   if (auto EC = Stream.writeBytes(Offset, Buffer))
@@ -51,7 +51,7 @@ Error StreamWriter::writeFixedString(Str
   return Error::success();
 }
 
-Error StreamWriter::writeStreamRef(StreamRef Ref) {
+Error StreamWriter::writeStreamRef(ReadableStreamRef Ref) {
   if (auto EC = writeStreamRef(Ref, Ref.getLength()))
     return EC;
   // Don't increment Offset here, it is done by the overloaded call to
@@ -59,7 +59,7 @@ Error StreamWriter::writeStreamRef(Strea
   return Error::success();
 }
 
-Error StreamWriter::writeStreamRef(StreamRef Ref, uint32_t Length) {
+Error StreamWriter::writeStreamRef(ReadableStreamRef Ref, uint32_t Length) {
   Ref = Ref.slice(0, Length);
 
   StreamReader SrcReader(Ref);

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Thu Jul 28 14:12:28 2016
@@ -272,22 +272,21 @@ Error DbiStream::initializeSectionHeader
   if (StreamNum >= Pdb.getNumStreams())
     return make_error<RawError>(raw_error_code::no_stream);
 
-  auto SHS = MappedBlockStream::createIndexedStream(StreamNum, Pdb);
-  if (!SHS)
-    return SHS.takeError();
+  auto SHS = MappedBlockStream::createIndexedStream(
+      Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
 
-  size_t StreamLen = (*SHS)->getLength();
+  size_t StreamLen = SHS->getLength();
   if (StreamLen % sizeof(object::coff_section))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Corrupted section header stream.");
 
   size_t NumSections = StreamLen / sizeof(object::coff_section);
-  msf::StreamReader Reader(**SHS);
+  msf::StreamReader Reader(*SHS);
   if (auto EC = Reader.readArray(SectionHeaders, NumSections))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Could not read a bitmap.");
 
-  SectionHeaderStream = std::move(*SHS);
+  SectionHeaderStream = std::move(SHS);
   return Error::success();
 }
 
@@ -305,21 +304,20 @@ Error DbiStream::initializeFpoRecords()
   if (StreamNum >= Pdb.getNumStreams())
     return make_error<RawError>(raw_error_code::no_stream);
 
-  auto FS = MappedBlockStream::createIndexedStream(StreamNum, Pdb);
-  if (!FS)
-    return FS.takeError();
+  auto FS = MappedBlockStream::createIndexedStream(
+      Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
 
-  size_t StreamLen = (*FS)->getLength();
+  size_t StreamLen = FS->getLength();
   if (StreamLen % sizeof(object::FpoData))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Corrupted New FPO stream.");
 
   size_t NumRecords = StreamLen / sizeof(object::FpoData);
-  msf::StreamReader Reader(**FS);
+  msf::StreamReader Reader(*FS);
   if (auto EC = Reader.readArray(FpoRecords, NumRecords))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Corrupted New FPO stream.");
-  FpoStream = std::move(*FS);
+  FpoStream = std::move(FS);
   return Error::success();
 }
 
@@ -421,32 +419,3 @@ Expected<StringRef> DbiStream::getFileNa
     return std::move(EC);
   return Name;
 }
-
-Error DbiStream::commit() {
-  StreamWriter Writer(*Stream);
-  if (auto EC = Writer.writeObject(*Header))
-    return EC;
-
-  if (auto EC = Writer.writeStreamRef(ModInfoSubstream))
-    return EC;
-
-  if (auto EC = Writer.writeStreamRef(SecContrSubstream,
-                                      SecContrSubstream.getLength()))
-    return EC;
-  if (auto EC =
-          Writer.writeStreamRef(SecMapSubstream, SecMapSubstream.getLength()))
-    return EC;
-  if (auto EC = Writer.writeStreamRef(FileInfoSubstream,
-                                      FileInfoSubstream.getLength()))
-    return EC;
-  if (auto EC = Writer.writeStreamRef(TypeServerMapSubstream,
-                                      TypeServerMapSubstream.getLength()))
-    return EC;
-  if (auto EC = Writer.writeStreamRef(ECSubstream, ECSubstream.getLength()))
-    return EC;
-
-  if (Writer.bytesRemaining() > 0)
-    return make_error<RawError>(raw_error_code::invalid_format,
-                                "Unexpected bytes found in DBI Stream");
-  return Error::success();
-}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp Thu Jul 28 14:12:28 2016
@@ -25,7 +25,7 @@ class ModiSubstreamBuilder {};
 
 DbiStreamBuilder::DbiStreamBuilder(BumpPtrAllocator &Allocator)
     : Allocator(Allocator), Age(1), BuildNumber(0), PdbDllVersion(0),
-      PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86) {}
+      PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86), Header(nullptr) {}
 
 void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
 
@@ -108,7 +108,7 @@ Error DbiStreamBuilder::generateModiSubs
   uint32_t Size = calculateModiSubstreamSize();
   auto Data = Allocator.Allocate<uint8_t>(Size);
 
-  ModInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+  ModInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
 
   StreamWriter ModiWriter(ModInfoBuffer);
   for (const auto &M : ModuleInfoList) {
@@ -134,9 +134,10 @@ Error DbiStreamBuilder::generateFileInfo
   auto Data = Allocator.Allocate<uint8_t>(Size);
   uint32_t NamesOffset = Size - NameSize;
 
-  FileInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+  FileInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
 
-  StreamRef MetadataBuffer = StreamRef(FileInfoBuffer).keep_front(NamesOffset);
+  WritableStreamRef MetadataBuffer =
+      WritableStreamRef(FileInfoBuffer).keep_front(NamesOffset);
   StreamWriter MetadataWriter(MetadataBuffer);
 
   uint16_t ModiCount = std::min<uint16_t>(UINT16_MAX, ModuleInfos.size());
@@ -159,7 +160,7 @@ Error DbiStreamBuilder::generateFileInfo
   // A side effect of this is that this will actually compute the various
   // file name offsets, so we can then go back and write the FileNameOffsets
   // array to the other substream.
-  NamesBuffer = StreamRef(FileInfoBuffer).drop_front(NamesOffset);
+  NamesBuffer = WritableStreamRef(FileInfoBuffer).drop_front(NamesOffset);
   StreamWriter NameBufferWriter(NamesBuffer);
   for (auto &Name : SourceFileNames) {
     Name.second = NameBufferWriter.getOffset();
@@ -190,16 +191,11 @@ Error DbiStreamBuilder::generateFileInfo
   return Error::success();
 }
 
-Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build(PDBFile &File) {
-  if (!VerHeader.hasValue())
-    return make_error<RawError>(raw_error_code::unspecified,
-                                "Missing DBI Stream Version");
+Error DbiStreamBuilder::finalize() {
+  if (Header)
+    return Error::success();
 
-  auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, File);
-  if (!DbiS)
-    return DbiS.takeError();
-  auto DS = std::move(*DbiS);
-  DbiStreamHeader *H = DS->getAllocator().Allocate<DbiStreamHeader>(1);
+  DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
 
   if (auto EC = generateModiSubstream())
     return std::move(EC);
@@ -227,13 +223,47 @@ Expected<std::unique_ptr<DbiStream>> Dbi
   H->MFCTypeServerIndex = kInvalidStreamIndex;
   H->GlobalSymbolStreamIndex = kInvalidStreamIndex;
 
-  auto Dbi = llvm::make_unique<DbiStream>(File, std::move(DS));
-  Dbi->Header = H;
-  Dbi->FileInfoSubstream = StreamRef(FileInfoBuffer);
-  Dbi->ModInfoSubstream = StreamRef(ModInfoBuffer);
+  Header = H;
+  return Error::success();
+}
+
+Expected<std::unique_ptr<DbiStream>>
+DbiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
+  if (!VerHeader.hasValue())
+    return make_error<RawError>(raw_error_code::unspecified,
+                                "Missing DBI Stream Version");
+  if (auto EC = finalize())
+    return std::move(EC);
+
+  auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
+                                                           Buffer, StreamDBI);
+  auto Dbi = llvm::make_unique<DbiStream>(File, std::move(StreamData));
+  Dbi->Header = Header;
+  Dbi->FileInfoSubstream = ReadableStreamRef(FileInfoBuffer);
+  Dbi->ModInfoSubstream = ReadableStreamRef(ModInfoBuffer);
   if (auto EC = Dbi->initializeModInfoArray())
     return std::move(EC);
   if (auto EC = Dbi->initializeFileInfo())
     return std::move(EC);
   return std::move(Dbi);
 }
+
+Error DbiStreamBuilder::commit(const msf::MsfLayout &Layout,
+                               const msf::WritableStream &Buffer) const {
+  auto InfoS =
+      WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamDBI);
+
+  StreamWriter Writer(*InfoS);
+  if (auto EC = Writer.writeObject(*Header))
+    return EC;
+
+  if (auto EC = Writer.writeStreamRef(ModInfoBuffer))
+    return EC;
+  if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
+    return EC;
+
+  if (Writer.bytesRemaining() > 0)
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "Unexpected bytes found in DBI Stream");
+  return Error::success();
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp Thu Jul 28 14:12:28 2016
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
@@ -27,7 +28,7 @@ InfoStream::InfoStream(std::unique_ptr<M
 Error InfoStream::reload() {
   StreamReader Reader(*Stream);
 
-  const HeaderInfo *H;
+  const InfoStreamHeader *H;
   if (auto EC = Reader.readObject(H))
     return joinErrors(
         std::move(EC),
@@ -74,17 +75,3 @@ uint32_t InfoStream::getSignature() cons
 uint32_t InfoStream::getAge() const { return Age; }
 
 PDB_UniqueId InfoStream::getGuid() const { return Guid; }
-
-Error InfoStream::commit() {
-  StreamWriter Writer(*Stream);
-
-  HeaderInfo H;
-  H.Age = Age;
-  H.Signature = Signature;
-  H.Version = Version;
-  H.Guid = Guid;
-  if (auto EC = Writer.writeObject(H))
-    return EC;
-
-  return NamedStreams.commit(Writer);
-}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp Thu Jul 28 14:12:28 2016
@@ -13,13 +13,15 @@
 #include "llvm/DebugInfo/Msf/StreamWriter.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
-InfoStreamBuilder::InfoStreamBuilder() {}
+InfoStreamBuilder::InfoStreamBuilder()
+    : Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
 
 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
 
@@ -34,35 +36,38 @@ NameMapBuilder &InfoStreamBuilder::getNa
 }
 
 uint32_t InfoStreamBuilder::calculateSerializedLength() const {
-  return sizeof(InfoStream::HeaderInfo) +
-         NamedStreams.calculateSerializedLength();
+  return sizeof(InfoStreamHeader) + NamedStreams.calculateSerializedLength();
 }
 
-Expected<std::unique_ptr<InfoStream>> InfoStreamBuilder::build(PDBFile &File) {
-  if (!Ver.hasValue())
-    return make_error<RawError>(raw_error_code::unspecified,
-                                "Missing PDB Stream Version");
-  if (!Sig.hasValue())
-    return make_error<RawError>(raw_error_code::unspecified,
-                                "Missing PDB Stream Signature");
-  if (!Age.hasValue())
-    return make_error<RawError>(raw_error_code::unspecified,
-                                "Missing PDB Stream Age");
-  if (!Guid.hasValue())
-    return make_error<RawError>(raw_error_code::unspecified,
-                                "Missing PDB Stream Guid");
-
-  auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, File);
-  if (!InfoS)
-    return InfoS.takeError();
-  auto Info = llvm::make_unique<InfoStream>(std::move(*InfoS));
-  Info->Version = *Ver;
-  Info->Signature = *Sig;
-  Info->Age = *Age;
-  Info->Guid = *Guid;
+Expected<std::unique_ptr<InfoStream>>
+InfoStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
+  auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
+                                                           Buffer, StreamPDB);
+  auto Info = llvm::make_unique<InfoStream>(std::move(StreamData));
+  Info->Version = Ver;
+  Info->Signature = Sig;
+  Info->Age = Age;
+  Info->Guid = Guid;
   auto NS = NamedStreams.build();
   if (!NS)
     return NS.takeError();
   Info->NamedStreams = **NS;
   return std::move(Info);
 }
+
+Error InfoStreamBuilder::commit(const msf::MsfLayout &Layout,
+                                const msf::WritableStream &Buffer) const {
+  auto InfoS =
+      WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamPDB);
+  StreamWriter Writer(*InfoS);
+
+  InfoStreamHeader H;
+  H.Age = Age;
+  H.Signature = Sig;
+  H.Version = Ver;
+  H.Guid = Guid;
+  if (auto EC = Writer.writeObject(H))
+    return EC;
+
+  return NamedStreams.commit(Writer);
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp Thu Jul 28 14:12:28 2016
@@ -27,7 +27,7 @@ ModInfo::ModInfo(const ModInfo &Info)
 
 ModInfo::~ModInfo() {}
 
-Error ModInfo::initialize(StreamRef Stream, ModInfo &Info) {
+Error ModInfo::initialize(ReadableStreamRef Stream, ModInfo &Info) {
   StreamReader Reader(Stream);
   if (auto EC = Reader.readObject(Info.Layout))
     return EC;

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp Thu Jul 28 14:12:28 2016
@@ -36,7 +36,7 @@ Error ModStream::reload() {
     return llvm::make_error<RawError>(raw_error_code::corrupt_file,
                                       "Module has both C11 and C13 line info");
 
-  StreamRef S;
+  ReadableStreamRef S;
 
   uint32_t SymbolSubstreamSig = 0;
   if (auto EC = Reader.readInteger(SymbolSubstreamSig))

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp Thu Jul 28 14:12:28 2016
@@ -145,60 +145,6 @@ Error NameMap::load(StreamReader &Stream
   return Error::success();
 }
 
-Error NameMap::commit(StreamWriter &Writer) {
-  // The first field is the number of bytes of string data.  So add
-  // up the length of all strings plus a null terminator for each
-  // one.
-  uint32_t NumBytes = 0;
-  for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
-    NumBytes += B->getKeyLength() + 1;
-  }
-
-  if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data
-    return EC;
-  // Now all of the string data itself.
-  for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
-    if (auto EC = Writer.writeZeroString(B->getKey()))
-      return EC;
-  }
-
-  if (auto EC = Writer.writeInteger(Mapping.size())) // Hash Size
-    return EC;
-
-  if (auto EC = Writer.writeInteger(Mapping.size())) // Max Number of Strings
-    return EC;
-
-  if (auto EC = Writer.writeInteger(Mapping.size())) // Num Present Words
-    return EC;
-
-  // For each entry in the mapping, write a bit mask which represents a bucket
-  // to store it in.  We don't use this, so the value we write isn't important
-  // to us, it just has to be there.
-  for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
-    if (auto EC = Writer.writeInteger(1U))
-      return EC;
-  }
-
-  if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
-    return EC;
-
-  // Mappings of each word.
-  uint32_t OffsetSoFar = 0;
-  for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
-    // This is a list of key value pairs where the key is the offset into the
-    // strings buffer, and the value is a stream number.  Write each pair.
-    if (auto EC = Writer.writeInteger(OffsetSoFar))
-      return EC;
-
-    if (auto EC = Writer.writeInteger(B->second))
-      return EC;
-
-    OffsetSoFar += B->getKeyLength() + 1;
-  }
-
-  return Error::success();
-}
-
 iterator_range<StringMapConstIterator<uint32_t>> NameMap::entries() const {
   return llvm::make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
                                                             Mapping.end());

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp Thu Jul 28 14:12:28 2016
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h"
 
+#include "llvm/DebugInfo/Msf/StreamWriter.h"
 #include "llvm/DebugInfo/PDB/Raw/NameMap.h"
 #include "llvm/Support/Endian.h"
 
@@ -48,3 +49,57 @@ uint32_t NameMapBuilder::calculateSerial
 
   return TotalLength;
 }
+
+Error NameMapBuilder::commit(msf::StreamWriter &Writer) const {
+  // The first field is the number of bytes of string data.  So add
+  // up the length of all strings plus a null terminator for each
+  // one.
+  uint32_t NumBytes = 0;
+  for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+    NumBytes += B->getKeyLength() + 1;
+  }
+
+  if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data
+    return EC;
+  // Now all of the string data itself.
+  for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+    if (auto EC = Writer.writeZeroString(B->getKey()))
+      return EC;
+  }
+
+  if (auto EC = Writer.writeInteger(Map.size())) // Hash Size
+    return EC;
+
+  if (auto EC = Writer.writeInteger(Map.size())) // Max Number of Strings
+    return EC;
+
+  if (auto EC = Writer.writeInteger(Map.size())) // Num Present Words
+    return EC;
+
+  // For each entry in the mapping, write a bit mask which represents a bucket
+  // to store it in.  We don't use this, so the value we write isn't important
+  // to us, it just has to be there.
+  for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+    if (auto EC = Writer.writeInteger(1U))
+      return EC;
+  }
+
+  if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
+    return EC;
+
+  // Mappings of each word.
+  uint32_t OffsetSoFar = 0;
+  for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+    // This is a list of key value pairs where the key is the offset into the
+    // strings buffer, and the value is a stream number.  Write each pair.
+    if (auto EC = Writer.writeInteger(OffsetSoFar))
+      return EC;
+
+    if (auto EC = Writer.writeInteger(B->second))
+      return EC;
+
+    OffsetSoFar += B->getKeyLength() + 1;
+  }
+
+  return Error::success();
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Thu Jul 28 14:12:28 2016
@@ -34,48 +34,53 @@ namespace {
 typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
 }
 
-PDBFile::PDBFile(std::unique_ptr<StreamInterface> PdbFileBuffer,
+PDBFile::PDBFile(std::unique_ptr<ReadableStream> PdbFileBuffer,
                  BumpPtrAllocator &Allocator)
     : Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
 
 PDBFile::~PDBFile() {}
 
-uint32_t PDBFile::getBlockSize() const { return MsfLayout.SB->BlockSize; }
+uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }
 
 uint32_t PDBFile::getFreeBlockMapBlock() const {
-  return MsfLayout.SB->FreeBlockMapBlock;
+  return ContainerLayout.SB->FreeBlockMapBlock;
 }
 
-uint32_t PDBFile::getBlockCount() const { return MsfLayout.SB->NumBlocks; }
+uint32_t PDBFile::getBlockCount() const {
+  return ContainerLayout.SB->NumBlocks;
+}
 
 uint32_t PDBFile::getNumDirectoryBytes() const {
-  return MsfLayout.SB->NumDirectoryBytes;
+  return ContainerLayout.SB->NumDirectoryBytes;
 }
 
 uint32_t PDBFile::getBlockMapIndex() const {
-  return MsfLayout.SB->BlockMapAddr;
+  return ContainerLayout.SB->BlockMapAddr;
 }
 
-uint32_t PDBFile::getUnknown1() const { return MsfLayout.SB->Unknown1; }
+uint32_t PDBFile::getUnknown1() const { return ContainerLayout.SB->Unknown1; }
 
 uint32_t PDBFile::getNumDirectoryBlocks() const {
-  return msf::bytesToBlocks(MsfLayout.SB->NumDirectoryBytes,
-                            MsfLayout.SB->BlockSize);
+  return msf::bytesToBlocks(ContainerLayout.SB->NumDirectoryBytes,
+                            ContainerLayout.SB->BlockSize);
 }
 
 uint64_t PDBFile::getBlockMapOffset() const {
-  return (uint64_t)MsfLayout.SB->BlockMapAddr * MsfLayout.SB->BlockSize;
+  return (uint64_t)ContainerLayout.SB->BlockMapAddr *
+         ContainerLayout.SB->BlockSize;
 }
 
-uint32_t PDBFile::getNumStreams() const { return MsfLayout.StreamSizes.size(); }
+uint32_t PDBFile::getNumStreams() const {
+  return ContainerLayout.StreamSizes.size();
+}
 
 uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
-  return MsfLayout.StreamSizes[StreamIndex];
+  return ContainerLayout.StreamSizes[StreamIndex];
 }
 
 ArrayRef<support::ulittle32_t>
 PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
-  return MsfLayout.StreamMap[StreamIndex];
+  return ContainerLayout.StreamMap[StreamIndex];
 }
 
 uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
@@ -92,18 +97,8 @@ Expected<ArrayRef<uint8_t>> PDBFile::get
 
 Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
                             ArrayRef<uint8_t> Data) const {
-  if (Offset >= getBlockSize())
-    return make_error<RawError>(
-        raw_error_code::invalid_block_address,
-        "setBlockData attempted to write out of block bounds.");
-  if (Data.size() > getBlockSize() - Offset)
-    return make_error<RawError>(
-        raw_error_code::invalid_block_address,
-        "setBlockData attempted to write out of block bounds.");
-
-  uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
-  StreamBlockOffset += Offset;
-  return Buffer->writeBytes(StreamBlockOffset, Data);
+  return make_error<RawError>(raw_error_code::not_writable,
+                              "PDBFile is immutable");
 }
 
 Error PDBFile::parseFileHeaders() {
@@ -122,18 +117,18 @@ Error PDBFile::parseFileHeaders() {
   if (Buffer->getLength() % SB->BlockSize != 0)
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "File size is not a multiple of block size");
-  MsfLayout.SB = SB;
+  ContainerLayout.SB = SB;
 
   Reader.setOffset(getBlockMapOffset());
-  if (auto EC =
-          Reader.readArray(MsfLayout.DirectoryBlocks, getNumDirectoryBlocks()))
+  if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,
+                                 getNumDirectoryBlocks()))
     return EC;
 
   return Error::success();
 }
 
 Error PDBFile::parseStreamData() {
-  assert(MsfLayout.SB);
+  assert(ContainerLayout.SB);
   if (DirectoryStream)
     return Error::success();
 
@@ -144,15 +139,12 @@ Error PDBFile::parseStreamData() {
   // is exactly what we are attempting to parse.  By specifying a custom
   // subclass of IPDBStreamData which only accesses the fields that have already
   // been parsed, we can avoid this and reuse MappedBlockStream.
-  auto DS = MappedBlockStream::createDirectoryStream(
-      MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
-  if (!DS)
-    return DS.takeError();
-  StreamReader Reader(**DS);
+  auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer);
+  StreamReader Reader(*DS);
   if (auto EC = Reader.readInteger(NumStreams))
     return EC;
 
-  if (auto EC = Reader.readArray(MsfLayout.StreamSizes, NumStreams))
+  if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
     return EC;
   for (uint32_t I = 0; I < NumStreams; ++I) {
     uint32_t StreamSize = getStreamByteSize(I);
@@ -160,7 +152,7 @@ Error PDBFile::parseStreamData() {
     uint64_t NumExpectedStreamBlocks =
         StreamSize == UINT32_MAX
             ? 0
-            : msf::bytesToBlocks(StreamSize, MsfLayout.SB->BlockSize);
+            : msf::bytesToBlocks(StreamSize, ContainerLayout.SB->BlockSize);
 
     // For convenience, we store the block array contiguously.  This is because
     // if someone calls setStreamMap(), it is more convenient to be able to call
@@ -172,30 +164,30 @@ Error PDBFile::parseStreamData() {
     if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
       return EC;
     for (uint32_t Block : Blocks) {
-      uint64_t BlockEndOffset = (uint64_t)(Block + 1) * MsfLayout.SB->BlockSize;
+      uint64_t BlockEndOffset =
+          (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;
       if (BlockEndOffset > getFileSize())
         return make_error<RawError>(raw_error_code::corrupt_file,
                                     "Stream block map is corrupt.");
     }
-    MsfLayout.StreamMap.push_back(Blocks);
+    ContainerLayout.StreamMap.push_back(Blocks);
   }
 
   // We should have read exactly SB->NumDirectoryBytes bytes.
   assert(Reader.bytesRemaining() == 0);
-  DirectoryStream = std::move(*DS);
+  DirectoryStream = std::move(DS);
   return Error::success();
 }
 
 llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
-  return MsfLayout.DirectoryBlocks;
+  return ContainerLayout.DirectoryBlocks;
 }
 
 Expected<InfoStream &> PDBFile::getPDBInfoStream() {
   if (!Info) {
-    auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
-    if (!InfoS)
-      return InfoS.takeError();
-    auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
+    auto InfoS = MappedBlockStream::createIndexedStream(ContainerLayout,
+                                                        *Buffer, StreamPDB);
+    auto TempInfo = llvm::make_unique<InfoStream>(std::move(InfoS));
     if (auto EC = TempInfo->reload())
       return std::move(EC);
     Info = std::move(TempInfo);
@@ -205,10 +197,9 @@ Expected<InfoStream &> PDBFile::getPDBIn
 
 Expected<DbiStream &> PDBFile::getPDBDbiStream() {
   if (!Dbi) {
-    auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, *this);
-    if (!DbiS)
-      return DbiS.takeError();
-    auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS));
+    auto DbiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+                                                       StreamDBI);
+    auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(DbiS));
     if (auto EC = TempDbi->reload())
       return std::move(EC);
     Dbi = std::move(TempDbi);
@@ -218,10 +209,9 @@ Expected<DbiStream &> PDBFile::getPDBDbi
 
 Expected<TpiStream &> PDBFile::getPDBTpiStream() {
   if (!Tpi) {
-    auto TpiS = MappedBlockStream::createIndexedStream(StreamTPI, *this);
-    if (!TpiS)
-      return TpiS.takeError();
-    auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
+    auto TpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+                                                       StreamTPI);
+    auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(TpiS));
     if (auto EC = TempTpi->reload())
       return std::move(EC);
     Tpi = std::move(TempTpi);
@@ -231,10 +221,9 @@ Expected<TpiStream &> PDBFile::getPDBTpi
 
 Expected<TpiStream &> PDBFile::getPDBIpiStream() {
   if (!Ipi) {
-    auto IpiS = MappedBlockStream::createIndexedStream(StreamIPI, *this);
-    if (!IpiS)
-      return IpiS.takeError();
-    auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
+    auto IpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+                                                       StreamIPI);
+    auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(IpiS));
     if (auto EC = TempIpi->reload())
       return std::move(EC);
     Ipi = std::move(TempIpi);
@@ -250,12 +239,10 @@ Expected<PublicsStream &> PDBFile::getPD
 
     uint32_t PublicsStreamNum = DbiS->getPublicSymbolStreamIndex();
 
-    auto PublicS =
-        MappedBlockStream::createIndexedStream(PublicsStreamNum, *this);
-    if (!PublicS)
-      return PublicS.takeError();
+    auto PublicS = MappedBlockStream::createIndexedStream(
+        ContainerLayout, *Buffer, PublicsStreamNum);
     auto TempPublics =
-        llvm::make_unique<PublicsStream>(*this, std::move(*PublicS));
+        llvm::make_unique<PublicsStream>(*this, std::move(PublicS));
     if (auto EC = TempPublics->reload())
       return std::move(EC);
     Publics = std::move(TempPublics);
@@ -270,12 +257,10 @@ Expected<SymbolStream &> PDBFile::getPDB
       return DbiS.takeError();
 
     uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
+    auto SymbolS = MappedBlockStream::createIndexedStream(
+        ContainerLayout, *Buffer, SymbolStreamNum);
 
-    auto SymbolS =
-        MappedBlockStream::createIndexedStream(SymbolStreamNum, *this);
-    if (!SymbolS)
-      return SymbolS.takeError();
-    auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
+    auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(SymbolS));
     if (auto EC = TempSymbols->reload())
       return std::move(EC);
     Symbols = std::move(TempSymbols);
@@ -295,76 +280,15 @@ Expected<NameHashTable &> PDBFile::getSt
       return make_error<RawError>(raw_error_code::no_stream);
     if (NameStreamIndex >= getNumStreams())
       return make_error<RawError>(raw_error_code::no_stream);
+    auto NS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+                                                     NameStreamIndex);
 
-    auto NS = MappedBlockStream::createIndexedStream(NameStreamIndex, *this);
-    if (!NS)
-      return NS.takeError();
-
-    StreamReader Reader(**NS);
+    StreamReader Reader(*NS);
     auto N = llvm::make_unique<NameHashTable>();
     if (auto EC = N->load(Reader))
       return std::move(EC);
     StringTable = std::move(N);
-    StringTableStream = std::move(*NS);
+    StringTableStream = std::move(NS);
   }
   return *StringTable;
 }
-
-Error PDBFile::commit() {
-  StreamWriter Writer(*Buffer);
-
-  if (auto EC = Writer.writeObject(*MsfLayout.SB))
-    return EC;
-  Writer.setOffset(getBlockMapOffset());
-  if (auto EC = Writer.writeArray(MsfLayout.DirectoryBlocks))
-    return EC;
-
-  auto DS = MappedBlockStream::createDirectoryStream(
-      MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
-  if (!DS)
-    return DS.takeError();
-  auto DirStream = std::move(*DS);
-  StreamWriter DW(*DirStream);
-  if (auto EC = DW.writeInteger(this->getNumStreams()))
-    return EC;
-
-  if (auto EC = DW.writeArray(MsfLayout.StreamSizes))
-    return EC;
-
-  for (const auto &Blocks : MsfLayout.StreamMap) {
-    if (auto EC = DW.writeArray(Blocks))
-      return EC;
-  }
-
-  if (Info) {
-    if (auto EC = Info->commit())
-      return EC;
-  }
-
-  if (Dbi) {
-    if (auto EC = Dbi->commit())
-      return EC;
-  }
-
-  if (Symbols) {
-    if (auto EC = Symbols->commit())
-      return EC;
-  }
-
-  if (Publics) {
-    if (auto EC = Publics->commit())
-      return EC;
-  }
-
-  if (Tpi) {
-    if (auto EC = Tpi->commit())
-      return EC;
-  }
-
-  if (Ipi) {
-    if (auto EC = Ipi->commit())
-      return EC;
-  }
-
-  return Buffer->commit();
-}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp Thu Jul 28 14:12:28 2016
@@ -58,7 +58,7 @@ DbiStreamBuilder &PDBFileBuilder::getDbi
   return *Dbi;
 }
 
-Expected<msf::Layout> PDBFileBuilder::finalizeMsfLayout() const {
+Expected<msf::MsfLayout> PDBFileBuilder::finalizeMsfLayout() const {
   if (Info) {
     uint32_t Length = Info->calculateSerializedLength();
     if (auto EC = Msf->setStreamSize(StreamPDB, Length))
@@ -74,23 +74,23 @@ Expected<msf::Layout> PDBFileBuilder::fi
 }
 
 Expected<std::unique_ptr<PDBFile>>
-PDBFileBuilder::build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer) {
+PDBFileBuilder::build(std::unique_ptr<msf::WritableStream> PdbFileBuffer) {
   auto ExpectedLayout = finalizeMsfLayout();
   if (!ExpectedLayout)
     return ExpectedLayout.takeError();
 
   auto File = llvm::make_unique<PDBFile>(std::move(PdbFileBuffer), Allocator);
-  File->MsfLayout = *ExpectedLayout;
+  File->ContainerLayout = *ExpectedLayout;
 
   if (Info) {
-    auto ExpectedInfo = Info->build(*File);
+    auto ExpectedInfo = Info->build(*File, *PdbFileBuffer);
     if (!ExpectedInfo)
       return ExpectedInfo.takeError();
     File->Info = std::move(*ExpectedInfo);
   }
 
   if (Dbi) {
-    auto ExpectedDbi = Dbi->build(*File);
+    auto ExpectedDbi = Dbi->build(*File, *PdbFileBuffer);
     if (!ExpectedDbi)
       return ExpectedDbi.takeError();
     File->Dbi = std::move(*ExpectedDbi);
@@ -103,3 +103,45 @@ PDBFileBuilder::build(std::unique_ptr<ms
 
   return std::move(File);
 }
+
+Error PDBFileBuilder::commit(const msf::WritableStream &Buffer) {
+  StreamWriter Writer(Buffer);
+  auto ExpectedLayout = finalizeMsfLayout();
+  if (!ExpectedLayout)
+    return ExpectedLayout.takeError();
+  auto &Layout = *ExpectedLayout;
+
+  if (auto EC = Writer.writeObject(*Layout.SB))
+    return EC;
+  uint32_t BlockMapOffset =
+      msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
+  Writer.setOffset(BlockMapOffset);
+  if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
+    return EC;
+
+  auto DirStream =
+      WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
+  StreamWriter DW(*DirStream);
+  if (auto EC = DW.writeInteger(Layout.StreamSizes.size()))
+    return EC;
+
+  if (auto EC = DW.writeArray(Layout.StreamSizes))
+    return EC;
+
+  for (const auto &Blocks : Layout.StreamMap) {
+    if (auto EC = DW.writeArray(Blocks))
+      return EC;
+  }
+
+  if (Info) {
+    if (auto EC = Info->commit(Layout, Buffer))
+      return EC;
+  }
+
+  if (Dbi) {
+    if (auto EC = Dbi->commit(Layout, Buffer))
+      return EC;
+  }
+
+  return Buffer.commit();
+}
\ No newline at end of file

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp Thu Jul 28 14:12:28 2016
@@ -26,21 +26,6 @@ using namespace llvm;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
-namespace {
-// We need a class which behaves like an immutable ByteStream, but whose data
-// is backed by an llvm::MemoryBuffer.  It also needs to own the underlying
-// MemoryBuffer, so this simple adapter is a good way to achieve that.
-class InputByteStream : public ByteStream<false> {
-public:
-  explicit InputByteStream(std::unique_ptr<MemoryBuffer> Buffer)
-      : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
-                                     Buffer->getBuffer().bytes_end())),
-        MemBuffer(std::move(Buffer)) {}
-
-  std::unique_ptr<MemoryBuffer> MemBuffer;
-};
-}
-
 RawSession::RawSession(std::unique_ptr<PDBFile> PdbFile,
                        std::unique_ptr<BumpPtrAllocator> Allocator)
     : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
@@ -57,7 +42,7 @@ Error RawSession::createFromPdb(StringRe
     return llvm::make_error<GenericError>(generic_error_code::invalid_path);
 
   std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
-  auto Stream = llvm::make_unique<InputByteStream>(std::move(Buffer));
+  auto Stream = llvm::make_unique<MemoryBufferByteStream>(std::move(Buffer));
 
   auto Allocator = llvm::make_unique<BumpPtrAllocator>();
   auto File = llvm::make_unique<PDBFile>(std::move(Stream), *Allocator);

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Thu Jul 28 14:12:28 2016
@@ -188,12 +188,9 @@ Error TpiStream::reload() {
   if (Header->HashStreamIndex >= Pdb.getNumStreams())
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Invalid TPI hash stream index.");
-
-  auto HS =
-      MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
-  if (!HS)
-    return HS.takeError();
-  StreamReader HSR(**HS);
+  auto HS = MappedBlockStream::createIndexedStream(
+      Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex);
+  StreamReader HSR(*HS);
 
   uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
   if (NumHashValues != NumTypeRecords())
@@ -216,7 +213,7 @@ Error TpiStream::reload() {
   if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
     return EC;
 
-  HashStream = std::move(*HS);
+  HashStream = std::move(HS);
 
   // TPI hash table is a parallel array for the type records.
   // Verify that the hash values match with type records.

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Thu Jul 28 14:12:28 2016
@@ -259,10 +259,9 @@ Error LLVMOutputStyle::dumpStreamData()
   if (DumpStreamNum >= StreamCount)
     return make_error<RawError>(raw_error_code::no_stream);
 
-  auto S = MappedBlockStream::createIndexedStream(DumpStreamNum, File);
-  if (!S)
-    return S.takeError();
-  StreamReader R(**S);
+  auto S = MappedBlockStream::createIndexedStream(
+      File.getMsfLayout(), File.getMsfBuffer(), DumpStreamNum);
+  StreamReader R(*S);
   while (R.bytesRemaining() > 0) {
     ArrayRef<uint8_t> Data;
     uint32_t BytesToReadInBlock = std::min(
@@ -311,11 +310,9 @@ Error LLVMOutputStyle::dumpNamedStream()
     DictScope D(P, Name);
     P.printNumber("Index", NameStreamIndex);
 
-    auto NameStream =
-        MappedBlockStream::createIndexedStream(NameStreamIndex, File);
-    if (!NameStream)
-      return NameStream.takeError();
-    StreamReader Reader(**NameStream);
+    auto NameStream = MappedBlockStream::createIndexedStream(
+        File.getMsfLayout(), File.getMsfBuffer(), NameStreamIndex);
+    StreamReader Reader(*NameStream);
 
     NameHashTable NameTable;
     if (auto EC = NameTable.load(Reader))
@@ -486,10 +483,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
           (opts::raw::DumpModuleSyms || opts::raw::DumpSymRecordBytes);
       if (HasModuleDI && (ShouldDumpSymbols || opts::raw::DumpLineInfo)) {
         auto ModStreamData = MappedBlockStream::createIndexedStream(
-            Modi.Info.getModuleStreamIndex(), File);
-        if (!ModStreamData)
-          return ModStreamData.takeError();
-        ModStream ModS(Modi.Info, std::move(*ModStreamData));
+            File.getMsfLayout(), File.getMsfBuffer(),
+            Modi.Info.getModuleStreamIndex());
+
+        ModStream ModS(Modi.Info, std::move(ModStreamData));
         if (auto EC = ModS.reload())
           return EC;
 
@@ -519,7 +516,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
           public:
             RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
             Error visitUnknown(ModuleSubstreamKind Kind,
-                               StreamRef Stream) override {
+                               ReadableStreamRef Stream) override {
               DictScope DD(P, "Unknown");
               ArrayRef<uint8_t> Data;
               StreamReader R(Stream);
@@ -532,7 +529,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
               return Error::success();
             }
             Error
-            visitFileChecksums(StreamRef Data,
+            visitFileChecksums(ReadableStreamRef Data,
                                const FileChecksumArray &Checksums) override {
               DictScope DD(P, "FileChecksums");
               for (const auto &C : Checksums) {
@@ -548,7 +545,8 @@ Error LLVMOutputStyle::dumpDbiStream() {
               return Error::success();
             }
 
-            Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
+            Error visitLines(ReadableStreamRef Data,
+                             const LineSubstreamHeader *Header,
                              const LineInfoArray &Lines) override {
               DictScope DD(P, "Lines");
               for (const auto &L : Lines) {

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Thu Jul 28 14:12:28 2016
@@ -69,27 +69,6 @@ using namespace llvm::codeview;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
-namespace {
-// A simple adapter that acts like a ByteStream but holds ownership over
-// and underlying FileOutputBuffer.
-class FileBufferByteStream : public ByteStream<true> {
-public:
-  FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
-      : ByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
-                                            Buffer->getBufferEnd())),
-        FileBuffer(std::move(Buffer)) {}
-
-  Error commit() const override {
-    if (FileBuffer->commit())
-      return llvm::make_error<RawError>(raw_error_code::not_writable);
-    return Error::success();
-  }
-
-private:
-  std::unique_ptr<FileOutputBuffer> FileBuffer;
-};
-}
-
 namespace opts {
 
 cl::SubCommand RawSubcommand("raw", "Dump raw structure of the PDB file");
@@ -395,11 +374,7 @@ static void yamlToPdb(StringRef Path) {
     }
   }
 
-  auto Pdb = Builder.build(std::move(FileByteStream));
-  ExitOnErr(Pdb.takeError());
-
-  auto &PdbFile = *Pdb;
-  ExitOnErr(PdbFile->commit());
+  ExitOnErr(Builder.commit(*FileByteStream));
 }
 
 static void pdb2Yaml(StringRef Path) {

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Thu Jul 28 14:12:28 2016
@@ -954,7 +954,7 @@ void COFFDumper::printCodeViewSymbolsSub
                                                         SectionContents);
 
   CVSymbolDumper CVSD(W, CVTD, std::move(CODD), opts::CodeViewSubsectionBytes);
-  ByteStream<> Stream(BinaryData);
+  ByteStream Stream(BinaryData);
   CVSymbolArray Symbols;
   StreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
@@ -1062,7 +1062,7 @@ void COFFDumper::mergeCodeViewTypes(Memo
         error(object_error::parse_failed);
       ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
                               Data.size());
-      ByteStream<> Stream(Bytes);
+      ByteStream Stream(Bytes);
       CVTypeArray Types;
       StreamReader Reader(Stream);
       if (auto EC = Reader.readArray(Types, Reader.getLength())) {

Modified: llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp Thu Jul 28 14:12:28 2016
@@ -28,37 +28,43 @@ namespace {
 static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
 static uint8_t DataAry[] = {'A', 'B', 'C', 'F', 'E', 'D', 'G', 'H', 'I', 'J'};
 
-class DiscontiguousFile : public IMsfFile {
+class DiscontiguousStream : public WritableStream {
 public:
-  DiscontiguousFile(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
+  DiscontiguousStream(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
       : Blocks(Blocks.begin(), Blocks.end()), Data(Data.begin(), Data.end()) {}
 
-  uint32_t getBlockSize() const override { return 1; }
-  uint32_t getBlockCount() const override { return Blocks.size(); }
-  uint32_t getNumStreams() const override { return 1; }
-  uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
-    return getBlockCount() * getBlockSize();
-  }
-  ArrayRef<support::ulittle32_t>
-  getStreamBlockList(uint32_t StreamIndex) const override {
-    if (StreamIndex != 0)
-      return ArrayRef<support::ulittle32_t>();
-    return Blocks;
-  }
-  Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
-                                           uint32_t NumBytes) const override {
-    return ArrayRef<uint8_t>(&Data[BlockIndex], NumBytes);
+  uint32_t block_size() const { return 1; }
+  uint32_t block_count() const { return Blocks.size(); }
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) const override {
+    if (Offset + Size > Data.size())
+      return make_error<MsfError>(msf_error_code::insufficient_buffer);
+    Buffer = Data.slice(Offset, Size);
+    return Error::success();
   }
 
-  Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
-                     ArrayRef<uint8_t> SrcData) const override {
-    if (BlockIndex >= Blocks.size())
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) const override {
+    if (Offset >= Data.size())
       return make_error<MsfError>(msf_error_code::insufficient_buffer);
-    if (Offset > getBlockSize() - SrcData.size())
+    Buffer = Data.drop_front(Offset);
+    return Error::success();
+  }
+
+  uint32_t getLength() const override { return Data.size(); }
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) const override {
+    if (Offset + SrcData.size() > Data.size())
       return make_error<MsfError>(msf_error_code::insufficient_buffer);
-    ::memcpy(&Data[BlockIndex] + Offset, SrcData.data(), SrcData.size());
+    ::memcpy(&Data[Offset], SrcData.data(), SrcData.size());
     return Error::success();
   }
+  Error commit() const override { return Error::success(); }
+
+  MsfStreamLayout layout() const {
+    return MsfStreamLayout{Data.size(), Blocks};
+  }
 
 private:
   std::vector<support::ulittle32_t> Blocks;
@@ -68,13 +74,12 @@ private:
 // Tests that a read which is entirely contained within a single block works
 // and does not allocate.
 TEST(MappedBlockStreamTest, ReadBeyondEndOfStreamRef) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
 
   StreamReader R(*S);
-  StreamRef SR;
+  ReadableStreamRef SR;
   EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
   ArrayRef<uint8_t> Buffer;
   EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
@@ -85,10 +90,10 @@ TEST(MappedBlockStreamTest, ReadBeyondEn
 // Tests that a read which outputs into a full destination buffer works and
 // does not fail due to the length of the output buffer.
 TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
+
   StreamReader R(*S);
   StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
   EXPECT_NO_ERROR(R.readFixedString(Str, 1));
@@ -100,10 +105,9 @@ TEST(MappedBlockStreamTest, ReadOntoNonE
 // blocks are still contiguous in memory to the previous block works and does
 // not allocate memory.
 TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 2));
@@ -120,10 +124,9 @@ TEST(MappedBlockStreamTest, ZeroCopyRead
 // contiguously works and allocates only the precise amount of bytes
 // requested.
 TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 10));
@@ -134,10 +137,9 @@ TEST(MappedBlockStreamTest, CopyReadNonC
 // Test that an out of bounds read which doesn't cross a block boundary
 // fails and allocates no memory.
 TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
 
@@ -149,10 +151,9 @@ TEST(MappedBlockStreamTest, InvalidReadS
 // Test that an out of bounds read which crosses a contiguous block boundary
 // fails and allocates no memory.
 TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
 
@@ -164,10 +165,9 @@ TEST(MappedBlockStreamTest, InvalidReadS
 // Test that an out of bounds read which crosses a discontiguous block
 // boundary fails and allocates no memory.
 TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
 
@@ -178,10 +178,9 @@ TEST(MappedBlockStreamTest, InvalidReadS
 // Tests that a read which is entirely contained within a single block but
 // beyond the end of a StreamRef fails.
 TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 1));
@@ -193,10 +192,9 @@ TEST(MappedBlockStreamTest, ZeroCopyRead
 // cached request, but which is known to overlap that request, shares the
 // previous allocation.
 TEST(MappedBlockStreamTest, UnalignedOverlappingRead) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str1;
   StringRef Str2;
@@ -215,10 +213,9 @@ TEST(MappedBlockStreamTest, UnalignedOve
 // cached request, but which only partially overlaps a previous cached request,
 // still works correctly and allocates again from the shared pool.
 TEST(MappedBlockStreamTest, UnalignedOverlappingReadFail) {
-  DiscontiguousFile F(BlocksAry, DataAry);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, DataAry);
+  auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
+                                           F.layout(), F);
   StreamReader R(*S);
   StringRef Str1;
   StringRef Str2;
@@ -240,10 +237,9 @@ TEST(MappedBlockStreamTest, WriteBeyondE
   static_assert(sizeof(LargeBuffer) > sizeof(Data),
                 "LargeBuffer is not big enough");
 
-  DiscontiguousFile F(BlocksAry, Data);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, Data);
+  auto S = WritableMappedBlockStream::createStream(
+      F.block_size(), F.block_count(), F.layout(), F);
   ArrayRef<uint8_t> Buffer;
 
   EXPECT_ERROR(S->writeBytes(0, ArrayRef<uint8_t>(LargeBuffer)));
@@ -254,10 +250,9 @@ TEST(MappedBlockStreamTest, WriteBeyondE
 
 TEST(MappedBlockStreamTest, TestWriteBytesNoBreakBoundary) {
   static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
-  DiscontiguousFile F(BlocksAry, Data);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, Data);
+  auto S = WritableMappedBlockStream::createStream(
+      F.block_size(), F.block_count(), F.layout(), F);
   ArrayRef<uint8_t> Buffer;
 
   EXPECT_NO_ERROR(S->readBytes(0, 1, Buffer));
@@ -288,10 +283,9 @@ TEST(MappedBlockStreamTest, TestWriteByt
   static uint8_t Expected[] = {'T', 'E', 'S', 'N', 'I',
                                'T', 'G', '.', '0', '0'};
 
-  DiscontiguousFile F(BlocksAry, Data);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(BlocksAry, Data);
+  auto S = WritableMappedBlockStream::createStream(
+      F.block_size(), F.block_count(), F.layout(), F);
   ArrayRef<uint8_t> Buffer;
 
   EXPECT_NO_ERROR(S->writeBytes(0, TestData));
@@ -308,10 +302,9 @@ TEST(MappedBlockStreamTest, TestWriteThe
   MutableArrayRef<uint8_t> Data(DataBytes);
   const uint32_t Blocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
 
-  DiscontiguousFile F(Blocks, Data);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &S = *ExpectedS;
+  DiscontiguousStream F(Blocks, Data);
+  auto S = WritableMappedBlockStream::createStream(
+      F.block_size(), F.block_count(), F.layout(), F);
 
   enum class MyEnum : uint32_t { Val1 = 2908234, Val2 = 120891234 };
   using support::ulittle32_t;
@@ -401,13 +394,12 @@ TEST(MappedBlockStreamTest, TestWriteCon
   std::vector<uint8_t> SrcDataBytes(10);
   MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
 
-  DiscontiguousFile F(DestBlocks, DestData);
-  auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
-  EXPECT_EXPECTED(ExpectedS);
-  auto &DestStream = *ExpectedS;
+  DiscontiguousStream F(DestBlocks, DestData);
+  auto DestStream = WritableMappedBlockStream::createStream(
+      F.block_size(), F.block_count(), F.layout(), F);
 
   // First write "Test Str" into the source stream.
-  ByteStream<true> SourceStream(SrcData);
+  MutableByteStream SourceStream(SrcData);
   StreamWriter SourceWriter(SourceStream);
   EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
   EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
@@ -435,31 +427,29 @@ TEST(MappedBlockStreamTest, TestWriteDis
   MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
   const uint32_t SrcBlocks[] = {1, 0, 6, 3, 4, 5, 2, 7, 8, 9};
 
-  DiscontiguousFile DestFile(DestBlocks, DestData);
-  DiscontiguousFile SrcFile(SrcBlocks, SrcData);
+  DiscontiguousStream DestF(DestBlocks, DestData);
+  DiscontiguousStream SrcF(SrcBlocks, SrcData);
 
-  auto ExpectedDest = MappedBlockStream::createIndexedStream(0, DestFile);
-  auto ExpectedSrc = MappedBlockStream::createIndexedStream(0, SrcFile);
-  EXPECT_EXPECTED(ExpectedDest);
-  EXPECT_EXPECTED(ExpectedSrc);
-  auto &DestStream = *ExpectedDest;
-  auto &SrcStream = *ExpectedSrc;
+  auto Dest = WritableMappedBlockStream::createStream(
+      DestF.block_size(), DestF.block_count(), DestF.layout(), DestF);
+  auto Src = WritableMappedBlockStream::createStream(
+      SrcF.block_size(), SrcF.block_count(), SrcF.layout(), SrcF);
 
   // First write "Test Str" into the source stream.
-  StreamWriter SourceWriter(*SrcStream);
+  StreamWriter SourceWriter(*Src);
   EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
   EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
                               {'e', 'T', 't', 't', ' ', 'S', 's', 'r', 0, 0}));
 
   // Then write the source stream into the dest stream.
-  StreamWriter DestWriter(*DestStream);
-  EXPECT_NO_ERROR(DestWriter.writeStreamRef(*SrcStream));
+  StreamWriter DestWriter(*Dest);
+  EXPECT_NO_ERROR(DestWriter.writeStreamRef(*Src));
   EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
                                {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
 
   // Then read the string back out of the dest stream.
   StringRef Result;
-  StreamReader DestReader(*DestStream);
+  StreamReader DestReader(*Dest);
   EXPECT_NO_ERROR(DestReader.readZeroString(Result));
   EXPECT_EQ(Result, "Test Str");
 }

Modified: llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp?rev=277019&r1=277018&r2=277019&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp Thu Jul 28 14:12:28 2016
@@ -110,7 +110,7 @@ TEST_F(MsfBuilderTest, TestAddStreamNoDi
 
   auto ExpectedL1 = Msf.build();
   EXPECT_EXPECTED(ExpectedL1);
-  Layout &L1 = *ExpectedL1;
+  MsfLayout &L1 = *ExpectedL1;
 
   auto OldDirBlocks = L1.DirectoryBlocks;
   EXPECT_EQ(1U, OldDirBlocks.size());
@@ -127,7 +127,7 @@ TEST_F(MsfBuilderTest, TestAddStreamNoDi
 
   auto ExpectedL2 = Msf2.build();
   EXPECT_EXPECTED(ExpectedL2);
-  Layout &L2 = *ExpectedL2;
+  MsfLayout &L2 = *ExpectedL2;
   auto NewDirBlocks = L2.DirectoryBlocks;
   EXPECT_EQ(1U, NewDirBlocks.size());
 }
@@ -146,7 +146,7 @@ TEST_F(MsfBuilderTest, TestAddStreamWith
 
   auto ExpectedL1 = Msf.build();
   EXPECT_EXPECTED(ExpectedL1);
-  Layout &L1 = *ExpectedL1;
+  MsfLayout &L1 = *ExpectedL1;
   auto DirBlocks = L1.DirectoryBlocks;
   EXPECT_EQ(2U, DirBlocks.size());
 }
@@ -270,7 +270,7 @@ TEST_F(MsfBuilderTest, TestBlockCountsWh
 }
 
 TEST_F(MsfBuilderTest, BuildMsfLayout) {
-  // Test that we can generate an Msf Layout structure from a valid layout
+  // Test that we can generate an Msf MsfLayout structure from a valid layout
   // specification.
   auto ExpectedMsf = MsfBuilder::create(Allocator, 4096);
   EXPECT_EXPECTED(ExpectedMsf);
@@ -286,7 +286,7 @@ TEST_F(MsfBuilderTest, BuildMsfLayout) {
 
   auto ExpectedLayout = Msf.build();
   EXPECT_EXPECTED(ExpectedLayout);
-  Layout &L = *ExpectedLayout;
+  MsfLayout &L = *ExpectedLayout;
   EXPECT_EQ(4096U, L.SB->BlockSize);
   EXPECT_EQ(ExpectedNumBlocks, L.SB->NumBlocks);
 
@@ -313,7 +313,7 @@ TEST_F(MsfBuilderTest, UseDirectoryBlock
 
   auto ExpectedLayout = Msf.build();
   EXPECT_EXPECTED(ExpectedLayout);
-  Layout &L = *ExpectedLayout;
+  MsfLayout &L = *ExpectedLayout;
   EXPECT_EQ(msf::getMinimumBlockCount() + 2, L.SB->NumBlocks);
   EXPECT_EQ(1U, L.DirectoryBlocks.size());
   EXPECT_EQ(1U, L.StreamMap[0].size());
@@ -335,7 +335,7 @@ TEST_F(MsfBuilderTest, DirectoryBlockHin
 
   auto ExpectedLayout = Msf.build();
   EXPECT_EXPECTED(ExpectedLayout);
-  Layout &L = *ExpectedLayout;
+  MsfLayout &L = *ExpectedLayout;
   EXPECT_EQ(2U, L.DirectoryBlocks.size());
   EXPECT_EQ(B + 1, L.DirectoryBlocks[0]);
 }
@@ -353,7 +353,7 @@ TEST_F(MsfBuilderTest, DirectoryBlockHin
 
   auto ExpectedLayout = Msf.build();
   EXPECT_EXPECTED(ExpectedLayout);
-  Layout &L = *ExpectedLayout;
+  MsfLayout &L = *ExpectedLayout;
   EXPECT_EQ(1U, L.DirectoryBlocks.size());
   EXPECT_EQ(B + 1, L.DirectoryBlocks[0]);
 }




More information about the llvm-commits mailing list