<div dir="ltr">Strange, I compiled with clang-cl and it worked fine.  I will take a look</div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 28, 2016 at 12:32 PM Rafael Espíndola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Either this or the next patch broke windows builds:<br>
<br>
<a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/9076/steps/build/logs/stdio" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/9076/steps/build/logs/stdio</a><br>
<br>
'llvm::msf::StreamWriter::writeInteger': ambiguous call to overloaded function<br>
C:\Buildbot\Slave\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\include\llvm/DebugInfo/Msf/StreamWriter.h(32):<br>
note: could be 'llvm::Error<br>
llvm::msf::StreamWriter::writeInteger(uint32_t)'<br>
C:\Buildbot\Slave\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\include\llvm/DebugInfo/Msf/StreamWriter.h(31):<br>
note: or       'llvm::Error<br>
llvm::msf::StreamWriter::writeInteger(uint16_t)'<br>
<br>
Cheers,<br>
Rafael<br>
<br>
<br>
<br>
On 28 July 2016 at 15:12, Zachary Turner via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: zturner<br>
> Date: Thu Jul 28 14:12:28 2016<br>
> New Revision: 277019<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=277019&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=277019&view=rev</a><br>
> Log:<br>
> [pdb] Refactor library to more clearly separate reading/writing<br>
><br>
> Reviewed By: amccarth, ruiu<br>
> Differential Revision: <a href="https://reviews.llvm.org/D22693" rel="noreferrer" target="_blank">https://reviews.llvm.org/D22693</a><br>
><br>
> Removed:<br>
>     llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp<br>
> Modified:<br>
>     llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h<br>
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h<br>
>     llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h<br>
>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h<br>
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp<br>
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp<br>
>     llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp<br>
>     llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt<br>
>     llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp<br>
>     llvm/trunk/lib/DebugInfo/Msf/MsfBuilder.cpp<br>
>     llvm/trunk/lib/DebugInfo/Msf/StreamReader.cpp<br>
>     llvm/trunk/lib/DebugInfo/Msf/StreamWriter.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStream.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/NameMap.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/RawSession.cpp<br>
>     llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp<br>
>     llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp<br>
>     llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
>     llvm/trunk/tools/llvm-readobj/COFFDumper.cpp<br>
>     llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp<br>
>     llvm/trunk/unittests/DebugInfo/PDB/MsfBuilderTest.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Thu Jul 28 14:12:28 2016<br>
> @@ -32,7 +32,7 @@ namespace msf {<br>
><br>
>  template <typename Kind><br>
>  struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {<br>
> -  Error operator()(StreamRef Stream, uint32_t &Len,<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Len,<br>
>                     codeview::CVRecord<Kind> &Item) const {<br>
>      using namespace codeview;<br>
>      const RecordPrefix *Prefix = nullptr;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h Thu Jul 28 14:12:28 2016<br>
> @@ -59,15 +59,15 @@ struct ColumnNumberEntry {<br>
>  class ModuleSubstream {<br>
>  public:<br>
>    ModuleSubstream();<br>
> -  ModuleSubstream(ModuleSubstreamKind Kind, msf::StreamRef Data);<br>
> -  static Error initialize(msf::StreamRef Stream, ModuleSubstream &Info);<br>
> +  ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);<br>
> +  static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);<br>
>    uint32_t getRecordLength() const;<br>
>    ModuleSubstreamKind getSubstreamKind() const;<br>
> -  msf::StreamRef getRecordData() const;<br>
> +  msf::ReadableStreamRef getRecordData() const;<br>
><br>
>  private:<br>
>    ModuleSubstreamKind Kind;<br>
> -  msf::StreamRef Data;<br>
> +  msf::ReadableStreamRef Data;<br>
>  };<br>
><br>
>  typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray;<br>
> @@ -75,7 +75,7 @@ typedef msf::VarStreamArray<ModuleSubstr<br>
><br>
>  namespace msf {<br>
>  template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {<br>
> -  Error operator()(StreamRef Stream, uint32_t &Length,<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Length,<br>
>                     codeview::ModuleSubstream &Info) const {<br>
>      if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))<br>
>        return EC;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h Thu Jul 28 14:12:28 2016<br>
> @@ -38,23 +38,24 @@ class IModuleSubstreamVisitor {<br>
>  public:<br>
>    virtual ~IModuleSubstreamVisitor() {}<br>
><br>
> -  virtual Error visitUnknown(ModuleSubstreamKind Kind, msf::StreamRef Data) = 0;<br>
> -  virtual Error visitSymbols(msf::StreamRef Data);<br>
> -  virtual Error visitLines(msf::StreamRef Data,<br>
> +  virtual Error visitUnknown(ModuleSubstreamKind Kind,<br>
> +                             msf::ReadableStreamRef Data) = 0;<br>
> +  virtual Error visitSymbols(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitLines(msf::ReadableStreamRef Data,<br>
>                             const LineSubstreamHeader *Header,<br>
>                             const LineInfoArray &Lines);<br>
> -  virtual Error visitStringTable(msf::StreamRef Data);<br>
> -  virtual Error visitFileChecksums(msf::StreamRef Data,<br>
> +  virtual Error visitStringTable(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitFileChecksums(msf::ReadableStreamRef Data,<br>
>                                     const FileChecksumArray &Checksums);<br>
> -  virtual Error visitFrameData(msf::StreamRef Data);<br>
> -  virtual Error visitInlineeLines(msf::StreamRef Data);<br>
> -  virtual Error visitCrossScopeImports(msf::StreamRef Data);<br>
> -  virtual Error visitCrossScopeExports(msf::StreamRef Data);<br>
> -  virtual Error visitILLines(msf::StreamRef Data);<br>
> -  virtual Error visitFuncMDTokenMap(msf::StreamRef Data);<br>
> -  virtual Error visitTypeMDTokenMap(msf::StreamRef Data);<br>
> -  virtual Error visitMergedAssemblyInput(msf::StreamRef Data);<br>
> -  virtual Error visitCoffSymbolRVA(msf::StreamRef Data);<br>
> +  virtual Error visitFrameData(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitInlineeLines(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitCrossScopeImports(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitCrossScopeExports(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitILLines(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitFuncMDTokenMap(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitTypeMDTokenMap(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitMergedAssemblyInput(msf::ReadableStreamRef Data);<br>
> +  virtual Error visitCoffSymbolRVA(msf::ReadableStreamRef Data);<br>
>  };<br>
><br>
>  Error visitModuleSubstream(const ModuleSubstream &R,<br>
> @@ -67,7 +68,7 @@ public:<br>
>    VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header)<br>
>        : Header(Header) {}<br>
><br>
> -  Error operator()(StreamRef Stream, uint32_t &Len,<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Len,<br>
>                     codeview::LineColumnEntry &Item) const {<br>
>      using namespace codeview;<br>
>      const LineFileBlockHeader *BlockHeader;<br>
> @@ -104,7 +105,7 @@ private:<br>
><br>
>  template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {<br>
>  public:<br>
> -  Error operator()(StreamRef Stream, uint32_t &Len,<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Len,<br>
>                     codeview::FileChecksumEntry &Item) const {<br>
>      using namespace codeview;<br>
>      const FileChecksum *Header;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/ByteStream.h Thu Jul 28 14:12:28 2016<br>
> @@ -12,45 +12,147 @@<br>
><br>
>  #include "llvm/ADT/ArrayRef.h"<br>
>  #include "llvm/ADT/StringRef.h"<br>
> +#include "llvm/DebugInfo/Msf/MsfError.h"<br>
>  #include "llvm/DebugInfo/Msf/StreamInterface.h"<br>
>  #include "llvm/Support/Error.h"<br>
> +#include "llvm/Support/FileOutputBuffer.h"<br>
> +#include "llvm/Support/MemoryBuffer.h"<br>
>  #include <cstdint><br>
>  #include <memory><br>
>  #include <type_traits><br>
><br>
>  namespace llvm {<br>
>  namespace msf {<br>
> -class StreamReader;<br>
> -<br>
> -template <bool Writable = false> class ByteStream : public StreamInterface {<br>
> -  typedef typename std::conditional<Writable, MutableArrayRef<uint8_t>,<br>
> -                                    ArrayRef<uint8_t>>::type ArrayType;<br>
><br>
> +class ByteStream : public ReadableStream {<br>
>  public:<br>
>    ByteStream() {}<br>
> -  explicit ByteStream(ArrayType Data) : Data(Data) {}<br>
> -  ~ByteStream() override {}<br>
> +  explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}<br>
><br>
>    Error readBytes(uint32_t Offset, uint32_t Size,<br>
> -                  ArrayRef<uint8_t> &Buffer) const override;<br>
> +                  ArrayRef<uint8_t> &Buffer) const override {<br>
> +    if (Offset > Data.size())<br>
> +      return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> +    if (Data.size() < Size + Offset)<br>
> +      return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> +    Buffer = Data.slice(Offset, Size);<br>
> +    return Error::success();<br>
> +  }<br>
>    Error readLongestContiguousChunk(uint32_t Offset,<br>
> -                                   ArrayRef<uint8_t> &Buffer) const override;<br>
> +                                   ArrayRef<uint8_t> &Buffer) const override {<br>
> +    if (Offset >= Data.size())<br>
> +      return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> +    Buffer = Data.slice(Offset);<br>
> +    return Error::success();<br>
> +  }<br>
><br>
> -  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;<br>
> +  uint32_t getLength() const override { return Data.size(); }<br>
><br>
> -  uint32_t getLength() const override;<br>
> +  ArrayRef<uint8_t> data() const { return Data; }<br>
><br>
> -  Error commit() const override;<br>
> +  StringRef str() const {<br>
> +    const char *CharData = reinterpret_cast<const char *>(Data.data());<br>
> +    return StringRef(CharData, Data.size());<br>
> +  }<br>
><br>
> -  ArrayRef<uint8_t> data() const { return Data; }<br>
> -  StringRef str() const;<br>
> +protected:<br>
> +  ArrayRef<uint8_t> Data;<br>
> +};<br>
> +<br>
> +// MemoryBufferByteStream behaves like a read-only ByteStream, but has its data<br>
> +// backed by an llvm::MemoryBuffer.  It also owns the underlying MemoryBuffer.<br>
> +class MemoryBufferByteStream : public ByteStream {<br>
> +public:<br>
> +  explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)<br>
> +      : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),<br>
> +                                     Buffer->getBuffer().bytes_end())),<br>
> +        MemBuffer(std::move(Buffer)) {}<br>
> +<br>
> +  std::unique_ptr<MemoryBuffer> MemBuffer;<br>
> +};<br>
> +<br>
> +class MutableByteStream : public WritableStream {<br>
> +public:<br>
> +  MutableByteStream() {}<br>
> +  explicit MutableByteStream(MutableArrayRef<uint8_t> Data)<br>
> +      : Data(Data), ImmutableStream(Data) {}<br>
> +<br>
> +  Error readBytes(uint32_t Offset, uint32_t Size,<br>
> +                  ArrayRef<uint8_t> &Buffer) const override {<br>
> +    return ImmutableStream.readBytes(Offset, Size, Buffer);<br>
> +  }<br>
> +  Error readLongestContiguousChunk(uint32_t Offset,<br>
> +                                   ArrayRef<uint8_t> &Buffer) const override {<br>
> +    return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);<br>
> +  }<br>
> +<br>
> +  uint32_t getLength() const override { return ImmutableStream.getLength(); }<br>
> +<br>
> +  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {<br>
> +    if (Data.size() < Buffer.size())<br>
> +      return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> +    if (Offset > Buffer.size() - Data.size())<br>
> +      return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> +<br>
> +    uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());<br>
> +    ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());<br>
> +    return Error::success();<br>
> +  }<br>
> +<br>
> +  Error commit() const override { return Error::success(); }<br>
> +<br>
> +  MutableArrayRef<uint8_t> data() const { return Data; }<br>
> +<br>
> +private:<br>
> +  MutableArrayRef<uint8_t> Data;<br>
> +  ByteStream ImmutableStream;<br>
> +};<br>
> +<br>
> +// A simple adapter that acts like a ByteStream but holds ownership over<br>
> +// and underlying FileOutputBuffer.<br>
> +class FileBufferByteStream : public WritableStream {<br>
> +private:<br>
> +  class StreamImpl : public MutableByteStream {<br>
> +  public:<br>
> +    StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)<br>
> +        : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),<br>
> +                                                     Buffer->getBufferEnd())),<br>
> +          FileBuffer(std::move(Buffer)) {}<br>
> +<br>
> +    Error commit() const override {<br>
> +      if (FileBuffer->commit())<br>
> +        return llvm::make_error<MsfError>(msf_error_code::not_writable);<br>
> +      return Error::success();<br>
> +    }<br>
> +<br>
> +  private:<br>
> +    std::unique_ptr<FileOutputBuffer> FileBuffer;<br>
> +  };<br>
> +<br>
> +public:<br>
> +  explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)<br>
> +      : Impl(std::move(Buffer)) {}<br>
> +<br>
> +  Error readBytes(uint32_t Offset, uint32_t Size,<br>
> +                  ArrayRef<uint8_t> &Buffer) const override {<br>
> +    return Impl.readBytes(Offset, Size, Buffer);<br>
> +  }<br>
> +  Error readLongestContiguousChunk(uint32_t Offset,<br>
> +                                   ArrayRef<uint8_t> &Buffer) const override {<br>
> +    return Impl.readLongestContiguousChunk(Offset, Buffer);<br>
> +  }<br>
> +<br>
> +  uint32_t getLength() const override { return Impl.getLength(); }<br>
> +<br>
> +  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {<br>
> +    return Impl.writeBytes(Offset, Data);<br>
> +  }<br>
> +  Error commit() const override { return Impl.commit(); }<br>
><br>
>  private:<br>
> -  ArrayType Data;<br>
> +  StreamImpl Impl;<br>
>  };<br>
><br>
> -extern template class ByteStream<true>;<br>
> -extern template class ByteStream<false>;<br>
><br>
>  } // end namespace msf<br>
>  } // end namespace llvm<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/MappedBlockStream.h Thu Jul 28 14:12:28 2016<br>
> @@ -25,7 +25,7 @@<br>
>  namespace llvm {<br>
>  namespace msf {<br>
><br>
> -class IMsfFile;<br>
> +struct MsfLayout;<br>
><br>
>  /// MappedBlockStream represents data stored in an Msf file into chunks of a<br>
>  /// particular size (called the Block Size), and whose chunks may not be<br>
> @@ -37,42 +37,102 @@ class IMsfFile;<br>
>  /// the Msf.  MappedBlockStream provides methods for reading from and writing<br>
>  /// to one of these streams transparently, as if it were a contiguous sequence<br>
>  /// of bytes.<br>
> -class MappedBlockStream : public StreamInterface {<br>
> +class MappedBlockStream : public ReadableStream {<br>
> +  friend class WritableMappedBlockStream;<br>
> +<br>
>  public:<br>
> +  static std::unique_ptr<MappedBlockStream><br>
> +  createStream(uint32_t BlockSize, uint32_t NumBlocks,<br>
> +               const MsfStreamLayout &Layout, const ReadableStream &MsfData);<br>
> +<br>
> +  static std::unique_ptr<MappedBlockStream><br>
> +  createIndexedStream(const MsfLayout &Layout, const ReadableStream &MsfData,<br>
> +                      uint32_t StreamIndex);<br>
> +<br>
> +  static std::unique_ptr<MappedBlockStream><br>
> +  createDirectoryStream(const MsfLayout &Layout, const ReadableStream &MsfData);<br>
> +<br>
>    Error readBytes(uint32_t Offset, uint32_t Size,<br>
>                    ArrayRef<uint8_t> &Buffer) const override;<br>
>    Error readLongestContiguousChunk(uint32_t Offset,<br>
>                                     ArrayRef<uint8_t> &Buffer) const override;<br>
> -  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;<br>
><br>
>    uint32_t getLength() const override;<br>
> -  Error commit() const override;<br>
><br>
>    uint32_t getNumBytesCopied() const;<br>
><br>
> -  static Expected<std::unique_ptr<MappedBlockStream>><br>
> -  createIndexedStream(uint32_t StreamIdx, const IMsfFile &File);<br>
> -  static Expected<std::unique_ptr<MappedBlockStream>><br>
> -  createDirectoryStream(uint32_t Length, ArrayRef<support::ulittle32_t> Blocks,<br>
> -                        const IMsfFile &File);<br>
> -<br>
>    llvm::BumpPtrAllocator &getAllocator() { return Pool; }<br>
><br>
> +  void invalidateCache();<br>
> +<br>
> +  uint32_t getBlockSize() const { return BlockSize; }<br>
> +  uint32_t getNumBlocks() const { return NumBlocks; }<br>
> +  uint32_t getStreamLength() const { return StreamLayout.Length; }<br>
> +<br>
>  protected:<br>
> -  MappedBlockStream(const MsfStreamLayout &Layout, const IMsfFile &File);<br>
> +  MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,<br>
> +                    const MsfStreamLayout &StreamLayout,<br>
> +                    const ReadableStream &MsfData);<br>
> +<br>
> +private:<br>
> +  const MsfStreamLayout &getStreamLayout() const { return StreamLayout; }<br>
> +  void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;<br>
><br>
>    Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const;<br>
>    bool tryReadContiguously(uint32_t Offset, uint32_t Size,<br>
>                             ArrayRef<uint8_t> &Buffer) const;<br>
><br>
> -  const IMsfFile &Msf;<br>
> -  const MsfStreamLayout Layout;<br>
> +  const uint32_t BlockSize;<br>
> +  const uint32_t NumBlocks;<br>
> +  const MsfStreamLayout StreamLayout;<br>
> +  const ReadableStream &MsfData;<br>
><br>
>    typedef MutableArrayRef<uint8_t> CacheEntry;<br>
>    mutable llvm::BumpPtrAllocator Pool;<br>
>    mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;<br>
>  };<br>
><br>
> +class WritableMappedBlockStream : public WritableStream {<br>
> +public:<br>
> +  static std::unique_ptr<WritableMappedBlockStream><br>
> +  createStream(uint32_t BlockSize, uint32_t NumBlocks,<br>
> +               const MsfStreamLayout &Layout, const WritableStream &MsfData);<br>
> +<br>
> +  static std::unique_ptr<WritableMappedBlockStream><br>
> +  createIndexedStream(const MsfLayout &Layout, const WritableStream &MsfData,<br>
> +                      uint32_t StreamIndex);<br>
> +<br>
> +  static std::unique_ptr<WritableMappedBlockStream><br>
> +  createDirectoryStream(const MsfLayout &Layout, const WritableStream &MsfData);<br>
> +<br>
> +  Error readBytes(uint32_t Offset, uint32_t Size,<br>
> +                  ArrayRef<uint8_t> &Buffer) const override;<br>
> +  Error readLongestContiguousChunk(uint32_t Offset,<br>
> +                                   ArrayRef<uint8_t> &Buffer) const override;<br>
> +  uint32_t getLength() const override;<br>
> +<br>
> +  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;<br>
> +<br>
> +  Error commit() const override;<br>
> +<br>
> +  const MsfStreamLayout &getStreamLayout() const {<br>
> +    return ReadInterface.getStreamLayout();<br>
> +  }<br>
> +  uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }<br>
> +  uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }<br>
> +  uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }<br>
> +<br>
> +protected:<br>
> +  WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,<br>
> +                            const MsfStreamLayout &StreamLayout,<br>
> +                            const WritableStream &MsfData);<br>
> +<br>
> +private:<br>
> +  MappedBlockStream ReadInterface;<br>
> +<br>
> +  const WritableStream &WriteInterface;<br>
> +};<br>
> +<br>
>  } // end namespace pdb<br>
>  } // end namespace llvm<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/MsfBuilder.h Thu Jul 28 14:12:28 2016<br>
> @@ -111,7 +111,7 @@ public:<br>
><br>
>    /// Finalize the layout and build the headers and structures that describe the<br>
>    /// MSF layout and can be written directly to the MSF file.<br>
> -  Expected<Layout> build();<br>
> +  Expected<MsfLayout> build();<br>
><br>
>  private:<br>
>    MsfBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/MsfCommon.h Thu Jul 28 14:12:28 2016<br>
> @@ -48,8 +48,8 @@ struct SuperBlock {<br>
>    support::ulittle32_t BlockMapAddr;<br>
>  };<br>
><br>
> -struct Layout {<br>
> -  Layout() : SB(nullptr) {}<br>
> +struct MsfLayout {<br>
> +  MsfLayout() : SB(nullptr) {}<br>
>    const SuperBlock *SB;<br>
>    ArrayRef<support::ulittle32_t> DirectoryBlocks;<br>
>    ArrayRef<support::ulittle32_t> StreamSizes;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamArray.h Thu Jul 28 14:12:28 2016<br>
> @@ -34,7 +34,8 @@ namespace msf {<br>
>  template <typename T> struct VarStreamArrayExtractor {<br>
>    // Method intentionally deleted.  You must provide an explicit specialization<br>
>    // with the following method implemented.<br>
> -  Error operator()(StreamRef Stream, uint32_t &Len, T &Item) const = delete;<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Len,<br>
> +                   T &Item) const = delete;<br>
>  };<br>
><br>
>  /// VarStreamArray represents an array of variable length records backed by a<br>
> @@ -83,8 +84,9 @@ public:<br>
>    VarStreamArray() {}<br>
>    explicit VarStreamArray(const Extractor &E) : E(E) {}<br>
><br>
> -  explicit VarStreamArray(StreamRef Stream) : Stream(Stream) {}<br>
> -  VarStreamArray(StreamRef Stream, const Extractor &E) : Stream(Stream), E(E) {}<br>
> +  explicit VarStreamArray(ReadableStreamRef Stream) : Stream(Stream) {}<br>
> +  VarStreamArray(ReadableStreamRef Stream, const Extractor &E)<br>
> +      : Stream(Stream), E(E) {}<br>
><br>
>    VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)<br>
>        : Stream(Other.Stream), E(Other.E) {}<br>
> @@ -97,10 +99,10 @@ public:<br>
><br>
>    const Extractor &getExtractor() const { return E; }<br>
><br>
> -  StreamRef getUnderlyingStream() const { return Stream; }<br>
> +  ReadableStreamRef getUnderlyingStream() const { return Stream; }<br>
><br>
>  private:<br>
> -  StreamRef Stream;<br>
> +  ReadableStreamRef Stream;<br>
>    Extractor E;<br>
>  };<br>
><br>
> @@ -189,7 +191,7 @@ private:<br>
>    }<br>
><br>
>    ValueType ThisValue;<br>
> -  StreamRef IterRef;<br>
> +  ReadableStreamRef IterRef;<br>
>    const ArrayType *Array{nullptr};<br>
>    uint32_t ThisLen{0};<br>
>    bool HasError{false};<br>
> @@ -204,7 +206,7 @@ template <typename T> class FixedStreamA<br>
><br>
>  public:<br>
>    FixedStreamArray() : Stream() {}<br>
> -  FixedStreamArray(StreamRef Stream) : Stream(Stream) {<br>
> +  FixedStreamArray(ReadableStreamRef Stream) : Stream(Stream) {<br>
>      assert(Stream.getLength() % sizeof(T) == 0);<br>
>    }<br>
><br>
> @@ -230,10 +232,10 @@ public:<br>
>      return FixedStreamArrayIterator<T>(*this, size());<br>
>    }<br>
><br>
> -  StreamRef getUnderlyingStream() const { return Stream; }<br>
> +  ReadableStreamRef getUnderlyingStream() const { return Stream; }<br>
><br>
>  private:<br>
> -  StreamRef Stream;<br>
> +  ReadableStreamRef Stream;<br>
>  };<br>
><br>
>  template <typename T> class FixedStreamArrayIterator {<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamInterface.h Thu Jul 28 14:12:28 2016<br>
> @@ -17,16 +17,9 @@<br>
>  namespace llvm {<br>
>  namespace msf {<br>
><br>
> -/// StreamInterface abstracts the notion of a data stream.  This way, an<br>
> -/// implementation could implement trivial reading from a contiguous memory<br>
> -/// buffer or, as in the case of PDB files, reading from a set of possibly<br>
> -/// discontiguous blocks.  The implementation is required to return references<br>
> -/// to stable memory, so if this is not possible (for example in the case of<br>
> -/// a PDB file with discontiguous blocks, it must keep its own pool of temp<br>
> -/// storage.<br>
> -class StreamInterface {<br>
> +class ReadableStream {<br>
>  public:<br>
> -  virtual ~StreamInterface() {}<br>
> +  virtual ~ReadableStream() {}<br>
><br>
>    // Given an offset into the stream and a number of bytes, attempt to read<br>
>    // the bytes and set the output ArrayRef to point to a reference into the<br>
> @@ -39,13 +32,18 @@ public:<br>
>    virtual Error readLongestContiguousChunk(uint32_t Offset,<br>
>                                             ArrayRef<uint8_t> &Buffer) const = 0;<br>
><br>
> +  virtual uint32_t getLength() const = 0;<br>
> +};<br>
> +<br>
> +class WritableStream : public ReadableStream {<br>
> +public:<br>
> +  virtual ~WritableStream() {}<br>
> +<br>
>    // Attempt to write the given bytes into the stream at the desired offset.<br>
>    // This will always necessitate a copy.  Cannot shrink or grow the stream,<br>
>    // only writes into existing allocated space.<br>
>    virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;<br>
><br>
> -  virtual uint32_t getLength() const = 0;<br>
> -<br>
>    virtual Error commit() const = 0;<br>
>  };<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamReader.h Thu Jul 28 14:12:28 2016<br>
> @@ -14,6 +14,7 @@<br>
>  #include "llvm/DebugInfo/Msf/MsfError.h"<br>
>  #include "llvm/DebugInfo/Msf/StreamArray.h"<br>
>  #include "llvm/DebugInfo/Msf/StreamInterface.h"<br>
> +#include "llvm/DebugInfo/Msf/StreamRef.h"<br>
>  #include "llvm/Support/Endian.h"<br>
>  #include "llvm/Support/Error.h"<br>
><br>
> @@ -22,11 +23,9 @@<br>
>  namespace llvm {<br>
>  namespace msf {<br>
><br>
> -class StreamRef;<br>
> -<br>
>  class StreamReader {<br>
>  public:<br>
> -  StreamReader(StreamRef Stream);<br>
> +  StreamReader(ReadableStreamRef Stream);<br>
><br>
>    Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);<br>
>    Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);<br>
> @@ -34,8 +33,8 @@ public:<br>
>    Error readInteger(uint32_t &Dest);<br>
>    Error readZeroString(StringRef &Dest);<br>
>    Error readFixedString(StringRef &Dest, uint32_t Length);<br>
> -  Error readStreamRef(StreamRef &Ref);<br>
> -  Error readStreamRef(StreamRef &Ref, uint32_t Length);<br>
> +  Error readStreamRef(ReadableStreamRef &Ref);<br>
> +  Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length);<br>
><br>
>    template <typename T> Error readEnum(T &Dest) {<br>
>      typename std::underlying_type<T>::type N;<br>
> @@ -72,7 +71,7 @@ public:<br>
><br>
>    template <typename T, typename U><br>
>    Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {<br>
> -    StreamRef S;<br>
> +    ReadableStreamRef S;<br>
>      if (auto EC = readStreamRef(S, Size))<br>
>        return EC;<br>
>      Array = VarStreamArray<T, U>(S, Array.getExtractor());<br>
> @@ -90,7 +89,7 @@ public:<br>
>        return make_error<MsfError>(msf_error_code::invalid_format);<br>
>      if (Offset + Length > Stream.getLength())<br>
>        return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -    StreamRef View = Stream.slice(Offset, Length);<br>
> +    ReadableStreamRef View = Stream.slice(Offset, Length);<br>
>      Array = FixedStreamArray<T>(View);<br>
>      Offset += Length;<br>
>      return Error::success();<br>
> @@ -102,7 +101,7 @@ public:<br>
>    uint32_t bytesRemaining() const { return getLength() - getOffset(); }<br>
><br>
>  private:<br>
> -  StreamRef Stream;<br>
> +  ReadableStreamRef Stream;<br>
>    uint32_t Offset;<br>
>  };<br>
>  } // namespace msf<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamRef.h Thu Jul 28 14:12:28 2016<br>
> @@ -15,17 +15,63 @@<br>
><br>
>  namespace llvm {<br>
>  namespace msf {<br>
> -<br>
> -class StreamRef {<br>
> +template <class StreamType, class RefType> class StreamRefBase {<br>
>  public:<br>
> -  StreamRef() : Stream(nullptr), ViewOffset(0), Length(0) {}<br>
> -  StreamRef(const StreamInterface &Stream)<br>
> -      : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {}<br>
> -  StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)<br>
> +  StreamRefBase() : Stream(nullptr), Length(0), ViewOffset(0) {}<br>
> +  StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)<br>
>        : Stream(&Stream), ViewOffset(Offset), Length(Length) {}<br>
><br>
> +  uint32_t getLength() const { return Length; }<br>
> +  const StreamType *getStream() const { return Stream; }<br>
> +<br>
> +  RefType drop_front(uint32_t N) const {<br>
> +    if (!Stream)<br>
> +      return RefType();<br>
> +<br>
> +    N = std::min(N, Length);<br>
> +    return RefType(*Stream, ViewOffset + N, Length - N);<br>
> +  }<br>
> +<br>
> +  RefType keep_front(uint32_t N) const {<br>
> +    if (!Stream)<br>
> +      return RefType();<br>
> +    N = std::min(N, Length);<br>
> +    return RefType(*Stream, ViewOffset, N);<br>
> +  }<br>
> +<br>
> +  RefType slice(uint32_t Offset, uint32_t Len) const {<br>
> +    return drop_front(Offset).keep_front(Len);<br>
> +  }<br>
> +<br>
> +  bool operator==(const RefType &Other) const {<br>
> +    if (Stream != Other.Stream)<br>
> +      return false;<br>
> +    if (ViewOffset != Other.ViewOffset)<br>
> +      return false;<br>
> +    if (Length != Other.Length)<br>
> +      return false;<br>
> +    return true;<br>
> +  }<br>
> +<br>
> +protected:<br>
> +  const StreamType *Stream;<br>
> +  uint32_t ViewOffset;<br>
> +  uint32_t Length;<br>
> +};<br>
> +<br>
> +class ReadableStreamRef<br>
> +    : public StreamRefBase<ReadableStream, ReadableStreamRef> {<br>
> +public:<br>
> +  ReadableStreamRef() : StreamRefBase() {}<br>
> +  ReadableStreamRef(const ReadableStream &Stream)<br>
> +      : StreamRefBase(Stream, 0, Stream.getLength()) {}<br>
> +  ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset,<br>
> +                    uint32_t Length)<br>
> +      : StreamRefBase(Stream, Offset, Length) {}<br>
> +<br>
>    // Use StreamRef.slice() instead.<br>
> -  StreamRef(const StreamRef &S, uint32_t Offset, uint32_t Length) = delete;<br>
> +  ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,<br>
> +                    uint32_t Length) = delete;<br>
><br>
>    Error readBytes(uint32_t Offset, uint32_t Size,<br>
>                    ArrayRef<uint8_t> &Buffer) const {<br>
> @@ -53,6 +99,21 @@ public:<br>
>        Buffer = Buffer.slice(0, MaxLength);<br>
>      return Error::success();<br>
>    }<br>
> +};<br>
> +<br>
> +class WritableStreamRef<br>
> +    : public StreamRefBase<WritableStream, WritableStreamRef> {<br>
> +public:<br>
> +  WritableStreamRef() : StreamRefBase() {}<br>
> +  WritableStreamRef(const WritableStream &Stream)<br>
> +      : StreamRefBase(Stream, 0, Stream.getLength()) {}<br>
> +  WritableStreamRef(const WritableStream &Stream, uint32_t Offset,<br>
> +                    uint32_t Length)<br>
> +      : StreamRefBase(Stream, Offset, Length) {}<br>
> +<br>
> +  // Use StreamRef.slice() instead.<br>
> +  WritableStreamRef(const WritableStreamRef &S, uint32_t Offset,<br>
> +                    uint32_t Length) = delete;<br>
><br>
>    Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {<br>
>      if (Data.size() + Offset > Length)<br>
> @@ -60,44 +121,9 @@ public:<br>
>      return Stream->writeBytes(ViewOffset + Offset, Data);<br>
>    }<br>
><br>
> -  uint32_t getLength() const { return Length; }<br>
> -<br>
>    Error commit() const { return Stream->commit(); }<br>
> -<br>
> -  StreamRef drop_front(uint32_t N) const {<br>
> -    if (!Stream)<br>
> -      return StreamRef();<br>
> -<br>
> -    N = std::min(N, Length);<br>
> -    return StreamRef(*Stream, ViewOffset + N, Length - N);<br>
> -  }<br>
> -<br>
> -  StreamRef keep_front(uint32_t N) const {<br>
> -    if (!Stream)<br>
> -      return StreamRef();<br>
> -    N = std::min(N, Length);<br>
> -    return StreamRef(*Stream, ViewOffset, N);<br>
> -  }<br>
> -<br>
> -  StreamRef slice(uint32_t Offset, uint32_t Len) const {<br>
> -    return drop_front(Offset).keep_front(Len);<br>
> -  }<br>
> -<br>
> -  bool operator==(const StreamRef &Other) const {<br>
> -    if (Stream != Other.Stream)<br>
> -      return false;<br>
> -    if (ViewOffset != Other.ViewOffset)<br>
> -      return false;<br>
> -    if (Length != Other.Length)<br>
> -      return false;<br>
> -    return true;<br>
> -  }<br>
> -<br>
> -private:<br>
> -  const StreamInterface *Stream;<br>
> -  uint32_t ViewOffset;<br>
> -  uint32_t Length;<br>
>  };<br>
> +<br>
>  } // namespace msf<br>
>  } // namespace llvm<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/Msf/StreamWriter.h Thu Jul 28 14:12:28 2016<br>
> @@ -14,6 +14,7 @@<br>
>  #include "llvm/DebugInfo/Msf/MsfError.h"<br>
>  #include "llvm/DebugInfo/Msf/StreamArray.h"<br>
>  #include "llvm/DebugInfo/Msf/StreamInterface.h"<br>
> +#include "llvm/DebugInfo/Msf/StreamRef.h"<br>
>  #include "llvm/Support/Endian.h"<br>
>  #include "llvm/Support/Error.h"<br>
><br>
> @@ -22,19 +23,17 @@<br>
>  namespace llvm {<br>
>  namespace msf {<br>
><br>
> -class StreamRef;<br>
> -<br>
>  class StreamWriter {<br>
>  public:<br>
> -  StreamWriter(StreamRef Stream);<br>
> +  StreamWriter(WritableStreamRef Stream);<br>
><br>
>    Error writeBytes(ArrayRef<uint8_t> Buffer);<br>
>    Error writeInteger(uint16_t Dest);<br>
>    Error writeInteger(uint32_t Dest);<br>
>    Error writeZeroString(StringRef Str);<br>
>    Error writeFixedString(StringRef Str);<br>
> -  Error writeStreamRef(StreamRef Ref);<br>
> -  Error writeStreamRef(StreamRef Ref, uint32_t Size);<br>
> +  Error writeStreamRef(ReadableStreamRef Ref);<br>
> +  Error writeStreamRef(ReadableStreamRef Ref, uint32_t Size);<br>
><br>
>    template <typename T> Error writeEnum(T Num) {<br>
>      return writeInteger(<br>
> @@ -77,7 +76,7 @@ public:<br>
>    uint32_t bytesRemaining() const { return getLength() - getOffset(); }<br>
><br>
>  private:<br>
> -  StreamRef Stream;<br>
> +  WritableStreamRef Stream;<br>
>    uint32_t Offset;<br>
>  };<br>
>  } // namespace msf<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Thu Jul 28 14:12:28 2016<br>
> @@ -12,9 +12,10 @@<br>
><br>
>  #include "llvm/Config/llvm-config.h"<br>
>  #include "llvm/DebugInfo/CodeView/CodeView.h"<br>
> -#include <functional><br>
> +#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"<br>
>  #include <cstdint><br>
>  #include <cstring><br>
> +#include <functional><br>
><br>
>  namespace llvm {<br>
>  namespace pdb {<br>
> @@ -73,13 +74,6 @@ enum class PDB_ReaderType {<br>
>    Raw = 1,<br>
>  };<br>
><br>
> -/// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but<br>
> -/// is abstracted here for the purposes of non-Windows platforms that don't have<br>
> -/// the GUID structure defined.<br>
> -struct PDB_UniqueId {<br>
> -  char Guid[16];<br>
> -};<br>
> -<br>
>  /// An enumeration indicating the type of data contained in this table.<br>
>  enum class PDB_TableType {<br>
>    Symbols,<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Thu Jul 28 14:12:28 2016<br>
> @@ -77,8 +77,6 @@ public:<br>
>    msf::FixedStreamArray<SecMapEntry> getSectionMap() const;<br>
>    void visitSectionContributions(ISectionContribVisitor &Visitor) const;<br>
><br>
> -  Error commit();<br>
> -<br>
>  private:<br>
>    Error initializeModInfoArray();<br>
>    Error initializeSectionContributionData();<br>
> @@ -93,14 +91,14 @@ private:<br>
>    std::vector<ModuleInfoEx> ModuleInfos;<br>
>    NameHashTable ECNames;<br>
><br>
> -  msf::StreamRef ModInfoSubstream;<br>
> -  msf::StreamRef SecContrSubstream;<br>
> -  msf::StreamRef SecMapSubstream;<br>
> -  msf::StreamRef FileInfoSubstream;<br>
> -  msf::StreamRef TypeServerMapSubstream;<br>
> -  msf::StreamRef ECSubstream;<br>
> +  msf::ReadableStreamRef ModInfoSubstream;<br>
> +  msf::ReadableStreamRef SecContrSubstream;<br>
> +  msf::ReadableStreamRef SecMapSubstream;<br>
> +  msf::ReadableStreamRef FileInfoSubstream;<br>
> +  msf::ReadableStreamRef TypeServerMapSubstream;<br>
> +  msf::ReadableStreamRef ECSubstream;<br>
><br>
> -  msf::StreamRef NamesBuffer;<br>
> +  msf::ReadableStreamRef NamesBuffer;<br>
><br>
>    msf::FixedStreamArray<support::ulittle16_t> DbgStreams;<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h Thu Jul 28 14:12:28 2016<br>
> @@ -23,6 +23,7 @@<br>
>  namespace llvm {<br>
>  namespace pdb {<br>
>  class DbiStream;<br>
> +struct DbiStreamHeader;<br>
>  class PDBFile;<br>
><br>
>  class DbiStreamBuilder {<br>
> @@ -45,9 +46,13 @@ public:<br>
>    Error addModuleInfo(StringRef ObjFile, StringRef Module);<br>
>    Error addModuleSourceFile(StringRef Module, StringRef File);<br>
><br>
> -  Expected<std::unique_ptr<DbiStream>> build(PDBFile &File);<br>
> +  Expected<std::unique_ptr<DbiStream>> build(PDBFile &File,<br>
> +                                             const msf::WritableStream &Buffer);<br>
> +  Error commit(const msf::MsfLayout &Layout,<br>
> +               const msf::WritableStream &Buffer) const;<br>
><br>
>  private:<br>
> +  Error finalize();<br>
>    uint32_t calculateModiSubstreamSize() const;<br>
>    uint32_t calculateFileInfoSubstreamSize() const;<br>
>    uint32_t calculateNamesBufferSize() const;<br>
> @@ -71,14 +76,16 @@ private:<br>
>    uint16_t Flags;<br>
>    PDB_Machine MachineType;<br>
><br>
> +  const DbiStreamHeader *Header;<br>
> +<br>
>    StringMap<std::unique_ptr<ModuleInfo>> ModuleInfos;<br>
>    std::vector<ModuleInfo *> ModuleInfoList;<br>
><br>
>    StringMap<uint32_t> SourceFileNames;<br>
><br>
> -  msf::StreamRef NamesBuffer;<br>
> -  msf::ByteStream<true> ModInfoBuffer;<br>
> -  msf::ByteStream<true> FileInfoBuffer;<br>
> +  msf::WritableStreamRef NamesBuffer;<br>
> +  msf::MutableByteStream ModInfoBuffer;<br>
> +  msf::MutableByteStream FileInfoBuffer;<br>
>  };<br>
>  }<br>
>  }<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStream.h Thu Jul 28 14:12:28 2016<br>
> @@ -27,18 +27,10 @@ class PDBFile;<br>
>  class InfoStream {<br>
>    friend class InfoStreamBuilder;<br>
><br>
> -  struct HeaderInfo {<br>
> -    support::ulittle32_t Version;<br>
> -    support::ulittle32_t Signature;<br>
> -    support::ulittle32_t Age;<br>
> -    PDB_UniqueId Guid;<br>
> -  };<br>
> -<br>
>  public:<br>
>    InfoStream(std::unique_ptr<msf::MappedBlockStream> Stream);<br>
><br>
>    Error reload();<br>
> -  Error commit();<br>
><br>
>    PdbRaw_ImplVer getVersion() const;<br>
>    uint32_t getSignature() const;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h Thu Jul 28 14:12:28 2016<br>
> @@ -19,6 +19,9 @@<br>
>  #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"<br>
><br>
>  namespace llvm {<br>
> +namespace msf {<br>
> +class StreamWriter;<br>
> +}<br>
>  namespace pdb {<br>
>  class PDBFile;<br>
><br>
> @@ -37,13 +40,17 @@ public:<br>
><br>
>    uint32_t calculateSerializedLength() const;<br>
><br>
> -  Expected<std::unique_ptr<InfoStream>> build(PDBFile &File);<br>
> +  Expected<std::unique_ptr<InfoStream>><br>
> +  build(PDBFile &File, const msf::WritableStream &Buffer);<br>
> +<br>
> +  Error commit(const msf::MsfLayout &Layout,<br>
> +               const msf::WritableStream &Buffer) const;<br>
><br>
>  private:<br>
> -  Optional<PdbRaw_ImplVer> Ver;<br>
> -  Optional<uint32_t> Sig;<br>
> -  Optional<uint32_t> Age;<br>
> -  Optional<PDB_UniqueId> Guid;<br>
> +  PdbRaw_ImplVer Ver;<br>
> +  uint32_t Sig;<br>
> +  uint32_t Age;<br>
> +  PDB_UniqueId Guid;<br>
><br>
>    NameMapBuilder NamedStreams;<br>
>  };<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h Thu Jul 28 14:12:28 2016<br>
> @@ -29,7 +29,7 @@ public:<br>
>    ModInfo(const ModInfo &Info);<br>
>    ~ModInfo();<br>
><br>
> -  static Error initialize(msf::StreamRef Stream, ModInfo &Info);<br>
> +  static Error initialize(msf::ReadableStreamRef Stream, ModInfo &Info);<br>
><br>
>    bool hasECInfo() const;<br>
>    uint16_t getTypeServerIndex() const;<br>
> @@ -65,7 +65,7 @@ struct ModuleInfoEx {<br>
><br>
>  namespace msf {<br>
>  template <> struct VarStreamArrayExtractor<pdb::ModInfo> {<br>
> -  Error operator()(StreamRef Stream, uint32_t &Length,<br>
> +  Error operator()(ReadableStreamRef Stream, uint32_t &Length,<br>
>                     pdb::ModInfo &Info) const {<br>
>      if (auto EC = pdb::ModInfo::initialize(Stream, Info))<br>
>        return EC;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h Thu Jul 28 14:12:28 2016<br>
> @@ -46,9 +46,9 @@ private:<br>
>    std::unique_ptr<msf::MappedBlockStream> Stream;<br>
><br>
>    codeview::CVSymbolArray SymbolsSubstream;<br>
> -  msf::StreamRef LinesSubstream;<br>
> -  msf::StreamRef C13LinesSubstream;<br>
> -  msf::StreamRef GlobalRefsSubstream;<br>
> +  msf::ReadableStreamRef LinesSubstream;<br>
> +  msf::ReadableStreamRef C13LinesSubstream;<br>
> +  msf::ReadableStreamRef GlobalRefsSubstream;<br>
><br>
>    codeview::ModuleSubstreamArray LineInfo;<br>
>  };<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h Thu Jul 28 14:12:28 2016<br>
> @@ -41,7 +41,7 @@ public:<br>
>    msf::FixedStreamArray<support::ulittle32_t> name_ids() const;<br>
><br>
>  private:<br>
> -  msf::StreamRef NamesBuffer;<br>
> +  msf::ReadableStreamRef NamesBuffer;<br>
>    msf::FixedStreamArray<support::ulittle32_t> IDs;<br>
>    uint32_t Signature;<br>
>    uint32_t HashVersion;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMap.h Thu Jul 28 14:12:28 2016<br>
> @@ -29,7 +29,6 @@ public:<br>
>    NameMap();<br>
><br>
>    Error load(msf::StreamReader &Stream);<br>
> -  Error commit(msf::StreamWriter &Writer);<br>
><br>
>    bool tryGetValue(StringRef Name, uint32_t &Value) const;<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h Thu Jul 28 14:12:28 2016<br>
> @@ -17,6 +17,9 @@<br>
>  #include <memory><br>
><br>
>  namespace llvm {<br>
> +namespace msf {<br>
> +class StreamWriter;<br>
> +}<br>
>  namespace pdb {<br>
>  class NameMap;<br>
><br>
> @@ -27,6 +30,7 @@ public:<br>
>    void addMapping(StringRef Name, uint32_t Mapping);<br>
><br>
>    Expected<std::unique_ptr<NameMap>> build();<br>
> +  Error commit(msf::StreamWriter &Writer) const;<br>
><br>
>    uint32_t calculateSerializedLength() const;<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Thu Jul 28 14:12:28 2016<br>
> @@ -26,7 +26,7 @@ namespace llvm {<br>
><br>
>  namespace msf {<br>
>  class MappedBlockStream;<br>
> -class StreamInterface;<br>
> +class WritableStream;<br>
>  }<br>
><br>
>  namespace pdb {<br>
> @@ -42,7 +42,7 @@ class PDBFile : public msf::IMsfFile {<br>
>    friend PDBFileBuilder;<br>
><br>
>  public:<br>
> -  PDBFile(std::unique_ptr<msf::StreamInterface> PdbFileBuffer,<br>
> +  PDBFile(std::unique_ptr<msf::ReadableStream> PdbFileBuffer,<br>
>            BumpPtrAllocator &Allocator);<br>
>    ~PDBFile() override;<br>
><br>
> @@ -68,12 +68,15 @@ public:<br>
>                       ArrayRef<uint8_t> Data) const override;<br>
><br>
>    ArrayRef<support::ulittle32_t> getStreamSizes() const {<br>
> -    return MsfLayout.StreamSizes;<br>
> +    return ContainerLayout.StreamSizes;<br>
>    }<br>
>    ArrayRef<ArrayRef<support::ulittle32_t>> getStreamMap() const {<br>
> -    return MsfLayout.StreamMap;<br>
> +    return ContainerLayout.StreamMap;<br>
>    }<br>
><br>
> +  const msf::MsfLayout &getMsfLayout() const { return ContainerLayout; }<br>
> +  const msf::ReadableStream &getMsfBuffer() const { return *Buffer; }<br>
> +<br>
>    ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;<br>
><br>
>    Error parseFileHeaders();<br>
> @@ -87,14 +90,12 @@ public:<br>
>    Expected<SymbolStream &> getPDBSymbolStream();<br>
>    Expected<NameHashTable &> getStringTable();<br>
><br>
> -  Error commit();<br>
> -<br>
>  private:<br>
>    BumpPtrAllocator &Allocator;<br>
><br>
> -  std::unique_ptr<msf::StreamInterface> Buffer;<br>
> +  std::unique_ptr<msf::ReadableStream> Buffer;<br>
><br>
> -  msf::Layout MsfLayout;<br>
> +  msf::MsfLayout ContainerLayout;<br>
><br>
>    std::unique_ptr<InfoStream> Info;<br>
>    std::unique_ptr<DbiStream> Dbi;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h Thu Jul 28 14:12:28 2016<br>
> @@ -24,7 +24,6 @@<br>
>  namespace llvm {<br>
>  namespace msf {<br>
>  class MsfBuilder;<br>
> -class StreamInterface;<br>
>  }<br>
>  namespace pdb {<br>
>  class DbiStreamBuilder;<br>
> @@ -43,10 +42,12 @@ public:<br>
>    DbiStreamBuilder &getDbiBuilder();<br>
><br>
>    Expected<std::unique_ptr<PDBFile>><br>
> -  build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer);<br>
> +  build(std::unique_ptr<msf::WritableStream> PdbFileBuffer);<br>
> +<br>
> +  Error commit(const msf::WritableStream &Buffer);<br>
><br>
>  private:<br>
> -  Expected<msf::Layout> finalizeMsfLayout() const;<br>
> +  Expected<msf::MsfLayout> finalizeMsfLayout() const;<br>
><br>
>    BumpPtrAllocator &Allocator;<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawTypes.h Thu Jul 28 14:12:28 2016<br>
> @@ -259,6 +259,21 @@ struct ModuleInfoHeader {<br>
>    /// char ObjFileName[];<br>
>  };<br>
><br>
> +/// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but<br>
> +/// is abstracted here for the purposes of non-Windows platforms that don't have<br>
> +/// the GUID structure defined.<br>
> +struct PDB_UniqueId {<br>
> +  char Guid[16];<br>
> +};<br>
> +<br>
> +/// The header preceeding the global PDB Stream (Stream 1)<br>
> +struct InfoStreamHeader {<br>
> +  support::ulittle32_t Version;<br>
> +  support::ulittle32_t Signature;<br>
> +  support::ulittle32_t Age;<br>
> +  PDB_UniqueId Guid;<br>
> +};<br>
> +<br>
>  } // namespace pdb<br>
>  } // namespace llvm<br>
><br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Thu Jul 28 14:12:28 2016<br>
> @@ -475,7 +475,7 @@ void CodeViewDebug::emitTypeInformation(<br>
>            // comments. The MSVC linker doesn't do much type record validation,<br>
>            // so the first link of an invalid type record can succeed while<br>
>            // subsequent links will fail with LNK1285.<br>
> -          ByteStream<> Stream({Record.bytes_begin(), Record.bytes_end()});<br>
> +          ByteStream Stream({Record.bytes_begin(), Record.bytes_end()});<br>
>            CVTypeArray Types;<br>
>            StreamReader Reader(Stream);<br>
>            Error E = Reader.readArray(Types, Reader.getLength());<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp Thu Jul 28 14:12:28 2016<br>
> @@ -17,10 +17,12 @@ using namespace llvm::msf;<br>
><br>
>  ModuleSubstream::ModuleSubstream() : Kind(ModuleSubstreamKind::None) {}<br>
><br>
> -ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind, StreamRef Data)<br>
> +ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind,<br>
> +                                 ReadableStreamRef Data)<br>
>      : Kind(Kind), Data(Data) {}<br>
><br>
> -Error ModuleSubstream::initialize(StreamRef Stream, ModuleSubstream &Info) {<br>
> +Error ModuleSubstream::initialize(ReadableStreamRef Stream,<br>
> +                                  ModuleSubstream &Info) {<br>
>    const ModuleSubsectionHeader *Header;<br>
>    StreamReader Reader(Stream);<br>
>    if (auto EC = Reader.readObject(Header))<br>
> @@ -40,4 +42,4 @@ uint32_t ModuleSubstream::getRecordLengt<br>
><br>
>  ModuleSubstreamKind ModuleSubstream::getSubstreamKind() const { return Kind; }<br>
><br>
> -StreamRef ModuleSubstream::getRecordData() const { return Data; }<br>
> +ReadableStreamRef ModuleSubstream::getRecordData() const { return Data; }<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp Thu Jul 28 14:12:28 2016<br>
> @@ -15,46 +15,47 @@ using namespace llvm;<br>
>  using namespace llvm::codeview;<br>
>  using namespace llvm::msf;<br>
><br>
> -Error IModuleSubstreamVisitor::visitSymbols(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitSymbols(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::Symbols, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitLines(StreamRef Data,<br>
> +Error IModuleSubstreamVisitor::visitLines(ReadableStreamRef Data,<br>
>                                            const LineSubstreamHeader *Header,<br>
>                                            const LineInfoArray &Lines) {<br>
>    return visitUnknown(ModuleSubstreamKind::Lines, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitStringTable(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitStringTable(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::StringTable, Data);<br>
>  }<br>
>  Error IModuleSubstreamVisitor::visitFileChecksums(<br>
> -    StreamRef Data, const FileChecksumArray &Checksums) {<br>
> +    ReadableStreamRef Data, const FileChecksumArray &Checksums) {<br>
>    return visitUnknown(ModuleSubstreamKind::FileChecksums, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitFrameData(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitFrameData(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::FrameData, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitInlineeLines(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitInlineeLines(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::InlineeLines, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitCrossScopeImports(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitCrossScopeImports(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::CrossScopeExports, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitCrossScopeExports(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitCrossScopeExports(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::CrossScopeImports, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitILLines(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitILLines(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::ILLines, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitFuncMDTokenMap(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitFuncMDTokenMap(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::FuncMDTokenMap, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitTypeMDTokenMap(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitTypeMDTokenMap(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::TypeMDTokenMap, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitMergedAssemblyInput(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitMergedAssemblyInput(<br>
> +    ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::MergedAssemblyInput, Data);<br>
>  }<br>
> -Error IModuleSubstreamVisitor::visitCoffSymbolRVA(StreamRef Data) {<br>
> +Error IModuleSubstreamVisitor::visitCoffSymbolRVA(ReadableStreamRef Data) {<br>
>    return visitUnknown(ModuleSubstreamKind::CoffSymbolRVA, Data);<br>
>  }<br>
><br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Thu Jul 28 14:12:28 2016<br>
> @@ -681,7 +681,7 @@ Error CVTypeDumper::dump(const CVTypeArr<br>
>  }<br>
><br>
>  Error CVTypeDumper::dump(ArrayRef<uint8_t> Data) {<br>
> -  msf::ByteStream<> Stream(Data);<br>
> +  msf::ByteStream Stream(Data);<br>
>    CVTypeArray Types;<br>
>    msf::StreamReader Reader(Stream);<br>
>    if (auto EC = Reader.readArray(Types, Reader.getLength()))<br>
><br>
> Removed: llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp?rev=277018&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp?rev=277018&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/Msf/ByteStream.cpp (removed)<br>
> @@ -1,79 +0,0 @@<br>
> -//===- ByteStream.cpp - Reads stream data from a byte sequence ------------===//<br>
> -//<br>
> -//                     The LLVM Compiler Infrastructure<br>
> -//<br>
> -// This file is distributed under the University of Illinois Open Source<br>
> -// License. See LICENSE.TXT for details.<br>
> -//<br>
> -//===----------------------------------------------------------------------===//<br>
> -<br>
> -#include "llvm/DebugInfo/Msf/ByteStream.h"<br>
> -#include "llvm/DebugInfo/Msf/MsfError.h"<br>
> -#include "llvm/DebugInfo/Msf/StreamReader.h"<br>
> -#include <cstring><br>
> -<br>
> -using namespace llvm;<br>
> -using namespace llvm::msf;<br>
> -<br>
> -static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,<br>
> -                        ArrayRef<uint8_t> Dest) {<br>
> -  return make_error<MsfError>(msf_error_code::not_writable,<br>
> -                              "ByteStream is immutable.");<br>
> -}<br>
> -<br>
> -static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,<br>
> -                        MutableArrayRef<uint8_t> Dest) {<br>
> -  if (Dest.size() < Src.size())<br>
> -    return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -  if (Offset > Src.size() - Dest.size())<br>
> -    return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -<br>
> -  ::memcpy(Dest.data() + Offset, Src.data(), Src.size());<br>
> -  return Error::success();<br>
> -}<br>
> -<br>
> -template <bool Writable><br>
> -Error ByteStream<Writable>::readBytes(uint32_t Offset, uint32_t Size,<br>
> -                                      ArrayRef<uint8_t> &Buffer) const {<br>
> -  if (Offset > Data.size())<br>
> -    return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -  if (Data.size() < Size + Offset)<br>
> -    return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -  Buffer = Data.slice(Offset, Size);<br>
> -  return Error::success();<br>
> -}<br>
> -<br>
> -template <bool Writable><br>
> -Error ByteStream<Writable>::readLongestContiguousChunk(<br>
> -    uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {<br>
> -  if (Offset >= Data.size())<br>
> -    return make_error<MsfError>(msf_error_code::insufficient_buffer);<br>
> -  Buffer = Data.slice(Offset);<br>
> -  return Error::success();<br>
> -}<br>
> -<br>
> -template <bool Writable><br>
> -Error ByteStream<Writable>::writeBytes(uint32_t Offset,<br>
> -                                       ArrayRef<uint8_t> Buffer) const {<br>
> -  return ::writeBytes(Offset, Buffer, Data);<br>
> -}<br>
> -<br>
> -template <bool Writable> uint32_t ByteStream<Writable>::getLength() const {<br>
> -  return Data.size();<br>
> -}<br>
> -<br>
> -template <bool Writable> Error ByteStream<Writable>::commit() const {<br>
> -  return Error::success();<br>
> -}<br>
> -<br>
> -template <bool Writable> StringRef ByteStream<Writable>::str() const {<br>
> -  const char *CharData = reinterpret_cast<const char *>(Data.data());<br>
> -  return StringRef(CharData, Data.size());<br>
> -}<br>
> -<br>
> -namespace llvm {<br>
> -namespace msf {<br>
> -template class ByteStream<true>;<br>
> -template class ByteStream<false>;<br>
> -}<br>
> -}<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/DebugInfo/Msf/CMakeLists.txt Thu Jul 28 14:12:28 2016<br>
> @@ -1,5 +1,4 @@<br>
>  add_llvm_library(LLVMDebugInfoMsf<br>
> -  ByteStream.cpp<br>
>    MappedBlockStream.cpp<br>
>    MsfBuilder.cpp<br>
>    MsfCommon.cpp<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp?rev=277019&r1=277018&r2=277019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp?rev=277019&r1=277018&r2=277019&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/Msf/MappedBlockStream.cpp Thu Jul 28 14:12:28 2016<br>
> @@ -10,6 +10,7 @@<br>
>  #include "llvm/DebugInfo/Msf/MappedBlockStream.h"<br>
><br>
>  #include "llvm/DebugInfo/Msf/IMsfFile.h"<br>
> +#include "llvm/DebugInfo/Msf/MsfCommon.h"<br>
>  #include "llvm/DebugInfo/Msf/MsfError.h"<br>
>  #include "llvm/DebugInfo/Msf/MsfStreamLayout.h"<br>
><br>
> @@ -17,13 +18,11 @@ using namespace llvm;<br>
>  using namespace llvm::msf;<br>
><br>
>  namespace {<br>
> -// This exists so that we can use make_unique (which requires a public default<br>
> -// constructor, while still keeping the constructor of MappedBlockStream<br>
> -// protected, forcing users to go through the `create` interface.<br>
> -class MappedBlockStreamImpl : public MappedBlockStream {<br>
> +template <typename Base> class MappedBlockStreamImpl : public Base {<br>
>  public:<br>
> -  MappedBlockStreamImpl(const MsfStreamLayout &Layout, const IMsfFile &File)<br>
> -      : MappedBlockStream(Layout, File) {}<br>
> +  template <typename... Args><br>
> +  MappedBlockStreamImpl(Args &&... Params)<br>
> +      : Base(std::forward<Args>(Params)...) {}<br>
>  };<br>
>  }<br>
><br>
> @@ -33,16 +32,46 @@ static Interval intersect(const Interval<br>
>     </blockquote></div>