[llvm] r296215 - [PDB] General improvements to Stream library.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 24 16:44:32 PST 2017


Author: zturner
Date: Fri Feb 24 18:44:30 2017
New Revision: 296215

URL: http://llvm.org/viewvc/llvm-project?rev=296215&view=rev
Log:
[PDB] General improvements to Stream library.

This adds various new functionality and cleanup surrounding the
use of the Stream library.  Major changes include:

* Renaming of all classes for more consistency / meaningfulness
* Addition of some new methods for reading multiple values at once.
* Full suite of unit tests for reader / writer functionality.
* Full set of doxygen comments for all classes.
* Streams now store their own endianness.
* Fixed some bugs in a few of the classes that were discovered
  by the unit tests.

Added:
    llvm/trunk/unittests/DebugInfo/PDB/BinaryStreamTest.cpp
Modified:
    llvm/trunk/include/llvm/ADT/STLExtras.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/RecordSerialization.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryByteStream.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryItemStream.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStream.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamArray.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamReader.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamRef.h
    llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamWriter.h
    llvm/trunk/include/llvm/DebugInfo/MSF/MappedBlockStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModInfo.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFile.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PublicsStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
    llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp
    llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/RecordSerialization.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp
    llvm/trunk/lib/DebugInfo/MSF/BinaryStreamReader.cpp
    llvm/trunk/lib/DebugInfo/MSF/BinaryStreamWriter.cpp
    llvm/trunk/lib/DebugInfo/MSF/MappedBlockStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/GSI.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/GSI.h
    llvm/trunk/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/HashTable.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/ModInfo.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/ModStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PublicsStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/SymbolStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/unittests/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/unittests/DebugInfo/PDB/HashTableTest.cpp
    llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
    llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp

Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Fri Feb 24 18:44:30 2017
@@ -640,6 +640,16 @@ detail::concat_range<ValueT, RangeTs...>
 //     Extra additions to <utility>
 //===----------------------------------------------------------------------===//
 
+/// \brief Template class to compute the sum of sizes of all items in a
+/// parameter pack.
+template <typename T, typename... Ts> struct sizeof_sum {
+  static const size_t value = sizeof(T) + sizeof_sum<Ts...>::value;
+};
+
+template <typename T> struct sizeof_sum<T> {
+  static const size_t value = sizeof(T);
+};
+
 /// \brief Function object to check whether the first component of a std::pair
 /// compares less than the first component of another std::pair.
 struct less_first {

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=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Fri Feb 24 18:44:30 2017
@@ -48,15 +48,13 @@ public:
 
 } // end namespace codeview
 
-namespace msf {
-
 template <typename Kind>
 struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
-  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
                    codeview::CVRecord<Kind> &Item) const {
     using namespace codeview;
     const RecordPrefix *Prefix = nullptr;
-    StreamReader Reader(Stream);
+    BinaryStreamReader Reader(Stream);
     uint32_t Offset = Reader.getOffset();
 
     if (auto EC = Reader.readObject(Prefix))
@@ -76,8 +74,6 @@ struct VarStreamArrayExtractor<codeview:
   }
 };
 
-} // end namespace msf
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Fri Feb 24 18:44:30 2017
@@ -34,7 +34,7 @@ public:
   Error visitTypeStream(CVTypeRange Types);
 
   Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);
-  Error visitFieldListMemberStream(msf::StreamReader Reader);
+  Error visitFieldListMemberStream(BinaryStreamReader Reader);
 
 private:
   /// The interface to the class that gets notified of each visitation.

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h Fri Feb 24 18:44:30 2017
@@ -33,8 +33,8 @@ class CodeViewRecordIO {
   }
 
 public:
-  explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
-  explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}
+  explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
+  explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
 
   Error beginRecord(Optional<uint32_t> MaxLength);
   Error endRecord();
@@ -59,9 +59,9 @@ public:
 
   template <typename T> Error mapInteger(T &Value) {
     if (isWriting())
-      return Writer->writeInteger(Value, llvm::support::little);
+      return Writer->writeInteger(Value);
 
-    return Reader->readInteger(Value, llvm::support::little);
+    return Reader->readInteger(Value);
   }
 
   template <typename T> Error mapEnum(T &Value) {
@@ -93,7 +93,7 @@ public:
     SizeType Size;
     if (isWriting()) {
       Size = static_cast<SizeType>(Items.size());
-      if (auto EC = Writer->writeInteger(Size, llvm::support::little))
+      if (auto EC = Writer->writeInteger(Size))
         return EC;
 
       for (auto &X : Items) {
@@ -101,7 +101,7 @@ public:
           return EC;
       }
     } else {
-      if (auto EC = Reader->readInteger(Size, llvm::support::little))
+      if (auto EC = Reader->readInteger(Size))
         return EC;
       for (SizeType I = 0; I < Size; ++I) {
         typename T::value_type Item;
@@ -160,8 +160,8 @@ private:
 
   SmallVector<RecordLimit, 2> Limits;
 
-  msf::StreamReader *Reader = nullptr;
-  msf::StreamWriter *Writer = nullptr;
+  BinaryStreamReader *Reader = nullptr;
+  BinaryStreamWriter *Writer = nullptr;
 };
 
 } // end namespace codeview

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=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstream.h Fri Feb 24 18:44:30 2017
@@ -59,23 +59,22 @@ struct ColumnNumberEntry {
 class ModuleSubstream {
 public:
   ModuleSubstream();
-  ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data);
-  static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info);
+  ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data);
+  static Error initialize(BinaryStreamRef Stream, ModuleSubstream &Info);
   uint32_t getRecordLength() const;
   ModuleSubstreamKind getSubstreamKind() const;
-  msf::ReadableStreamRef getRecordData() const;
+  BinaryStreamRef getRecordData() const;
 
 private:
   ModuleSubstreamKind Kind;
-  msf::ReadableStreamRef Data;
+  BinaryStreamRef Data;
 };
 
-typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
+typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
 } // namespace codeview
 
-namespace msf {
 template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {
-  Error operator()(ReadableStreamRef Stream, uint32_t &Length,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Length,
                    codeview::ModuleSubstream &Info) const {
     if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))
       return EC;
@@ -83,7 +82,6 @@ template <> struct VarStreamArrayExtract
     return Error::success();
   }
 };
-} // namespace msf
 } // namespace llvm
 
 #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H

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=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h Fri Feb 24 18:44:30 2017
@@ -28,8 +28,8 @@ namespace codeview {
 
 struct LineColumnEntry {
   support::ulittle32_t NameIndex;
-  msf::FixedStreamArray<LineNumberEntry> LineNumbers;
-  msf::FixedStreamArray<ColumnNumberEntry> Columns;
+  FixedStreamArray<LineNumberEntry> LineNumbers;
+  FixedStreamArray<ColumnNumberEntry> Columns;
 };
 
 struct FileChecksumEntry {
@@ -38,49 +38,47 @@ struct FileChecksumEntry {
   ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
 };
 
-typedef msf::VarStreamArray<LineColumnEntry> LineInfoArray;
-typedef msf::VarStreamArray<FileChecksumEntry> FileChecksumArray;
+typedef VarStreamArray<LineColumnEntry> LineInfoArray;
+typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
 
 class IModuleSubstreamVisitor {
 public:
   virtual ~IModuleSubstreamVisitor() = default;
 
   virtual Error visitUnknown(ModuleSubstreamKind Kind,
-                             msf::ReadableStreamRef Data) = 0;
-  virtual Error visitSymbols(msf::ReadableStreamRef Data);
-  virtual Error visitLines(msf::ReadableStreamRef Data,
+                             BinaryStreamRef Data) = 0;
+  virtual Error visitSymbols(BinaryStreamRef Data);
+  virtual Error visitLines(BinaryStreamRef Data,
                            const LineSubstreamHeader *Header,
                            const LineInfoArray &Lines);
-  virtual Error visitStringTable(msf::ReadableStreamRef Data);
-  virtual Error visitFileChecksums(msf::ReadableStreamRef Data,
+  virtual Error visitStringTable(BinaryStreamRef Data);
+  virtual Error visitFileChecksums(BinaryStreamRef Data,
                                    const FileChecksumArray &Checksums);
-  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);
+  virtual Error visitFrameData(BinaryStreamRef Data);
+  virtual Error visitInlineeLines(BinaryStreamRef Data);
+  virtual Error visitCrossScopeImports(BinaryStreamRef Data);
+  virtual Error visitCrossScopeExports(BinaryStreamRef Data);
+  virtual Error visitILLines(BinaryStreamRef Data);
+  virtual Error visitFuncMDTokenMap(BinaryStreamRef Data);
+  virtual Error visitTypeMDTokenMap(BinaryStreamRef Data);
+  virtual Error visitMergedAssemblyInput(BinaryStreamRef Data);
+  virtual Error visitCoffSymbolRVA(BinaryStreamRef Data);
 };
 
 Error visitModuleSubstream(const ModuleSubstream &R,
                            IModuleSubstreamVisitor &V);
 } // end namespace codeview
 
-namespace msf {
-
 template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
 public:
   VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header)
       : Header(Header) {}
 
-  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
                    codeview::LineColumnEntry &Item) const {
     using namespace codeview;
     const LineFileBlockHeader *BlockHeader;
-    StreamReader Reader(Stream);
+    BinaryStreamReader Reader(Stream);
     if (auto EC = Reader.readObject(BlockHeader))
       return EC;
     bool HasColumn = Header->Flags & LineFlags::HaveColumns;
@@ -113,11 +111,11 @@ private:
 
 template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
 public:
-  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
                    codeview::FileChecksumEntry &Item) const {
     using namespace codeview;
     const FileChecksum *Header;
-    StreamReader Reader(Stream);
+    BinaryStreamReader Reader(Stream);
     if (auto EC = Reader.readObject(Header))
       return EC;
     Item.FileNameOffset = Header->FileNameOffset;
@@ -129,8 +127,6 @@ public:
   }
 };
 
-} // end namespace msf
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/RecordSerialization.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/RecordSerialization.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/RecordSerialization.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/RecordSerialization.h Fri Feb 24 18:44:30 2017
@@ -41,37 +41,37 @@ struct RecordPrefix {
 StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
 StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
 
-inline Error consume(msf::StreamReader &Reader) { return Error::success(); }
+inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
 
 /// Decodes a numeric "leaf" value. These are integer literals encountered in
 /// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
 /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
 /// that indicates the bitwidth and sign of the numeric data.
-Error consume(msf::StreamReader &Reader, APSInt &Num);
+Error consume(BinaryStreamReader &Reader, APSInt &Num);
 
 /// Decodes a numeric leaf value that is known to be a particular type.
-Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value);
+Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
 
 /// Decodes signed and unsigned fixed-length integers.
-Error consume(msf::StreamReader &Reader, uint32_t &Item);
-Error consume(msf::StreamReader &Reader, int32_t &Item);
+Error consume(BinaryStreamReader &Reader, uint32_t &Item);
+Error consume(BinaryStreamReader &Reader, int32_t &Item);
 
 /// Decodes a null terminated string.
-Error consume(msf::StreamReader &Reader, StringRef &Item);
+Error consume(BinaryStreamReader &Reader, StringRef &Item);
 
 Error consume(StringRef &Data, APSInt &Num);
 Error consume(StringRef &Data, uint32_t &Item);
 
 /// Decodes an arbitrary object whose layout matches that of the underlying
 /// byte sequence, and returns a pointer to the object.
-template <typename T> Error consume(msf::StreamReader &Reader, T *&Item) {
+template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
   return Reader.readObject(Item);
 }
 
 template <typename T, typename U> struct serialize_conditional_impl {
   serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     if (!Func())
       return Error::success();
     return consume(Reader, Item);
@@ -89,7 +89,7 @@ serialize_conditional_impl<T, U> seriali
 template <typename T, typename U> struct serialize_array_impl {
   serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     return Reader.readArray(Item, Func());
   }
 
@@ -100,7 +100,7 @@ template <typename T, typename U> struct
 template <typename T> struct serialize_vector_tail_impl {
   serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     T Field;
     // Stop when we run out of bytes or we hit record padding bytes.
     while (!Reader.empty() && Reader.peek() < LF_PAD0) {
@@ -118,14 +118,14 @@ struct serialize_null_term_string_array_
   serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
       : Item(Item) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     if (Reader.empty())
       return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
                                        "Null terminated string is empty!");
 
     while (Reader.peek() != 0) {
       StringRef Field;
-      if (auto EC = Reader.readZeroString(Field))
+      if (auto EC = Reader.readCString(Field))
         return EC;
       Item.push_back(Field);
     }
@@ -138,7 +138,7 @@ struct serialize_null_term_string_array_
 template <typename T> struct serialize_arrayref_tail_impl {
   serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     uint32_t Count = Reader.bytesRemaining() / sizeof(T);
     return Reader.readArray(Item, Count);
   }
@@ -149,7 +149,7 @@ template <typename T> struct serialize_a
 template <typename T> struct serialize_numeric_impl {
   serialize_numeric_impl(T &Item) : Item(Item) {}
 
-  Error deserialize(msf::StreamReader &Reader) const {
+  Error deserialize(BinaryStreamReader &Reader) const {
     return consume_numeric(Reader, Item);
   }
 
@@ -201,42 +201,42 @@ template <typename T> serialize_numeric_
 #define CV_NUMERIC_FIELD(I) serialize_numeric(I)
 
 template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
               const serialize_conditional_impl<T, U> &Item) {
   return Item.deserialize(Reader);
 }
 
 template <typename T, typename U>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
               const serialize_array_impl<T, U> &Item) {
   return Item.deserialize(Reader);
 }
 
-inline Error consume(msf::StreamReader &Reader,
+inline Error consume(BinaryStreamReader &Reader,
                      const serialize_null_term_string_array_impl &Item) {
   return Item.deserialize(Reader);
 }
 
 template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
               const serialize_vector_tail_impl<T> &Item) {
   return Item.deserialize(Reader);
 }
 
 template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
               const serialize_arrayref_tail_impl<T> &Item) {
   return Item.deserialize(Reader);
 }
 
 template <typename T>
-Error consume(msf::StreamReader &Reader,
+Error consume(BinaryStreamReader &Reader,
               const serialize_numeric_impl<T> &Item) {
   return Item.deserialize(Reader);
 }
 
 template <typename T, typename U, typename... Args>
-Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
+Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
   if (auto EC = consume(Reader, X))
     return EC;
   return consume(Reader, Y, std::forward<Args>(Rest)...);

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h Fri Feb 24 18:44:30 2017
@@ -25,10 +25,11 @@ class SymbolVisitorDelegate;
 class SymbolDeserializer : public SymbolVisitorCallbacks {
   struct MappingInfo {
     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
-        : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+        : Stream(RecordData, llvm::support::little), Reader(Stream),
+          Mapping(Reader) {}
 
-    msf::ByteStream Stream;
-    msf::StreamReader Reader;
+    BinaryByteStream Stream;
+    BinaryStreamReader Reader;
     SymbolRecordMapping Mapping;
   };
 

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Fri Feb 24 18:44:30 2017
@@ -938,7 +938,7 @@ public:
 };
 
 typedef CVRecord<SymbolKind> CVSymbol;
-typedef msf::VarStreamArray<CVSymbol> CVSymbolArray;
+typedef VarStreamArray<CVSymbol> CVSymbolArray;
 
 } // end namespace codeview
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h Fri Feb 24 18:44:30 2017
@@ -14,16 +14,14 @@
 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
 
 namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
 
 namespace codeview {
 class SymbolRecordMapping : public SymbolVisitorCallbacks {
 public:
-  explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
-  explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+  explicit SymbolRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
+  explicit SymbolRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
 
   Error visitSymbolBegin(CVSymbol &Record) override;
   Error visitSymbolEnd(CVSymbol &Record) override;

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h Fri Feb 24 18:44:30 2017
@@ -20,6 +20,8 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/MSF/BinaryByteStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Error.h"
 
@@ -28,7 +30,7 @@ namespace codeview {
 
 class SymbolSerializer : public SymbolVisitorCallbacks {
   uint32_t RecordStart = 0;
-  msf::StreamWriter &Writer;
+  BinaryStreamWriter &Writer;
   SymbolRecordMapping Mapping;
   Optional<SymbolKind> CurrentSymbol;
 
@@ -42,7 +44,7 @@ class SymbolSerializer : public SymbolVi
   }
 
 public:
-  explicit SymbolSerializer(msf::StreamWriter &Writer)
+  explicit SymbolSerializer(BinaryStreamWriter &Writer)
       : Writer(Writer), Mapping(Writer) {}
 
   virtual Error visitSymbolBegin(CVSymbol &Record) override {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h Fri Feb 24 18:44:30 2017
@@ -15,9 +15,7 @@
 
 namespace llvm {
 
-namespace msf {
-class StreamReader;
-} // end namespace msf
+class BinaryStreamReader;
 
 namespace codeview {
 
@@ -25,7 +23,7 @@ class SymbolVisitorDelegate {
 public:
   virtual ~SymbolVisitorDelegate() = default;
 
-  virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0;
+  virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
   virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
   virtual StringRef getStringTable() = 0;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Fri Feb 24 18:44:30 2017
@@ -29,10 +29,11 @@ namespace codeview {
 class TypeDeserializer : public TypeVisitorCallbacks {
   struct MappingInfo {
     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
-        : Stream(RecordData), Reader(Stream), Mapping(Reader) {}
+        : Stream(RecordData, llvm::support::little), Reader(Stream),
+          Mapping(Reader) {}
 
-    msf::ByteStream Stream;
-    msf::StreamReader Reader;
+    BinaryByteStream Stream;
+    BinaryStreamReader Reader;
     TypeRecordMapping Mapping;
   };
 
@@ -72,16 +73,16 @@ private:
 
 class FieldListDeserializer : public TypeVisitorCallbacks {
   struct MappingInfo {
-    explicit MappingInfo(msf::StreamReader &R)
+    explicit MappingInfo(BinaryStreamReader &R)
         : Reader(R), Mapping(Reader), StartOffset(0) {}
 
-    msf::StreamReader &Reader;
+    BinaryStreamReader &Reader;
     TypeRecordMapping Mapping;
     uint32_t StartOffset;
   };
 
 public:
-  explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
+  explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
     CVType FieldList;
     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Fri Feb 24 18:44:30 2017
@@ -26,9 +26,7 @@
 
 namespace llvm {
 
-namespace msf {
-class StreamReader;
-} // end namespace msf
+class BinaryStreamReader;
 
 namespace codeview {
 
@@ -42,7 +40,7 @@ struct CVMemberRecord {
   TypeLeafKind Kind;
   ArrayRef<uint8_t> Data;
 };
-typedef msf::VarStreamArray<CVType> CVTypeArray;
+typedef VarStreamArray<CVType> CVTypeArray;
 typedef iterator_range<CVTypeArray::Iterator> CVTypeRange;
 
 /// Equvalent to CV_fldattr_t in cvinfo.h.

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h Fri Feb 24 18:44:30 2017
@@ -16,15 +16,14 @@
 #include "llvm/Support/Error.h"
 
 namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
 namespace codeview {
 class TypeRecordMapping : public TypeVisitorCallbacks {
 public:
-  explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
-  explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}
+  explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
+  explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
 
   Error visitTypeBegin(CVType &Record) override;
   Error visitTypeEnd(CVType &Record) override;

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializer.h Fri Feb 24 18:44:30 2017
@@ -56,8 +56,8 @@ class TypeSerializer : public TypeVisito
   Optional<TypeLeafKind> TypeKind;
   Optional<TypeLeafKind> MemberKind;
   std::vector<uint8_t> RecordBuffer;
-  msf::MutableByteStream Stream;
-  msf::StreamWriter Writer;
+  MutableBinaryByteStream Stream;
+  BinaryStreamWriter Writer;
   TypeRecordMapping Mapping;
 
   RecordList SeenRecords;
@@ -109,7 +109,7 @@ private:
   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
     assert(CVR.Kind == static_cast<TypeLeafKind>(Record.getKind()));
 
-    if (auto EC = Writer.writeEnum(CVR.Kind, llvm::support::little))
+    if (auto EC = Writer.writeEnum(CVR.Kind))
       return EC;
 
     if (auto EC = Mapping.visitKnownMember(CVR, Record))

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryByteStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryByteStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryByteStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryByteStream.h Fri Feb 24 18:44:30 2017
@@ -1,19 +1,19 @@
-//===- ByteStream.h - Reads stream data from a byte sequence ----*- C++ -*-===//
+//===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
-//
+//===----------------------------------------------------------------------===//
+// A BinaryStream which stores data in a single continguous memory buffer.
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_BYTESTREAM_H
-#define LLVM_DEBUGINFO_MSF_BYTESTREAM_H
+#ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
+#define LLVM_SUPPORT_BINARYBYTESTREAM_H
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -23,34 +23,40 @@
 #include <memory>
 
 namespace llvm {
-namespace msf {
 
-class ByteStream : public ReadableStream {
+/// \brief An implementation of BinaryStream which holds its entire data set
+/// in a single contiguous buffer.  BinaryByteStream guarantees that no read
+/// operation will ever incur a copy.  Note that BinaryByteStream does not
+/// own the underlying buffer.
+class BinaryByteStream : public BinaryStream {
 public:
-  ByteStream() = default;
-  explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
-  explicit ByteStream(StringRef Data)
-      : Data(Data.bytes_begin(), Data.bytes_end()) {}
+  BinaryByteStream() = default;
+  BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
+      : Endian(Endian), Data(Data) {}
+  BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
+      : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
+
+  llvm::support::endianness getEndian() const override { return Endian; }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override {
+                  ArrayRef<uint8_t> &Buffer) override {
     if (Offset > Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     if (Data.size() < Size + Offset)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     Buffer = Data.slice(Offset, Size);
     return Error::success();
   }
 
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override {
+                                   ArrayRef<uint8_t> &Buffer) override {
     if (Offset >= Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     Buffer = Data.slice(Offset);
     return Error::success();
   }
 
-  uint32_t getLength() const override { return Data.size(); }
+  uint32_t getLength() override { return Data.size(); }
 
   ArrayRef<uint8_t> data() const { return Data; }
 
@@ -60,76 +66,91 @@ public:
   }
 
 protected:
+  llvm::support::endianness Endian;
   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 {
+/// \brief An implementation of BinaryStream whose data is backed by an llvm
+/// MemoryBuffer object.  MemoryBufferByteStream owns the MemoryBuffer in
+/// question.  As with BinaryByteStream, reading from a MemoryBufferByteStream
+/// will never cause a copy.
+class MemoryBufferByteStream : public BinaryByteStream {
 public:
-  explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
-      : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
-                                     Buffer->getBuffer().bytes_end())),
+  explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
+                                  llvm::support::endianness Endian)
+      : BinaryByteStream(Buffer->getBuffer(), Endian),
         MemBuffer(std::move(Buffer)) {}
 
   std::unique_ptr<MemoryBuffer> MemBuffer;
 };
 
-class MutableByteStream : public WritableStream {
+/// \brief An implementation of BinaryStream which holds its entire data set
+/// in a single contiguous buffer.  As with BinaryByteStream, the mutable
+/// version also guarantees that no read operation will ever incur a copy,
+/// and similarly it does not own the underlying buffer.
+class MutableBinaryByteStream : public WritableBinaryStream {
 public:
-  MutableByteStream() = default;
-  explicit MutableByteStream(MutableArrayRef<uint8_t> Data)
-      : Data(Data), ImmutableStream(Data) {}
+  MutableBinaryByteStream() = default;
+  MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
+                          llvm::support::endianness Endian)
+      : Data(Data), ImmutableStream(Data, Endian) {}
+
+  llvm::support::endianness getEndian() const override {
+    return ImmutableStream.getEndian();
+  }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override {
+                  ArrayRef<uint8_t> &Buffer) override {
     return ImmutableStream.readBytes(Offset, Size, Buffer);
   }
 
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override {
+                                   ArrayRef<uint8_t> &Buffer) override {
     return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
   }
 
-  uint32_t getLength() const override { return ImmutableStream.getLength(); }
+  uint32_t getLength() override { return ImmutableStream.getLength(); }
 
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override {
     if (Buffer.empty())
       return Error::success();
 
     if (Data.size() < Buffer.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     if (Offset > Buffer.size() - Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
 
     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(); }
+  Error commit() override { return Error::success(); }
 
   MutableArrayRef<uint8_t> data() const { return Data; }
 
 private:
   MutableArrayRef<uint8_t> Data;
-  ByteStream ImmutableStream;
+  BinaryByteStream ImmutableStream;
 };
 
-// A simple adapter that acts like a ByteStream but holds ownership over
-// and underlying FileOutputBuffer.
-class FileBufferByteStream : public WritableStream {
+/// \brief An implementation of WritableBinaryStream backed by an llvm
+/// FileOutputBuffer.
+class FileBufferByteStream : public WritableBinaryStream {
 private:
-  class StreamImpl : public MutableByteStream {
+  class StreamImpl : public MutableBinaryByteStream {
   public:
-    StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
-        : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
-                                                     Buffer->getBufferEnd())),
+    StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
+               llvm::support::endianness Endian)
+        : MutableBinaryByteStream(
+              MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
+                                       Buffer->getBufferEnd()),
+              Endian),
           FileBuffer(std::move(Buffer)) {}
 
-    Error commit() const override {
+    Error commit() override {
       if (FileBuffer->commit())
-        return llvm::make_error<MSFError>(msf_error_code::not_writable);
+        return errorCodeToError(make_error_code(std::errc::no_buffer_space));
       return Error::success();
     }
 
@@ -138,32 +159,36 @@ private:
   };
 
 public:
-  explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
-      : Impl(std::move(Buffer)) {}
+  explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
+                                llvm::support::endianness Endian)
+      : Impl(std::move(Buffer), Endian) {}
+
+  llvm::support::endianness getEndian() const override {
+    return Impl.getEndian();
+  }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override {
+                  ArrayRef<uint8_t> &Buffer) override {
     return Impl.readBytes(Offset, Size, Buffer);
   }
 
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override {
+                                   ArrayRef<uint8_t> &Buffer) override {
     return Impl.readLongestContiguousChunk(Offset, Buffer);
   }
 
-  uint32_t getLength() const override { return Impl.getLength(); }
+  uint32_t getLength() override { return Impl.getLength(); }
 
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
     return Impl.writeBytes(Offset, Data);
   }
 
-  Error commit() const override { return Impl.commit(); }
+  Error commit() override { return Impl.commit(); }
 
 private:
   StreamImpl Impl;
 };
 
-} // end namespace msf
 } // end namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H
+#endif // LLVM_SUPPORT_BINARYBYTESTREAM_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryItemStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryItemStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryItemStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryItemStream.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- SequencedItemStream.h ------------------------------------*- C++ -*-===//
+//===- BinaryItemStream.h ---------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,87 +7,96 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
-#define LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
+#ifndef LLVM_SUPPORT_BINARYITEMSTREAM_H
+#define LLVM_SUPPORT_BINARYITEMSTREAM_H
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 #include "llvm/Support/Error.h"
 #include <cstddef>
 #include <cstdint>
 
 namespace llvm {
-namespace msf {
 
-template <typename T> struct SequencedItemTraits {
-  static size_t length(const T &Item) = delete;
-  static ArrayRef<uint8_t> bytes(const T &Item) = delete;
+template <typename T> struct BinaryItemTraits {
+  size_t length(const T &Item) = delete;
+  ArrayRef<uint8_t> bytes(const T &Item) = delete;
 };
 
-/// SequencedItemStream represents a sequence of objects stored in a
-/// standard container but for which it is useful to view as a stream of
-/// contiguous bytes.  An example of this might be if you have a std::vector
-/// of TPI records, where each record contains a byte sequence that
-/// represents that one record serialized, but where each consecutive item
-/// might not be allocated immediately after the previous item.  Using a
-/// SequencedItemStream, we can adapt the VarStreamArray class to trivially
-/// extract one item at a time, allowing the data to be used anywhere a
-/// VarStreamArray could be used.
-template <typename T, typename Traits = SequencedItemTraits<T>>
-class SequencedItemStream : public ReadableStream {
+/// BinaryItemStream represents a sequence of objects stored in some kind of
+/// external container but for which it is useful to view as a stream of
+/// contiguous bytes.  An example of this might be if you have a collection of
+/// records and you serialize each one into a buffer, and store these serialized
+/// records in a container.  The pointers themselves are not laid out
+/// contiguously in memory, but we may wish to read from or write to these
+/// records as if they were.
+template <typename T, typename ItemTraits = BinaryItemTraits<T>>
+class BinaryItemStream : public BinaryStream {
 public:
-  SequencedItemStream() = default;
+  explicit BinaryItemStream(llvm::support::endianness Endian)
+      : Endian(Endian) {}
+
+  llvm::support::endianness getEndian() const override { return Endian; }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override {
-    auto ExpectedIndex = translateOffsetIndex(Offset);
-    if (!ExpectedIndex)
-      return ExpectedIndex.takeError();
-    const auto &Item = Items[*ExpectedIndex];
-    if (Size > Traits::length(Item))
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
-    Buffer = Traits::bytes(Item).take_front(Size);
+                  ArrayRef<uint8_t> &Buffer) override {
+    if (auto EC = readLongestContiguousChunk(Offset, Buffer))
+      return EC;
+
+    if (Size > Buffer.size())
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+
+    Buffer = Buffer.take_front(Size);
     return Error::success();
   }
 
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override {
-    auto ExpectedIndex = translateOffsetIndex(Offset);
-    if (!ExpectedIndex)
-      return ExpectedIndex.takeError();
-    Buffer = Traits::bytes(Items[*ExpectedIndex]);
+                                   ArrayRef<uint8_t> &Buffer) override {
+    uint32_t Index;
+    uint32_t ByteOffset;
+    if (auto EC = translateOffsetIndex(Offset, Index, ByteOffset))
+      return EC;
+    const auto &Item = Items[Index];
+    Buffer = Traits.bytes(Item).drop_front(ByteOffset);
     return Error::success();
   }
 
   void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; }
 
-  uint32_t getLength() const override {
+  uint32_t getLength() override {
     uint32_t Size = 0;
     for (const auto &Item : Items)
-      Size += Traits::length(Item);
+      Size += Traits.length(Item);
     return Size;
   }
 
 private:
-  Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const {
+  Error translateOffsetIndex(uint32_t Offset, uint32_t &ItemIndex,
+                             uint32_t &ByteOffset) {
+    ItemIndex = 0;
+    ByteOffset = 0;
+    uint32_t PrevOffset = 0;
     uint32_t CurrentOffset = 0;
-    uint32_t CurrentIndex = 0;
-    for (const auto &Item : Items) {
-      if (CurrentOffset >= Offset)
-        break;
-      CurrentOffset += Traits::length(Item);
-      ++CurrentIndex;
+    if (Offset > 0) {
+      for (const auto &Item : Items) {
+        PrevOffset = CurrentOffset;
+        CurrentOffset += Traits.length(Item);
+        if (CurrentOffset > Offset)
+          break;
+        ++ItemIndex;
+      }
     }
-    if (CurrentOffset != Offset)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
-    return CurrentIndex;
+    if (CurrentOffset < Offset)
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+    ByteOffset = Offset - PrevOffset;
+    return Error::success();
   }
 
+  llvm::support::endianness Endian;
+  ItemTraits Traits;
   ArrayRef<T> Items;
 };
 
-} // end namespace msf
 } // end namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
+#endif // LLVM_SUPPORT_BINARYITEMSTREAM_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStream.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamInterface.h - Base interface for a stream of data --*- C++ -*-===//
+//===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,47 +7,62 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
-#define LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
+#ifndef LLVM_SUPPORT_BINARYSTREAM_H
+#define LLVM_SUPPORT_BINARYSTREAM_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
 
 namespace llvm {
-namespace msf {
 
-class ReadableStream {
+/// \brief An interface for accessing data in a stream-like format, but which
+/// discourages copying.  Instead of specifying a buffer in which to copy
+/// data on a read, the API returns an ArrayRef to data owned by the stream's
+/// implementation.  Since implementations may not necessarily store data in a
+/// single contiguous buffer (or even in memory at all), in such cases a it may
+/// be necessary for an implementation to cache such a buffer so that it can
+/// return it.
+class BinaryStream {
 public:
-  virtual ~ReadableStream() = default;
+  virtual ~BinaryStream() = default;
 
-  // 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
-  // stream, without copying any data.
+  virtual llvm::support::endianness getEndian() const = 0;
+
+  /// \brief Given an offset into the stream and a number of bytes, attempt to
+  /// read the bytes and set the output ArrayRef to point to data owned by the
+  /// stream.
   virtual Error readBytes(uint32_t Offset, uint32_t Size,
-                          ArrayRef<uint8_t> &Buffer) const = 0;
+                          ArrayRef<uint8_t> &Buffer) = 0;
 
-  // Given an offset into the stream, read as much as possible without copying
-  // any data.
+  /// \brief Given an offset into the stream, read as much as possible without
+  /// copying any data.
   virtual Error readLongestContiguousChunk(uint32_t Offset,
-                                           ArrayRef<uint8_t> &Buffer) const = 0;
+                                           ArrayRef<uint8_t> &Buffer) = 0;
 
-  virtual uint32_t getLength() const = 0;
+  /// \brief Return the number of bytes of data in this stream.
+  virtual uint32_t getLength() = 0;
 };
 
-class WritableStream : public ReadableStream {
+/// \brief A BinaryStream which can be read from as well as written to.  Note
+/// that writing to a BinaryStream always necessitates copying from the input
+/// buffer to the stream's backing store.  Streams are assumed to be buffered
+/// so that to be portable it is necessary to call commit() on the stream when
+/// all data has been written.
+class WritableBinaryStream : public BinaryStream {
 public:
-  ~WritableStream() override = default;
+  ~WritableBinaryStream() override = default;
 
-  // 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;
+  /// \brief 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) = 0;
 
-  virtual Error commit() const = 0;
+  /// \brief For buffered streams, commits changes to the backing store.
+  virtual Error commit() = 0;
 };
 
-} // end namespace msf
 } // end namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H
+#endif // LLVM_SUPPORT_BINARYSTREAM_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamArray.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamArray.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamArray.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamArray.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamArray.h - Array backed by an arbitrary stream ------*- C++ -*-===//
+//===- BinaryStreamArray.h - Array backed by an arbitrary stream *- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_STREAMARRAY_H
-#define LLVM_DEBUGINFO_MSF_STREAMARRAY_H
+#ifndef LLVM_SUPPORT_BINARYSTREAMARRAY_H
+#define LLVM_SUPPORT_BINARYSTREAMARRAY_H
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/iterator.h"
@@ -17,11 +17,20 @@
 #include <cassert>
 #include <cstdint>
 
+/// Lightweight arrays that are backed by an arbitrary BinaryStream.  This file
+/// provides two different array implementations.
+///
+///     VarStreamArray - Arrays of variable length records.  The user specifies
+///       an Extractor type that can extract a record from a given offset and
+///       return the number of bytes consumed by the record.
+///
+///     FixedStreamArray - Arrays of fixed length records.  This is similar in
+///       spirit to ArrayRef<T>, but since it is backed by a BinaryStream, the
+///       elements of the array need not be laid out in contiguous memory.
 namespace llvm {
-namespace msf {
 
 /// VarStreamArrayExtractor is intended to be specialized to provide customized
-/// extraction logic.  On input it receives a StreamRef pointing to the
+/// extraction logic.  On input it receives a BinaryStreamRef pointing to the
 /// beginning of the next record, but where the length of the record is not yet
 /// known.  Upon completion, it should return an appropriate Error instance if
 /// a record could not be extracted, or if one could be extracted it should
@@ -35,7 +44,7 @@ namespace msf {
 template <typename T> struct VarStreamArrayExtractor {
   // Method intentionally deleted.  You must provide an explicit specialization
   // with the following method implemented.
-  Error operator()(ReadableStreamRef Stream, uint32_t &Len,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
                    T &Item) const = delete;
 };
 
@@ -49,10 +58,10 @@ template <typename T> struct VarStreamAr
 /// abstracting this out, we need not duplicate this memory, and we can
 /// iterate over arrays in arbitrarily formatted streams.  Elements are parsed
 /// lazily on iteration, so there is no upfront cost associated with building
-/// a VarStreamArray, no matter how large it may be.
+/// or copying a VarStreamArray, no matter how large it may be.
 ///
 /// You create a VarStreamArray by specifying a ValueType and an Extractor type.
-/// If you do not specify an Extractor type, it expects you to specialize
+/// If you do not specify an Extractor type, you are expected to specialize
 /// VarStreamArrayExtractor<T> for your ValueType.
 ///
 /// By default an Extractor is default constructed in the class, but in some
@@ -86,8 +95,8 @@ public:
   VarStreamArray() = default;
   explicit VarStreamArray(const Extractor &E) : E(E) {}
 
-  explicit VarStreamArray(ReadableStreamRef Stream) : Stream(Stream) {}
-  VarStreamArray(ReadableStreamRef Stream, const Extractor &E)
+  explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
+  VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
       : Stream(Stream), E(E) {}
 
   VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
@@ -101,10 +110,10 @@ public:
 
   const Extractor &getExtractor() const { return E; }
 
-  ReadableStreamRef getUnderlyingStream() const { return Stream; }
+  BinaryStreamRef getUnderlyingStream() const { return Stream; }
 
 private:
-  ReadableStreamRef Stream;
+  BinaryStreamRef Stream;
   Extractor E;
 };
 
@@ -153,23 +162,25 @@ public:
     return ThisValue;
   }
 
-  IterType &operator++() {
-    // We are done with the current record, discard it so that we are
-    // positioned at the next record.
-    IterRef = IterRef.drop_front(ThisLen);
-    if (IterRef.getLength() == 0) {
-      // There is nothing after the current record, we must make this an end
-      // iterator.
-      moveToEnd();
-    } else {
-      // There is some data after the current record.
-      auto EC = Extract(IterRef, ThisLen, ThisValue);
-      if (EC) {
-        consumeError(std::move(EC));
-        markError();
-      } else if (ThisLen == 0) {
-        // An empty record? Make this an end iterator.
+  IterType &operator+=(unsigned N) {
+    for (unsigned I = 0; I < N; ++I) {
+      // We are done with the current record, discard it so that we are
+      // positioned at the next record.
+      IterRef = IterRef.drop_front(ThisLen);
+      if (IterRef.getLength() == 0) {
+        // There is nothing after the current record, we must make this an end
+        // iterator.
         moveToEnd();
+      } else {
+        // There is some data after the current record.
+        auto EC = Extract(IterRef, ThisLen, ThisValue);
+        if (EC) {
+          consumeError(std::move(EC));
+          markError();
+        } else if (ThisLen == 0) {
+          // An empty record? Make this an end iterator.
+          moveToEnd();
+        }
       }
     }
     return *this;
@@ -188,7 +199,7 @@ private:
   }
 
   ValueType ThisValue;
-  ReadableStreamRef IterRef;
+  BinaryStreamRef IterRef;
   const ArrayType *Array{nullptr};
   uint32_t ThisLen{0};
   bool HasError{false};
@@ -198,12 +209,17 @@ private:
 
 template <typename T> class FixedStreamArrayIterator;
 
+/// FixedStreamArray is similar to VarStreamArray, except with each record
+/// having a fixed-length.  As with VarStreamArray, there is no upfront
+/// cost associated with building or copying a FixedStreamArray, as the
+/// memory for each element is not read from the backing stream until that
+/// element is iterated.
 template <typename T> class FixedStreamArray {
   friend class FixedStreamArrayIterator<T>;
 
 public:
   FixedStreamArray() = default;
-  FixedStreamArray(ReadableStreamRef Stream) : Stream(Stream) {
+  explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
     assert(Stream.getLength() % sizeof(T) == 0);
   }
 
@@ -242,10 +258,10 @@ public:
     return FixedStreamArrayIterator<T>(*this, size());
   }
 
-  ReadableStreamRef getUnderlyingStream() const { return Stream; }
+  BinaryStreamRef getUnderlyingStream() const { return Stream; }
 
 private:
-  ReadableStreamRef Stream;
+  BinaryStreamRef Stream;
 };
 
 template <typename T>
@@ -298,7 +314,6 @@ private:
   uint32_t Index;
 };
 
-} // namespace msf
 } // namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_STREAMARRAY_H
+#endif // LLVM_SUPPORT_BINARYSTREAMARRAY_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamReader.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamReader.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamReader.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamReader.h - Reads bytes and objects from a stream ---*- C++ -*-===//
+//===- BinaryStreamReader.h - Reads objects from a binary stream *- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,71 +7,166 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_STREAMREADER_H
-#define LLVM_DEBUGINFO_MSF_STREAMREADER_H
+#ifndef LLVM_SUPPORT_BINARYSTREAMREADER_H
+#define LLVM_SUPPORT_BINARYSTREAMREADER_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/type_traits.h"
 
 #include <string>
 #include <type_traits>
 
 namespace llvm {
-namespace msf {
 
-class StreamReader {
+/// \brief Provides read only access to a subclass of `BinaryStream`.  Provides
+/// bounds checking and helpers for writing certain common data types such as
+/// null-terminated strings, integers in various flavors of endianness, etc.
+/// Can be subclassed to provide reading of custom datatypes, although no
+/// are overridable.
+class BinaryStreamReader {
 public:
-  StreamReader(ReadableStreamRef Stream);
+  explicit BinaryStreamReader(BinaryStreamRef Stream);
+  virtual ~BinaryStreamReader() {}
 
+  /// Read as much as possible from the underlying string at the current offset
+  /// without invoking a copy, and set \p Buffer to the resulting data slice.
+  /// Updates the stream's offset to point after the newly read data.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
+
+  /// Read \p Size bytes from the underlying stream at the current offset and
+  /// and set \p Buffer to the resulting data slice.  Whether a copy occurs
+  /// depends on the implementation of the underlying stream.  Updates the
+  /// stream's offset to point after the newly read data.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
 
-  template <typename T>
-  Error readInteger(T &Dest,
-                    llvm::support::endianness Endian = llvm::support::native) {
+  /// Read an integer of the specified endianness into \p Dest and update the
+  /// stream's offset.  The data is always copied from the stream's underlying
+  /// buffer into \p Dest. Updates the stream's offset to point after the newly
+  /// read data.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  template <typename T> Error readInteger(T &Dest) {
     static_assert(std::is_integral<T>::value,
                   "Cannot call readInteger with non-integral value!");
 
     ArrayRef<uint8_t> Bytes;
     if (auto EC = readBytes(Bytes, sizeof(T)))
       return EC;
+    readIntegersImpl(Bytes, Dest);
+    return Error::success();
+  }
 
-    Dest = llvm::support::endian::read<T, llvm::support::unaligned>(
-        Bytes.data(), Endian);
+  /// Read a list of integers into \p Dest and update the stream's offset.
+  /// The data is always copied from the stream's underlying into \p Dest.
+  /// Updates the stream's offset to point after the newly read data.  Use of
+  /// this method is more efficient than calling `readInteger` multiple times
+  /// because this performs bounds checking only once, and requires only a
+  /// single error check by the user.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  template <typename... Ts> Error readIntegers(Ts &... Dest) {
+    const size_t Size = sizeof_sum<Ts...>::value;
+    ArrayRef<uint8_t> Bytes;
+    if (auto EC = readBytes(Bytes, Size))
+      return EC;
+    readIntegersImpl(Bytes, Dest...);
     return Error::success();
   }
 
-  Error readZeroString(StringRef &Dest);
-  Error readFixedString(StringRef &Dest, uint32_t Length);
-  Error readStreamRef(ReadableStreamRef &Ref);
-  Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length);
+  /// Read a \p ByteSize byte integer and store the result in \p Dest, updating
+  /// the reader's position if successful.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  Error readInteger(uint64_t &Dest, uint32_t ByteSize);
 
-  template <typename T>
-  Error readEnum(T &Dest,
-                 llvm::support::endianness Endian = llvm::support::native) {
+  /// Similar to readInteger.
+  template <typename T> Error readEnum(T &Dest) {
     static_assert(std::is_enum<T>::value,
                   "Cannot call readEnum with non-enum value!");
     typename std::underlying_type<T>::type N;
-    if (auto EC = readInteger(N, Endian))
+    if (auto EC = readInteger(N))
       return EC;
     Dest = static_cast<T>(N);
     return Error::success();
   }
 
+  /// Read a null terminated string from \p Dest.  Whether a copy occurs depends
+  /// on the implementation of the underlying stream.  Updates the stream's
+  /// offset to point after the newly read data.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  Error readCString(StringRef &Dest);
+
+  /// Read a \p Length byte string into \p Dest.  Whether a copy occurs depends
+  /// on the implementation of the underlying stream.  Updates the stream's
+  /// offset to point after the newly read data.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  Error readFixedString(StringRef &Dest, uint32_t Length);
+
+  /// Read the entire remainder of the underlying stream into \p Ref.  This is
+  /// equivalent to calling getUnderlyingStream().slice(Offset).  Updates the
+  /// stream's offset to point to the end of the stream.  Never causes a copy.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  Error readStreamRef(BinaryStreamRef &Ref);
+
+  /// Read \p Length bytes from the underlying stream into \p Ref.  This is
+  /// equivalent to calling getUnderlyingStream().slice(Offset, Length).
+  /// Updates the stream's offset to point after the newly read object.  Never
+  /// causes a copy.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
+  Error readStreamRef(BinaryStreamRef &Ref, uint32_t Length);
+
+  /// Get a pointer to an object of type T from the underlying stream, as if by
+  /// memcpy, and store the result into \p Dest.  It is up to the caller to
+  /// ensure that objects of type T can be safely treated in this manner.
+  /// Updates the stream's offset to point after the newly read object.  Whether
+  /// a copy occurs depends upon the implementation of the underlying
+  /// stream.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   template <typename T> Error readObject(const T *&Dest) {
     ArrayRef<uint8_t> Buffer;
     if (auto EC = readBytes(Buffer, sizeof(T)))
       return EC;
+    assert(alignmentAdjustment(Buffer.data(), alignof(T)) == 0 &&
+           "Reading at invalid alignment!");
     Dest = reinterpret_cast<const T *>(Buffer.data());
     return Error::success();
   }
 
+  /// Get a reference to a \p NumElements element array of objects of type T
+  /// from the underlying stream as if by memcpy, and store the resulting array
+  /// slice into \p array.  It is up to the caller to ensure that objects of
+  /// type T can be safely treated in this manner.  Updates the stream's offset
+  /// to point after the newly read object.  Whether a copy occurs depends upon
+  /// the implementation of the underlying stream.
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   template <typename T>
   Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
     ArrayRef<uint8_t> Bytes;
@@ -81,23 +176,43 @@ public:
     }
 
     if (NumElements > UINT32_MAX / sizeof(T))
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
 
     if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
       return EC;
+
+    assert(alignmentAdjustment(Bytes.data(), alignof(T)) == 0 &&
+           "Reading at invalid alignment!");
+
     Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
     return Error::success();
   }
 
+  /// Read a VarStreamArray of size \p Size bytes and store the result into
+  /// \p Array.  Updates the stream's offset to point after the newly read
+  /// array.  Never causes a copy (although iterating the elements of the
+  /// VarStreamArray may, depending upon the implementation of the underlying
+  /// stream).
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   template <typename T, typename U>
   Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
-    ReadableStreamRef S;
+    BinaryStreamRef S;
     if (auto EC = readStreamRef(S, Size))
       return EC;
     Array = VarStreamArray<T, U>(S, Array.getExtractor());
     return Error::success();
   }
 
+  /// Read a FixedStreamArray of \p NumItems elements and store the result into
+  /// \p Array.  Updates the stream's offset to point after the newly read
+  /// array.  Never causes a copy (although iterating the elements of the
+  /// FixedStreamArray may, depending upon the implementation of the underlying
+  /// stream).
+  ///
+  /// \returns a success error code if the data was successfully read, otherwise
+  /// returns an appropriate error code.
   template <typename T>
   Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
     if (NumItems == 0) {
@@ -106,10 +221,11 @@ public:
     }
     uint32_t Length = NumItems * sizeof(T);
     if (Length / sizeof(T) != NumItems)
-      return make_error<MSFError>(msf_error_code::invalid_format);
+      return errorCodeToError(
+          make_error_code(std::errc::illegal_byte_sequence));
     if (Offset + Length > Stream.getLength())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
-    ReadableStreamRef View = Stream.slice(Offset, Length);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+    BinaryStreamRef View = Stream.slice(Offset, Length);
     Array = FixedStreamArray<T>(View);
     Offset += Length;
     return Error::success();
@@ -121,15 +237,36 @@ public:
   uint32_t getLength() const { return Stream.getLength(); }
   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
 
+  /// Advance the stream's offset by \p Amount bytes.
+  ///
+  /// \returns a success error code if at least \p Amount bytes remain in the
+  /// stream, otherwise returns an appropriate error code.
   Error skip(uint32_t Amount);
 
+  /// Examine the next byte of the underlying stream without advancing the
+  /// stream's offset.  If the stream is empty the behavior is undefined.
+  ///
+  /// \returns the next byte in the stream.
   uint8_t peek() const;
 
 private:
-  ReadableStreamRef Stream;
+  template <typename T>
+  void readIntegersImpl(ArrayRef<uint8_t> Bytes, T &Dest) {
+    Dest = llvm::support::endian::read<T, llvm::support::unaligned>(
+        Bytes.data(), Stream.getEndian());
+  }
+
+  template <typename T, typename... Ts>
+  void readIntegersImpl(ArrayRef<uint8_t> Bytes, T &Dest, Ts &... Rest) {
+    auto Car = Bytes.take_front(sizeof(T));
+    auto Cdr = Bytes.drop_front(sizeof(T));
+    readIntegersImpl(Car, Dest);
+    readIntegersImpl(Cdr, Rest...);
+  }
+
+  BinaryStreamRef Stream;
   uint32_t Offset;
 };
-} // namespace msf
 } // namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_STREAMREADER_H
+#endif // LLVM_SUPPORT_BINARYSTREAMREADER_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamRef.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamRef.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamRef.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamRef.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamRef.h - A copyable reference to a stream -----------*- C++ -*-===//
+//===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,28 +7,30 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_STREAMREF_H
-#define LLVM_DEBUGINFO_MSF_STREAMREF_H
+#ifndef LLVM_SUPPORT_BINARYSTREAMREF_H
+#define LLVM_SUPPORT_BINARYSTREAMREF_H
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 #include "llvm/Support/Error.h"
 #include <algorithm>
 #include <cstdint>
 
 namespace llvm {
-namespace msf {
 
-template <class StreamType, class RefType> class StreamRefBase {
+/// Common stuff for mutable and immutable StreamRefs.
+template <class StreamType, class RefType> class BinaryStreamRefBase {
 public:
-  StreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
-  StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)
+  BinaryStreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
+  BinaryStreamRefBase(StreamType &Stream, uint32_t Offset, uint32_t Length)
       : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
 
+  llvm::support::endianness getEndian() const { return Stream->getEndian(); }
+
   uint32_t getLength() const { return Length; }
   const StreamType *getStream() const { return Stream; }
 
+  /// Return a new BinaryStreamRef with the first \p N elements removed.
   RefType drop_front(uint32_t N) const {
     if (!Stream)
       return RefType();
@@ -37,6 +39,7 @@ public:
     return RefType(*Stream, ViewOffset + N, Length - N);
   }
 
+  /// Return a new BinaryStreamRef with only the first \p N elements remaining.
   RefType keep_front(uint32_t N) const {
     if (!Stream)
       return RefType();
@@ -44,6 +47,8 @@ public:
     return RefType(*Stream, ViewOffset, N);
   }
 
+  /// Return a new BinaryStreamRef with the first \p Offset elements removed,
+  /// and retaining exactly \p Len elements.
   RefType slice(uint32_t Offset, uint32_t Len) const {
     return drop_front(Offset).keep_front(Len);
   }
@@ -59,40 +64,55 @@ public:
   }
 
 protected:
-  const StreamType *Stream;
+  StreamType *Stream;
   uint32_t ViewOffset;
   uint32_t Length;
 };
 
-class ReadableStreamRef
-    : public StreamRefBase<ReadableStream, ReadableStreamRef> {
+/// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.  It
+/// provides copy-semantics and read only access to a "window" of the underlying
+/// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream.  That is to
+/// say, it does not inherit and override the methods of BinaryStream.  In
+/// general, you should not pass around pointers or references to BinaryStreams
+/// and use inheritance to achieve polymorphism.  Instead, you should pass
+/// around BinaryStreamRefs by value and achieve polymorphism that way.
+class BinaryStreamRef
+    : public BinaryStreamRefBase<BinaryStream, BinaryStreamRef> {
 public:
-  ReadableStreamRef() = default;
-  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.
-  ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,
-                    uint32_t Length) = delete;
-
+  BinaryStreamRef() = default;
+  BinaryStreamRef(BinaryStream &Stream)
+      : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
+  BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length)
+      : BinaryStreamRefBase(Stream, Offset, Length) {}
+
+  // Use BinaryStreamRef.slice() instead.
+  BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
+                  uint32_t Length) = delete;
+
+  /// Given an Offset into this StreamRef and a Size, return a reference to a
+  /// buffer owned by the stream.
+  ///
+  /// \returns a success error code if the entire range of data is within the
+  /// bounds of this BinaryStreamRef's view and the implementation could read
+  /// the data, and an appropriate error code otherwise.
   Error readBytes(uint32_t Offset, uint32_t Size,
                   ArrayRef<uint8_t> &Buffer) const {
     if (ViewOffset + Offset < Offset)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     if (Size + Offset > Length)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
   }
 
-  // Given an offset into the stream, read as much as possible without copying
-  // any data.
+  /// Given an Offset into this BinaryStreamRef, return a reference to the
+  /// largest buffer the stream could support without necessitating a copy.
+  ///
+  /// \returns a success error code if implementation could read the data,
+  /// and an appropriate error code otherwise.
   Error readLongestContiguousChunk(uint32_t Offset,
                                    ArrayRef<uint8_t> &Buffer) const {
     if (Offset >= Length)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
 
     if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
       return EC;
@@ -106,30 +126,39 @@ public:
   }
 };
 
-class WritableStreamRef
-    : public StreamRefBase<WritableStream, WritableStreamRef> {
+class WritableBinaryStreamRef
+    : public BinaryStreamRefBase<WritableBinaryStream,
+                                 WritableBinaryStreamRef> {
 public:
-  WritableStreamRef() = default;
-  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;
-
+  WritableBinaryStreamRef() = default;
+  WritableBinaryStreamRef(WritableBinaryStream &Stream)
+      : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
+  WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
+                          uint32_t Length)
+      : BinaryStreamRefBase(Stream, Offset, Length) {}
+
+  // Use WritableBinaryStreamRef.slice() instead.
+  WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,
+                          uint32_t Length) = delete;
+
+  /// Given an Offset into this WritableBinaryStreamRef and some input data,
+  /// writes the data to the underlying stream.
+  ///
+  /// \returns a success error code if the data could fit within the underlying
+  /// stream at the specified location and the implementation could write the
+  /// data, and an appropriate error code otherwise.
   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
     if (Data.size() + Offset > Length)
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     return Stream->writeBytes(ViewOffset + Offset, Data);
   }
 
-  Error commit() const { return Stream->commit(); }
+  operator BinaryStreamRef() { return BinaryStreamRef(*Stream); }
+
+  /// \brief For buffered streams, commits changes to the backing store.
+  Error commit() { return Stream->commit(); }
 };
 
-} // end namespace msf
 } // end namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_STREAMREF_H
+#endif // LLVM_SUPPORT_BINARYSTREAMREF_H

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamWriter.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamWriter.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/BinaryStreamWriter.h Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamWriter.h - Writes bytes and objects to a stream ----*- C++ -*-===//
+//===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,55 +7,121 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_DEBUGINFO_MSF_STREAMWRITER_H
-#define LLVM_DEBUGINFO_MSF_STREAMWRITER_H
+#ifndef LLVM_SUPPORT_BINARYSTREAMWRITER_H
+#define LLVM_SUPPORT_BINARYSTREAMWRITER_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
 #include <type_traits>
 
 namespace llvm {
-namespace msf {
 
-class StreamWriter {
+/// \brief Provides write only access to a subclass of `WritableBinaryStream`.
+/// Provides bounds checking and helpers for writing certain common data types
+/// such as null-terminated strings, integers in various flavors of endianness,
+/// etc.  Can be subclassed to provide reading and writing of custom datatypes,
+/// although no methods are overridable.
+class BinaryStreamWriter {
 public:
-  StreamWriter() = default;
-  explicit StreamWriter(WritableStreamRef Stream);
-
+  BinaryStreamWriter() = default;
+  explicit BinaryStreamWriter(WritableBinaryStreamRef Stream);
+  virtual ~BinaryStreamWriter() {}
+
+  /// Write the bytes specified in \p Buffer to the underlying stream.
+  /// On success, updates the offset so that subsequent writes will occur
+  /// at the next unwritten position.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
   Error writeBytes(ArrayRef<uint8_t> Buffer);
 
-  template <typename T>
-  Error writeInteger(T Value,
-                     llvm::support::endianness Endian = llvm::support::native) {
-    static_assert(std::is_integral<T>::value,
-                  "Cannot call writeInteger with non-integral value!");
-    uint8_t Buffer[sizeof(T)];
-    llvm::support::endian::write<T, llvm::support::unaligned>(Buffer, Value,
-                                                              Endian);
+  /// Write the the integer \p Value to the underlying stream in the
+  /// specified endianness.  On success, updates the offset so that
+  /// subsequent writes occur at the next unwritten position.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  template <typename T> Error writeInteger(T Value) {
+    return writeIntegers(Value);
+  }
+
+  /// Write a \p ByteSize byte integer to the stream, updating the writer's
+  /// position if successful.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  Error writeInteger(uint64_t Value, uint32_t ByteSize);
+
+  /// Write a list of integers into the underlying stream and update the
+  /// stream's offset. On success, updates the offset so that subsequent writes
+  /// occur at the next unwritten position.  Use of this method is more
+  /// efficient than calling `writeInteger` multiple times because this performs
+  /// bounds checking only once, and requires only a single error check by the
+  /// user.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  template <typename... Ts> Error writeIntegers(Ts... Ints) {
+    uint8_t Buffer[sizeof_sum<Ts...>::value];
+
+    writeIntegersImpl(Buffer, Ints...);
     return writeBytes(Buffer);
   }
 
-  Error writeZeroString(StringRef Str);
-  Error writeFixedString(StringRef Str);
-  Error writeStreamRef(ReadableStreamRef Ref);
-  Error writeStreamRef(ReadableStreamRef Ref, uint32_t Size);
-
-  template <typename T>
-  Error writeEnum(T Num,
-                  llvm::support::endianness Endian = llvm::support::native) {
+  /// Similar to writeInteger
+  template <typename T> Error writeEnum(T Num) {
     static_assert(std::is_enum<T>::value,
                   "Cannot call writeEnum with non-Enum type");
 
     using U = typename std::underlying_type<T>::type;
-    return writeInteger<U>(static_cast<U>(Num), Endian);
+    return writeInteger<U>(static_cast<U>(Num));
   }
 
+  /// Write the the string \p Str to the underlying stream followed by a null
+  /// terminator.  On success, updates the offset so that subsequent writes
+  /// occur at the next unwritten position.  \p Str need not be null terminated
+  /// on input.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  Error writeCString(StringRef Str);
+
+  /// Write the the string \p Str to the underlying stream without a null
+  /// terminator.  On success, updates the offset so that subsequent writes
+  /// occur at the next unwritten position.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  Error writeFixedString(StringRef Str);
+
+  /// Efficiently reads all data from \p Ref, and writes it to this stream.
+  /// This operation will not invoke any copies of the source data, regardless
+  /// of the source stream's implementation.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  Error writeStreamRef(BinaryStreamRef Ref);
+
+  /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
+  /// This operation will not invoke any copies of the source data, regardless
+  /// of the source stream's implementation.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
+  Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size);
+
+  /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
+  /// It is up to the caller to ensure that type of \p Obj can be safely copied
+  /// in this fashion, as no checks are made to ensure that this is safe.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
   template <typename T> Error writeObject(const T &Obj) {
     static_assert(!std::is_pointer<T>::value,
                   "writeObject should not be used with pointers, to write "
@@ -65,23 +131,38 @@ public:
         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
   }
 
+  /// Writes an array of objects of type T to the underlying stream, as if by
+  /// using memcpy.  It is up to the caller to ensure that type of \p Obj can
+  /// be safely copied in this fashion, as no checks are made to ensure that
+  /// this is safe.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
   template <typename T> Error writeArray(ArrayRef<T> Array) {
     if (Array.empty())
       return Error::success();
 
     if (Array.size() > UINT32_MAX / sizeof(T))
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
 
     return writeBytes(
         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
                           Array.size() * sizeof(T)));
   }
 
+  /// Writes all data from the array \p Array to the underlying stream.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
   template <typename T, typename U>
   Error writeArray(VarStreamArray<T, U> Array) {
     return writeStreamRef(Array.getUnderlyingStream());
   }
 
+  /// Writes all elements from the array \p Array to the underlying stream.
+  ///
+  /// \returns a success error code if the data was successfully written,
+  /// otherwise returns an appropriate error code.
   template <typename T> Error writeArray(FixedStreamArray<T> Array) {
     return writeStreamRef(Array.getUnderlyingStream());
   }
@@ -91,12 +172,28 @@ public:
   uint32_t getLength() const { return Stream.getLength(); }
   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
 
-private:
-  WritableStreamRef Stream;
+protected:
+  template <typename T>
+  void writeIntegersImpl(MutableArrayRef<uint8_t> Buffer, T Value) {
+    static_assert(std::is_integral<T>::value,
+                  "Cannot call writeInteger with non-integral value!");
+    assert(Buffer.size() == sizeof(T));
+    llvm::support::endian::write<T, llvm::support::unaligned>(
+        Buffer.data(), Value, Stream.getEndian());
+  }
+
+  template <typename T, typename... Ts>
+  void writeIntegersImpl(MutableArrayRef<uint8_t> Buffer, T Car, Ts... Cdr) {
+    auto First = Buffer.take_front(sizeof(T));
+    auto Rest = Buffer.drop_front(sizeof(T));
+    writeIntegersImpl(First, Car);
+    writeIntegersImpl(Rest, Cdr...);
+  }
+
+  WritableBinaryStreamRef Stream;
   uint32_t Offset = 0;
 };
 
-} // end namespace msf
 } // end namespace llvm
 
-#endif // LLVM_DEBUGINFO_MSF_STREAMWRITER_H
+#endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H

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=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/MappedBlockStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/MappedBlockStream.h Fri Feb 24 18:44:30 2017
@@ -15,6 +15,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
 #include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Endian.h"
@@ -37,29 +39,33 @@ struct MSFLayout;
 /// 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 ReadableStream {
+class MappedBlockStream : public BinaryStream {
   friend class WritableMappedBlockStream;
 public:
   static std::unique_ptr<MappedBlockStream>
   createStream(uint32_t BlockSize, uint32_t NumBlocks,
-               const MSFStreamLayout &Layout, const ReadableStream &MsfData);
+               const MSFStreamLayout &Layout, BinaryStreamRef MsfData);
 
   static std::unique_ptr<MappedBlockStream>
-  createIndexedStream(const MSFLayout &Layout, const ReadableStream &MsfData,
+  createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
                       uint32_t StreamIndex);
 
   static std::unique_ptr<MappedBlockStream>
-  createFpmStream(const MSFLayout &Layout, const ReadableStream &MsfData);
+  createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData);
 
   static std::unique_ptr<MappedBlockStream>
-  createDirectoryStream(const MSFLayout &Layout, const ReadableStream &MsfData);
+  createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData);
+
+  llvm::support::endianness getEndian() const override {
+    return llvm::support::little;
+  }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override;
+                  ArrayRef<uint8_t> &Buffer) override;
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override;
+                                   ArrayRef<uint8_t> &Buffer) override;
 
-  uint32_t getLength() const override;
+  uint32_t getLength() override;
 
   uint32_t getNumBytesCopied() const;
 
@@ -74,51 +80,56 @@ public:
 protected:
   MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
                     const MSFStreamLayout &StreamLayout,
-                    const ReadableStream &MsfData);
+                    BinaryStreamRef 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;
+  Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer);
   bool tryReadContiguously(uint32_t Offset, uint32_t Size,
-                           ArrayRef<uint8_t> &Buffer) const;
+                           ArrayRef<uint8_t> &Buffer);
 
   const uint32_t BlockSize;
   const uint32_t NumBlocks;
   const MSFStreamLayout StreamLayout;
-  const ReadableStream &MsfData;
+  BinaryStreamRef MsfData;
 
   typedef MutableArrayRef<uint8_t> CacheEntry;
-  mutable llvm::BumpPtrAllocator Pool;
-  mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
+  llvm::BumpPtrAllocator Pool;
+  DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
 };
 
-class WritableMappedBlockStream : public WritableStream {
+class WritableMappedBlockStream : public WritableBinaryStream {
 public:
   static std::unique_ptr<WritableMappedBlockStream>
   createStream(uint32_t BlockSize, uint32_t NumBlocks,
-               const MSFStreamLayout &Layout, const WritableStream &MsfData);
+               const MSFStreamLayout &Layout, WritableBinaryStreamRef MsfData);
 
   static std::unique_ptr<WritableMappedBlockStream>
-  createIndexedStream(const MSFLayout &Layout, const WritableStream &MsfData,
+  createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
                       uint32_t StreamIndex);
 
   static std::unique_ptr<WritableMappedBlockStream>
-  createDirectoryStream(const MSFLayout &Layout, const WritableStream &MsfData);
+  createDirectoryStream(const MSFLayout &Layout,
+                        WritableBinaryStreamRef MsfData);
 
   static std::unique_ptr<WritableMappedBlockStream>
-  createFpmStream(const MSFLayout &Layout, const WritableStream &MsfData);
+  createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData);
+
+  llvm::support::endianness getEndian() const override {
+    return llvm::support::little;
+  }
 
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override;
+                  ArrayRef<uint8_t> &Buffer) override;
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override;
-  uint32_t getLength() const override;
+                                   ArrayRef<uint8_t> &Buffer) override;
+  uint32_t getLength() override;
 
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override;
 
-  Error commit() const override;
+  Error commit() override;
 
   const MSFStreamLayout &getStreamLayout() const {
     return ReadInterface.getStreamLayout();
@@ -130,12 +141,12 @@ public:
 protected:
   WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
                             const MSFStreamLayout &StreamLayout,
-                            const WritableStream &MsfData);
+                            WritableBinaryStreamRef MsfData);
 
 private:
   MappedBlockStream ReadInterface;
 
-  const WritableStream &WriteInterface;
+  WritableBinaryStreamRef WriteInterface;
 };
 
 } // end namespace pdb

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h Fri Feb 24 18:44:30 2017
@@ -12,6 +12,8 @@
 
 #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/ModInfo.h"
@@ -70,11 +72,11 @@ public:
 
   Expected<StringRef> getFileNameForIndex(uint32_t Index) const;
 
-  msf::FixedStreamArray<object::coff_section> getSectionHeaders();
+  FixedStreamArray<object::coff_section> getSectionHeaders();
 
-  msf::FixedStreamArray<object::FpoData> getFpoRecords();
+  FixedStreamArray<object::FpoData> getFpoRecords();
 
-  msf::FixedStreamArray<SecMapEntry> getSectionMap() const;
+  FixedStreamArray<SecMapEntry> getSectionMap() const;
   void visitSectionContributions(ISectionContribVisitor &Visitor) const;
 
 private:
@@ -91,28 +93,28 @@ private:
   std::vector<ModuleInfoEx> ModuleInfos;
   StringTable ECNames;
 
-  msf::ReadableStreamRef ModInfoSubstream;
-  msf::ReadableStreamRef SecContrSubstream;
-  msf::ReadableStreamRef SecMapSubstream;
-  msf::ReadableStreamRef FileInfoSubstream;
-  msf::ReadableStreamRef TypeServerMapSubstream;
-  msf::ReadableStreamRef ECSubstream;
+  BinaryStreamRef ModInfoSubstream;
+  BinaryStreamRef SecContrSubstream;
+  BinaryStreamRef SecMapSubstream;
+  BinaryStreamRef FileInfoSubstream;
+  BinaryStreamRef TypeServerMapSubstream;
+  BinaryStreamRef ECSubstream;
 
-  msf::ReadableStreamRef NamesBuffer;
+  BinaryStreamRef NamesBuffer;
 
-  msf::FixedStreamArray<support::ulittle16_t> DbgStreams;
+  FixedStreamArray<support::ulittle16_t> DbgStreams;
 
   PdbRaw_DbiSecContribVer SectionContribVersion;
-  msf::FixedStreamArray<SectionContrib> SectionContribs;
-  msf::FixedStreamArray<SectionContrib2> SectionContribs2;
-  msf::FixedStreamArray<SecMapEntry> SectionMap;
-  msf::FixedStreamArray<support::little32_t> FileNameOffsets;
+  FixedStreamArray<SectionContrib> SectionContribs;
+  FixedStreamArray<SectionContrib2> SectionContribs2;
+  FixedStreamArray<SecMapEntry> SectionMap;
+  FixedStreamArray<support::little32_t> FileNameOffsets;
 
   std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream;
-  msf::FixedStreamArray<object::coff_section> SectionHeaders;
+  FixedStreamArray<object::coff_section> SectionHeaders;
 
   std::unique_ptr<msf::MappedBlockStream> FpoStream;
-  msf::FixedStreamArray<object::FpoData> FpoRecords;
+  FixedStreamArray<object::FpoData> FpoRecords;
 
   const DbiStreamHeader *Header;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h Fri Feb 24 18:44:30 2017
@@ -60,7 +60,7 @@ public:
 
   Error finalizeMsfLayout();
 
-  Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer);
+  Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
 
   // A helper function to create Section Contributions from COFF input
   // section headers.
@@ -112,9 +112,9 @@ private:
 
   StringMap<uint32_t> SourceFileNames;
 
-  msf::WritableStreamRef NamesBuffer;
-  msf::MutableByteStream ModInfoBuffer;
-  msf::MutableByteStream FileInfoBuffer;
+  WritableBinaryStreamRef NamesBuffer;
+  MutableBinaryByteStream ModInfoBuffer;
+  MutableBinaryByteStream FileInfoBuffer;
   ArrayRef<SectionContrib> SectionContribs;
   ArrayRef<SecMapEntry> SectionMap;
   llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h Fri Feb 24 18:44:30 2017
@@ -11,6 +11,7 @@
 #define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
 
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
@@ -27,15 +28,15 @@ public:
   explicit GlobalsStream(std::unique_ptr<msf::MappedBlockStream> Stream);
   ~GlobalsStream();
   Error commit();
-  msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
+  FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
     return HashBuckets;
   }
   uint32_t getNumBuckets() const { return NumBuckets; }
   Error reload();
 
 private:
-  msf::FixedStreamArray<support::ulittle32_t> HashBuckets;
-  msf::FixedStreamArray<PSHashRecord> HashRecords;
+  FixedStreamArray<support::ulittle32_t> HashBuckets;
+  FixedStreamArray<PSHashRecord> HashRecords;
   uint32_t NumBuckets;
   std::unique_ptr<msf::MappedBlockStream> Stream;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h Fri Feb 24 18:44:30 2017
@@ -42,10 +42,10 @@ public:
   HashTable();
   explicit HashTable(uint32_t Capacity);
 
-  Error load(msf::StreamReader &Stream);
+  Error load(BinaryStreamReader &Stream);
 
   uint32_t calculateSerializedLength() const;
-  Error commit(msf::StreamWriter &Writer) const;
+  Error commit(BinaryStreamWriter &Writer) const;
 
   void clear();
 
@@ -71,9 +71,9 @@ private:
   static uint32_t maxLoad(uint32_t capacity);
   void grow();
 
-  static Error readSparseBitVector(msf::StreamReader &Stream,
+  static Error readSparseBitVector(BinaryStreamReader &Stream,
                                    SparseBitVector<> &V);
-  static Error writeSparseBitVector(msf::StreamWriter &Writer,
+  static Error writeSparseBitVector(BinaryStreamWriter &Writer,
                                     SparseBitVector<> &Vec);
 };
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h Fri Feb 24 18:44:30 2017
@@ -19,9 +19,10 @@
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 
 namespace llvm {
+class WritableBinaryStream;
+
 namespace msf {
 class MSFBuilder;
-class StreamWriter;
 }
 namespace pdb {
 class PDBFile;
@@ -43,7 +44,7 @@ public:
   Error finalizeMsfLayout();
 
   Error commit(const msf::MSFLayout &Layout,
-               const msf::WritableStream &Buffer) const;
+               WritableBinaryStreamRef Buffer) const;
 
 private:
   msf::MSFBuilder &Msf;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModInfo.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModInfo.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModInfo.h Fri Feb 24 18:44:30 2017
@@ -30,7 +30,7 @@ public:
   ModInfo(const ModInfo &Info);
   ~ModInfo();
 
-  static Error initialize(msf::ReadableStreamRef Stream, ModInfo &Info);
+  static Error initialize(BinaryStreamRef Stream, ModInfo &Info);
 
   bool hasECInfo() const;
   uint16_t getTypeServerIndex() const;
@@ -63,10 +63,8 @@ struct ModuleInfoEx {
 
 } // end namespace pdb
 
-namespace msf {
-
 template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
-  Error operator()(ReadableStreamRef Stream, uint32_t &Length,
+  Error operator()(BinaryStreamRef Stream, uint32_t &Length,
                    pdb::ModInfo &Info) const {
     if (auto EC = pdb::ModInfo::initialize(Stream, Info))
       return EC;
@@ -75,8 +73,6 @@ template <> struct VarStreamArrayExtract
   }
 };
 
-} // end namespace msf
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModStream.h Fri Feb 24 18:44:30 2017
@@ -50,9 +50,9 @@ private:
   std::unique_ptr<msf::MappedBlockStream> Stream;
 
   codeview::CVSymbolArray SymbolsSubstream;
-  msf::ReadableStreamRef LinesSubstream;
-  msf::ReadableStreamRef C13LinesSubstream;
-  msf::ReadableStreamRef GlobalRefsSubstream;
+  BinaryStreamRef LinesSubstream;
+  BinaryStreamRef C13LinesSubstream;
+  BinaryStreamRef GlobalRefsSubstream;
 
   codeview::ModuleSubstreamArray LineInfo;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h Fri Feb 24 18:44:30 2017
@@ -17,10 +17,9 @@
 #include <cstdint>
 
 namespace llvm {
-namespace msf {
-class StreamReader;
-class StreamWriter;
-}
+class BinaryStreamReader;
+class BinaryStreamWriter;
+
 namespace pdb {
 class NamedStreamMapBuilder;
 class NamedStreamMap {
@@ -33,8 +32,8 @@ class NamedStreamMap {
 public:
   NamedStreamMap();
 
-  Error load(msf::StreamReader &Stream);
-  Error commit(msf::StreamWriter &Writer) const;
+  Error load(BinaryStreamReader &Stream);
+  Error commit(BinaryStreamWriter &Writer) const;
   uint32_t finalize();
 
   bool get(StringRef Stream, uint32_t &StreamNo) const;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFile.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFile.h Fri Feb 24 18:44:30 2017
@@ -12,6 +12,8 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/IMSFFile.h"
 #include "llvm/DebugInfo/MSF/MSFCommon.h"
@@ -42,7 +44,7 @@ class PDBFile : public msf::IMSFFile {
   friend PDBFileBuilder;
 
 public:
-  PDBFile(StringRef Path, std::unique_ptr<msf::ReadableStream> PdbFileBuffer,
+  PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
           BumpPtrAllocator &Allocator);
   ~PDBFile() override;
 
@@ -80,7 +82,7 @@ public:
   }
 
   const msf::MSFLayout &getMsfLayout() const { return ContainerLayout; }
-  const msf::ReadableStream &getMsfBuffer() const { return *Buffer; }
+  BinaryStreamRef getMsfBuffer() const { return *Buffer; }
 
   ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
 
@@ -110,13 +112,13 @@ public:
 private:
   Expected<std::unique_ptr<msf::MappedBlockStream>>
   safelyCreateIndexedStream(const msf::MSFLayout &Layout,
-                            const msf::ReadableStream &MsfData,
+                            BinaryStreamRef MsfData,
                             uint32_t StreamIndex) const;
 
   std::string FilePath;
   BumpPtrAllocator &Allocator;
 
-  std::unique_ptr<msf::ReadableStream> Buffer;
+  std::unique_ptr<BinaryStream> Buffer;
 
   std::vector<uint32_t> FpmPages;
   msf::MSFLayout ContainerLayout;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PublicsStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PublicsStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PublicsStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PublicsStream.h Fri Feb 24 18:44:30 2017
@@ -17,6 +17,7 @@
 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/Support/Error.h"
 
 namespace llvm {
@@ -38,16 +39,16 @@ public:
   uint32_t getNumBuckets() const { return NumBuckets; }
   iterator_range<codeview::CVSymbolArray::Iterator>
   getSymbols(bool *HadError) const;
-  msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
+  FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
     return HashBuckets;
   }
-  msf::FixedStreamArray<support::ulittle32_t> getAddressMap() const {
+  FixedStreamArray<support::ulittle32_t> getAddressMap() const {
     return AddressMap;
   }
-  msf::FixedStreamArray<support::ulittle32_t> getThunkMap() const {
+  FixedStreamArray<support::ulittle32_t> getThunkMap() const {
     return ThunkMap;
   }
-  msf::FixedStreamArray<SectionOffset> getSectionOffsets() const {
+  FixedStreamArray<SectionOffset> getSectionOffsets() const {
     return SectionOffsets;
   }
 
@@ -59,11 +60,11 @@ private:
   std::unique_ptr<msf::MappedBlockStream> Stream;
   uint32_t NumBuckets = 0;
   ArrayRef<uint8_t> Bitmap;
-  msf::FixedStreamArray<PSHashRecord> HashRecords;
-  msf::FixedStreamArray<support::ulittle32_t> HashBuckets;
-  msf::FixedStreamArray<support::ulittle32_t> AddressMap;
-  msf::FixedStreamArray<support::ulittle32_t> ThunkMap;
-  msf::FixedStreamArray<SectionOffset> SectionOffsets;
+  FixedStreamArray<PSHashRecord> HashRecords;
+  FixedStreamArray<support::ulittle32_t> HashBuckets;
+  FixedStreamArray<support::ulittle32_t> AddressMap;
+  FixedStreamArray<support::ulittle32_t> ThunkMap;
+  FixedStreamArray<SectionOffset> SectionOffsets;
 
   const HeaderInfo *Header;
   const GSIHashHeader *HashHdr;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h Fri Feb 24 18:44:30 2017
@@ -20,16 +20,15 @@
 #include <vector>
 
 namespace llvm {
-namespace msf {
-class StreamReader;
-}
+class BinaryStreamReader;
+
 namespace pdb {
 
 class StringTable {
 public:
   StringTable();
 
-  Error load(msf::StreamReader &Stream);
+  Error load(BinaryStreamReader &Stream);
 
   uint32_t getNameCount() const { return NameCount; }
   uint32_t getHashVersion() const { return HashVersion; }
@@ -38,11 +37,11 @@ public:
   StringRef getStringForID(uint32_t ID) const;
   uint32_t getIDForString(StringRef Str) const;
 
-  msf::FixedStreamArray<support::ulittle32_t> name_ids() const;
+  FixedStreamArray<support::ulittle32_t> name_ids() const;
 
 private:
-  msf::ReadableStreamRef NamesBuffer;
-  msf::FixedStreamArray<support::ulittle32_t> IDs;
+  BinaryStreamRef NamesBuffer;
+  FixedStreamArray<support::ulittle32_t> IDs;
   uint32_t Signature;
   uint32_t HashVersion;
   uint32_t NameCount;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h Fri Feb 24 18:44:30 2017
@@ -20,9 +20,8 @@
 #include <vector>
 
 namespace llvm {
-namespace msf {
-class StreamWriter;
-}
+class BinaryStreamWriter;
+
 namespace pdb {
 
 class StringTableBuilder {
@@ -32,7 +31,7 @@ public:
   uint32_t insert(StringRef S);
 
   uint32_t finalize();
-  Error commit(msf::StreamWriter &Writer) const;
+  Error commit(BinaryStreamWriter &Writer) const;
 
 private:
   DenseMap<StringRef, uint32_t> Strings;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiHashing.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiHashing.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiHashing.h Fri Feb 24 18:44:30 2017
@@ -57,7 +57,7 @@ private:
 
 class TpiHashVerifier : public codeview::TypeVisitorCallbacks {
 public:
-  TpiHashVerifier(msf::FixedStreamArray<support::ulittle32_t> &HashValues,
+  TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                   uint32_t NumHashBuckets)
       : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
 
@@ -83,7 +83,7 @@ private:
             utohexstr(codeview::TypeIndex::FirstNonSimpleIndex + Index));
   }
 
-  msf::FixedStreamArray<support::ulittle32_t> HashValues;
+  FixedStreamArray<support::ulittle32_t> HashValues;
   codeview::CVType RawRecord;
   uint32_t NumHashBuckets;
   uint32_t Index = -1;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h Fri Feb 24 18:44:30 2017
@@ -46,8 +46,8 @@ public:
 
   uint32_t getHashKeySize() const;
   uint32_t NumHashBuckets() const;
-  msf::FixedStreamArray<support::ulittle32_t> getHashValues() const;
-  msf::FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
+  FixedStreamArray<support::ulittle32_t> getHashValues() const;
+  FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
   HashTable &getHashAdjusters();
 
   codeview::CVTypeRange types(bool *HadError) const;
@@ -62,9 +62,9 @@ private:
 
   codeview::CVTypeArray TypeRecords;
 
-  std::unique_ptr<msf::ReadableStream> HashStream;
-  msf::FixedStreamArray<support::ulittle32_t> HashValues;
-  msf::FixedStreamArray<TypeIndexOffset> TypeIndexOffsets;
+  std::unique_ptr<BinaryStream> HashStream;
+  FixedStreamArray<support::ulittle32_t> HashValues;
+  FixedStreamArray<TypeIndexOffset> TypeIndexOffsets;
   HashTable HashAdjusters;
 
   const TpiStreamHeader *Header;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h Fri Feb 24 18:44:30 2017
@@ -21,22 +21,22 @@
 #include <vector>
 
 namespace llvm {
-namespace codeview {
-class TypeRecord;
-}
-namespace msf {
-class ByteStream;
-class MSFBuilder;
-struct MSFLayout;
-class ReadableStreamRef;
-class WritableStream;
+class BinaryStreamRef;
+class WritableBinaryStream;
 
-template <> struct SequencedItemTraits<llvm::codeview::CVType> {
+template <> struct BinaryItemTraits<llvm::codeview::CVType> {
   static size_t length(const codeview::CVType &Item) { return Item.length(); }
   static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
     return Item.data();
   }
 };
+
+namespace codeview {
+class TypeRecord;
+}
+namespace msf {
+class MSFBuilder;
+struct MSFLayout;
 }
 namespace pdb {
 class PDBFile;
@@ -56,9 +56,9 @@ public:
 
   Error finalizeMsfLayout();
 
-  Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer);
+  Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
 
-  uint32_t calculateSerializedLength() const;
+  uint32_t calculateSerializedLength();
 
 private:
   uint32_t calculateHashBufferSize() const;
@@ -69,9 +69,9 @@ private:
 
   Optional<PdbRaw_TpiVer> VerHeader;
   std::vector<codeview::CVType> TypeRecords;
-  msf::SequencedItemStream<codeview::CVType> TypeRecordStream;
+  BinaryItemStream<codeview::CVType> TypeRecordStream;
   uint32_t HashStreamIndex = kInvalidStreamIndex;
-  std::unique_ptr<msf::ByteStream> HashValueStream;
+  std::unique_ptr<BinaryByteStream> HashValueStream;
 
   const TpiStreamHeader *Header;
   uint32_t Idx;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Feb 24 18:44:30 2017
@@ -38,7 +38,6 @@
 
 using namespace llvm;
 using namespace llvm::codeview;
-using namespace llvm::msf;
 
 CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
     : DebugHandlerBase(AP), OS(*Asm->OutStreamer), Allocator(),
@@ -495,9 +494,9 @@ 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);
+      BinaryByteStream Stream(Record, llvm::support::little);
       CVTypeArray Types;
-      StreamReader Reader(Stream);
+      BinaryStreamReader Reader(Stream);
       Error E = Reader.readArray(Types, Reader.getLength());
       if (!E) {
         TypeVisitorCallbacks C;

Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp Fri Feb 24 18:44:30 2017
@@ -56,9 +56,9 @@ Error CVTypeDumper::dump(const CVTypeArr
 }
 
 Error CVTypeDumper::dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper) {
-  msf::ByteStream Stream(Data);
+  BinaryByteStream Stream(Data, llvm::support::little);
   CVTypeArray Types;
-  msf::StreamReader Reader(Stream);
+  BinaryStreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Types, Reader.getLength()))
     return EC;
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp Fri Feb 24 18:44:30 2017
@@ -174,7 +174,7 @@ Error CVTypeVisitor::visitTypeStream(CVT
   return Error::success();
 }
 
-Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) {
+Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader Reader) {
   FieldListDeserializer Deserializer(Reader);
   TypeVisitorCallbackPipeline Pipeline;
   Pipeline.addCallbackToPipeline(Deserializer);
@@ -182,7 +182,7 @@ Error CVTypeVisitor::visitFieldListMembe
 
   TypeLeafKind Leaf;
   while (!Reader.empty()) {
-    if (auto EC = Reader.readEnum(Leaf, llvm::support::little))
+    if (auto EC = Reader.readEnum(Leaf))
       return EC;
 
     CVMemberRecord Record;
@@ -195,7 +195,7 @@ Error CVTypeVisitor::visitFieldListMembe
 }
 
 Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
-  msf::ByteStream S(Data);
-  msf::StreamReader SR(S);
+  BinaryByteStream S(Data, llvm::support::little);
+  BinaryStreamReader SR(S);
   return visitFieldListMemberStream(SR);
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp Fri Feb 24 18:44:30 2017
@@ -87,14 +87,13 @@ Error CodeViewRecordIO::mapByteVectorTai
 
 Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
   if (isWriting()) {
-    if (auto EC =
-            Writer->writeInteger(TypeInd.getIndex(), llvm::support::little))
+    if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
       return EC;
     return Error::success();
   }
 
   uint32_t I;
-  if (auto EC = Reader->readInteger(I, llvm::support::little))
+  if (auto EC = Reader->readInteger(I))
     return EC;
   TypeInd.setIndex(I);
   return Error::success();
@@ -146,10 +145,10 @@ Error CodeViewRecordIO::mapStringZ(Strin
   if (isWriting()) {
     // Truncate if we attempt to write too much.
     StringRef S = Value.take_front(maxFieldLength() - 1);
-    if (auto EC = Writer->writeZeroString(S))
+    if (auto EC = Writer->writeCString(S))
       return EC;
   } else {
-    if (auto EC = Reader->readZeroString(Value))
+    if (auto EC = Reader->readCString(Value))
       return EC;
   }
   return Error::success();
@@ -177,7 +176,7 @@ Error CodeViewRecordIO::mapStringZVector
       if (auto EC = mapStringZ(V))
         return EC;
     }
-    if (auto EC = Writer->writeInteger<uint8_t>(0, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint8_t>(0))
       return EC;
   } else {
     StringRef S;
@@ -195,28 +194,24 @@ Error CodeViewRecordIO::mapStringZVector
 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
   assert(Value < 0 && "Encoded integer is not signed!");
   if (Value >= std::numeric_limits<int8_t>::min()) {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_CHAR, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
       return EC;
-    if (auto EC = Writer->writeInteger<int8_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<int8_t>(Value))
       return EC;
   } else if (Value >= std::numeric_limits<int16_t>::min()) {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_SHORT, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
       return EC;
-    if (auto EC = Writer->writeInteger<int16_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<int16_t>(Value))
       return EC;
   } else if (Value >= std::numeric_limits<int32_t>::min()) {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_LONG, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
       return EC;
-    if (auto EC = Writer->writeInteger<int32_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<int32_t>(Value))
       return EC;
   } else {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_QUADWORD, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
       return EC;
-    if (auto EC = Writer->writeInteger(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger(Value))
       return EC;
   }
   return Error::success();
@@ -224,25 +219,22 @@ Error CodeViewRecordIO::writeEncodedSign
 
 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
   if (Value < LF_NUMERIC) {
-    if (auto EC = Writer->writeInteger<uint16_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(Value))
       return EC;
   } else if (Value <= std::numeric_limits<uint16_t>::max()) {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_USHORT, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
       return EC;
-    if (auto EC = Writer->writeInteger<uint16_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(Value))
       return EC;
   } else if (Value <= std::numeric_limits<uint32_t>::max()) {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_ULONG, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
       return EC;
-    if (auto EC = Writer->writeInteger<uint32_t>(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint32_t>(Value))
       return EC;
   } else {
-    if (auto EC =
-            Writer->writeInteger<uint16_t>(LF_UQUADWORD, llvm::support::little))
+    if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
       return EC;
-    if (auto EC = Writer->writeInteger(Value, llvm::support::little))
+    if (auto EC = Writer->writeInteger(Value))
       return EC;
   }
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstream.cpp Fri Feb 24 18:44:30 2017
@@ -13,18 +13,16 @@
 
 using namespace llvm;
 using namespace llvm::codeview;
-using namespace llvm::msf;
 
 ModuleSubstream::ModuleSubstream() : Kind(ModuleSubstreamKind::None) {}
 
-ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind,
-                                 ReadableStreamRef Data)
+ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data)
     : Kind(Kind), Data(Data) {}
 
-Error ModuleSubstream::initialize(ReadableStreamRef Stream,
+Error ModuleSubstream::initialize(BinaryStreamRef Stream,
                                   ModuleSubstream &Info) {
   const ModuleSubsectionHeader *Header;
-  StreamReader Reader(Stream);
+  BinaryStreamReader Reader(Stream);
   if (auto EC = Reader.readObject(Header))
     return EC;
 
@@ -42,4 +40,4 @@ uint32_t ModuleSubstream::getRecordLengt
 
 ModuleSubstreamKind ModuleSubstream::getSubstreamKind() const { return Kind; }
 
-ReadableStreamRef ModuleSubstream::getRecordData() const { return Data; }
+BinaryStreamRef 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=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp Fri Feb 24 18:44:30 2017
@@ -13,49 +13,47 @@
 
 using namespace llvm;
 using namespace llvm::codeview;
-using namespace llvm::msf;
 
-Error IModuleSubstreamVisitor::visitSymbols(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitSymbols(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::Symbols, Data);
 }
-Error IModuleSubstreamVisitor::visitLines(ReadableStreamRef Data,
+Error IModuleSubstreamVisitor::visitLines(BinaryStreamRef Data,
                                           const LineSubstreamHeader *Header,
                                           const LineInfoArray &Lines) {
   return visitUnknown(ModuleSubstreamKind::Lines, Data);
 }
-Error IModuleSubstreamVisitor::visitStringTable(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitStringTable(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::StringTable, Data);
 }
 Error IModuleSubstreamVisitor::visitFileChecksums(
-    ReadableStreamRef Data, const FileChecksumArray &Checksums) {
+    BinaryStreamRef Data, const FileChecksumArray &Checksums) {
   return visitUnknown(ModuleSubstreamKind::FileChecksums, Data);
 }
-Error IModuleSubstreamVisitor::visitFrameData(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitFrameData(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::FrameData, Data);
 }
-Error IModuleSubstreamVisitor::visitInlineeLines(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitInlineeLines(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::InlineeLines, Data);
 }
-Error IModuleSubstreamVisitor::visitCrossScopeImports(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeImports(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CrossScopeExports, Data);
 }
-Error IModuleSubstreamVisitor::visitCrossScopeExports(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeExports(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CrossScopeImports, Data);
 }
-Error IModuleSubstreamVisitor::visitILLines(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitILLines(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::ILLines, Data);
 }
-Error IModuleSubstreamVisitor::visitFuncMDTokenMap(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitFuncMDTokenMap(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::FuncMDTokenMap, Data);
 }
-Error IModuleSubstreamVisitor::visitTypeMDTokenMap(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitTypeMDTokenMap(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::TypeMDTokenMap, Data);
 }
-Error IModuleSubstreamVisitor::visitMergedAssemblyInput(
-    ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitMergedAssemblyInput(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::MergedAssemblyInput, Data);
 }
-Error IModuleSubstreamVisitor::visitCoffSymbolRVA(ReadableStreamRef Data) {
+Error IModuleSubstreamVisitor::visitCoffSymbolRVA(BinaryStreamRef Data) {
   return visitUnknown(ModuleSubstreamKind::CoffSymbolRVA, Data);
 }
 
@@ -65,7 +63,7 @@ Error llvm::codeview::visitModuleSubstre
   case ModuleSubstreamKind::Symbols:
     return V.visitSymbols(R.getRecordData());
   case ModuleSubstreamKind::Lines: {
-    StreamReader Reader(R.getRecordData());
+    BinaryStreamReader Reader(R.getRecordData());
     const LineSubstreamHeader *Header;
     if (auto EC = Reader.readObject(Header))
       return EC;
@@ -78,7 +76,7 @@ Error llvm::codeview::visitModuleSubstre
   case ModuleSubstreamKind::StringTable:
     return V.visitStringTable(R.getRecordData());
   case ModuleSubstreamKind::FileChecksums: {
-    StreamReader Reader(R.getRecordData());
+    BinaryStreamReader Reader(R.getRecordData());
     FileChecksumArray Checksums;
     if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
       return EC;

Modified: llvm/trunk/lib/DebugInfo/CodeView/RecordSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/RecordSerialization.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/RecordSerialization.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/RecordSerialization.cpp Fri Feb 24 18:44:30 2017
@@ -33,11 +33,11 @@ StringRef llvm::codeview::getBytesAsCStr
   return getBytesAsCharacters(LeafData).split('\0').first;
 }
 
-Error llvm::codeview::consume(msf::StreamReader &Reader, APSInt &Num) {
+Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
   // Used to avoid overload ambiguity on APInt construtor.
   bool FalseVal = false;
   uint16_t Short;
-  if (auto EC = Reader.readInteger(Short, llvm::support::little))
+  if (auto EC = Reader.readInteger(Short))
     return EC;
 
   if (Short < LF_NUMERIC) {
@@ -49,49 +49,49 @@ Error llvm::codeview::consume(msf::Strea
   switch (Short) {
   case LF_CHAR: {
     int8_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(8, N, true), false);
     return Error::success();
   }
   case LF_SHORT: {
     int16_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(16, N, true), false);
     return Error::success();
   }
   case LF_USHORT: {
     uint16_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(16, N, false), true);
     return Error::success();
   }
   case LF_LONG: {
     int32_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(32, N, true), false);
     return Error::success();
   }
   case LF_ULONG: {
     uint32_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(32, N, FalseVal), true);
     return Error::success();
   }
   case LF_QUADWORD: {
     int64_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(64, N, true), false);
     return Error::success();
   }
   case LF_UQUADWORD: {
     uint64_t N;
-    if (auto EC = Reader.readInteger(N, llvm::support::little))
+    if (auto EC = Reader.readInteger(N))
       return EC;
     Num = APSInt(APInt(64, N, false), true);
     return Error::success();
@@ -103,15 +103,15 @@ Error llvm::codeview::consume(msf::Strea
 
 Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
-  msf::ByteStream S(Bytes);
-  msf::StreamReader SR(S);
+  BinaryByteStream S(Bytes, llvm::support::little);
+  BinaryStreamReader SR(S);
   auto EC = consume(SR, Num);
   Data = Data.take_back(SR.bytesRemaining());
   return EC;
 }
 
 /// Decode a numeric leaf value that is known to be a uint64_t.
-Error llvm::codeview::consume_numeric(msf::StreamReader &Reader,
+Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
                                       uint64_t &Num) {
   APSInt N;
   if (auto EC = consume(Reader, N))
@@ -123,27 +123,27 @@ Error llvm::codeview::consume_numeric(ms
   return Error::success();
 }
 
-Error llvm::codeview::consume(msf::StreamReader &Reader, uint32_t &Item) {
-  return Reader.readInteger(Item, llvm::support::little);
+Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
+  return Reader.readInteger(Item);
 }
 
 Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
   ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
-  msf::ByteStream S(Bytes);
-  msf::StreamReader SR(S);
+  BinaryByteStream S(Bytes, llvm::support::little);
+  BinaryStreamReader SR(S);
   auto EC = consume(SR, Item);
   Data = Data.take_back(SR.bytesRemaining());
   return EC;
 }
 
-Error llvm::codeview::consume(msf::StreamReader &Reader, int32_t &Item) {
-  return Reader.readInteger(Item, llvm::support::little);
+Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
+  return Reader.readInteger(Item);
 }
 
-Error llvm::codeview::consume(msf::StreamReader &Reader, StringRef &Item) {
+Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
   if (Reader.empty())
     return make_error<CodeViewError>(cv_error_code::corrupt_record,
                                      "Null terminated string buffer is empty!");
 
-  return Reader.readZeroString(Item);
+  return Reader.readCString(Item);
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeSerializer.cpp Fri Feb 24 18:44:30 2017
@@ -76,7 +76,7 @@ TypeSerializer::addPadding(MutableArrayR
   int N = PaddingBytes;
   while (PaddingBytes > 0) {
     uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
-    if (auto EC = Writer.writeInteger(Pad, llvm::support::little))
+    if (auto EC = Writer.writeInteger(Pad))
       return std::move(EC);
     --PaddingBytes;
   }
@@ -85,7 +85,8 @@ TypeSerializer::addPadding(MutableArrayR
 
 TypeSerializer::TypeSerializer(BumpPtrAllocator &Storage)
     : RecordStorage(Storage), LastTypeIndex(),
-      RecordBuffer(MaxRecordLength * 2), Stream(RecordBuffer), Writer(Stream),
+      RecordBuffer(MaxRecordLength * 2),
+      Stream(RecordBuffer, llvm::support::little), Writer(Stream),
       Mapping(Writer) {
   // RecordBuffer needs to be able to hold enough data so that if we are 1
   // byte short of MaxRecordLen, and then we try to write MaxRecordLen bytes,
@@ -203,15 +204,15 @@ Error TypeSerializer::visitMemberEnd(CVM
 
     uint8_t *SegmentBytes = RecordStorage.Allocate<uint8_t>(LengthWithSize);
     auto SavedSegment = MutableArrayRef<uint8_t>(SegmentBytes, LengthWithSize);
-    msf::MutableByteStream CS(SavedSegment);
-    msf::StreamWriter CW(CS);
+    MutableBinaryByteStream CS(SavedSegment, llvm::support::little);
+    BinaryStreamWriter CW(CS);
     if (auto EC = CW.writeBytes(CopyData))
       return EC;
-    if (auto EC = CW.writeEnum(TypeLeafKind::LF_INDEX, llvm::support::little))
+    if (auto EC = CW.writeEnum(TypeLeafKind::LF_INDEX))
       return EC;
-    if (auto EC = CW.writeInteger<uint16_t>(0, llvm::support::little))
+    if (auto EC = CW.writeInteger<uint16_t>(0))
       return EC;
-    if (auto EC = CW.writeInteger<uint32_t>(0xB0C0B0C0, llvm::support::little))
+    if (auto EC = CW.writeInteger<uint32_t>(0xB0C0B0C0))
       return EC;
     FieldListSegments.push_back(SavedSegment);
 

Modified: llvm/trunk/lib/DebugInfo/MSF/BinaryStreamReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/MSF/BinaryStreamReader.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/MSF/BinaryStreamReader.cpp (original)
+++ llvm/trunk/lib/DebugInfo/MSF/BinaryStreamReader.cpp Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamReader.cpp - Reads bytes and objects from a stream -----------===//
+//===- BinaryStreamReader.cpp - Reads objects from a binary stream --------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,53 +10,79 @@
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 
 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 
 using namespace llvm;
-using namespace llvm::msf;
 
-StreamReader::StreamReader(ReadableStreamRef S) : Stream(S), Offset(0) {}
+BinaryStreamReader::BinaryStreamReader(BinaryStreamRef S)
+    : Stream(S), Offset(0) {}
 
-Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) {
+Error BinaryStreamReader::readLongestContiguousChunk(
+    ArrayRef<uint8_t> &Buffer) {
   if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer))
     return EC;
   Offset += Buffer.size();
   return Error::success();
 }
 
-Error StreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) {
+Error BinaryStreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) {
   if (auto EC = Stream.readBytes(Offset, Size, Buffer))
     return EC;
   Offset += Size;
   return Error::success();
 }
 
-Error StreamReader::readZeroString(StringRef &Dest) {
+Error BinaryStreamReader::readInteger(uint64_t &Dest, uint32_t ByteSize) {
+  assert(ByteSize == 1 || ByteSize == 2 || ByteSize == 4 || ByteSize == 8);
+  ArrayRef<uint8_t> Bytes;
+
+  if (auto EC = readBytes(Bytes, ByteSize))
+    return EC;
+  switch (ByteSize) {
+  case 1:
+    Dest = Bytes[0];
+    return Error::success();
+  case 2:
+    Dest = llvm::support::endian::read16(Bytes.data(), Stream.getEndian());
+    return Error::success();
+  case 4:
+    Dest = llvm::support::endian::read32(Bytes.data(), Stream.getEndian());
+    return Error::success();
+  case 8:
+    Dest = llvm::support::endian::read64(Bytes.data(), Stream.getEndian());
+    return Error::success();
+  }
+  llvm_unreachable("Unreachable!");
+  return Error::success();
+}
+
+Error BinaryStreamReader::readCString(StringRef &Dest) {
+  // TODO: This could be made more efficient by using readLongestContiguousChunk
+  // and searching for null terminators in the resulting buffer.
+
   uint32_t Length = 0;
   // First compute the length of the string by reading 1 byte at a time.
   uint32_t OriginalOffset = getOffset();
   const char *C;
-  do {
+  while (true) {
     if (auto EC = readObject(C))
       return EC;
-    if (*C != '\0')
-      ++Length;
-  } while (*C != '\0');
+    if (*C == '\0')
+      break;
+    ++Length;
+  }
   // Now go back and request a reference for that many bytes.
   uint32_t NewOffset = getOffset();
   setOffset(OriginalOffset);
 
-  ArrayRef<uint8_t> Data;
-  if (auto EC = readBytes(Data, Length))
+  if (auto EC = readFixedString(Dest, Length))
     return EC;
-  Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size());
 
   // Now set the offset back to where it was after we calculated the length.
   setOffset(NewOffset);
   return Error::success();
 }
 
-Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
+Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
   ArrayRef<uint8_t> Bytes;
   if (auto EC = readBytes(Bytes, Length))
     return EC;
@@ -64,26 +90,26 @@ Error StreamReader::readFixedString(Stri
   return Error::success();
 }
 
-Error StreamReader::readStreamRef(ReadableStreamRef &Ref) {
+Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref) {
   return readStreamRef(Ref, bytesRemaining());
 }
 
-Error StreamReader::readStreamRef(ReadableStreamRef &Ref, uint32_t Length) {
+Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) {
   if (bytesRemaining() < Length)
-    return make_error<MSFError>(msf_error_code::insufficient_buffer);
+    return errorCodeToError(make_error_code(std::errc::no_buffer_space));
   Ref = Stream.slice(Offset, Length);
   Offset += Length;
   return Error::success();
 }
 
-Error StreamReader::skip(uint32_t Amount) {
+Error BinaryStreamReader::skip(uint32_t Amount) {
   if (Amount > bytesRemaining())
-    return make_error<MSFError>(msf_error_code::insufficient_buffer);
+    return errorCodeToError(make_error_code(std::errc::no_buffer_space));
   Offset += Amount;
   return Error::success();
 }
 
-uint8_t StreamReader::peek() const {
+uint8_t BinaryStreamReader::peek() const {
   ArrayRef<uint8_t> Buffer;
   auto EC = Stream.readBytes(Offset, 1, Buffer);
   assert(!EC && "Cannot peek an empty buffer!");

Modified: llvm/trunk/lib/DebugInfo/MSF/BinaryStreamWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/MSF/BinaryStreamWriter.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/MSF/BinaryStreamWriter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/MSF/BinaryStreamWriter.cpp Fri Feb 24 18:44:30 2017
@@ -1,4 +1,4 @@
-//===- StreamWrite.cpp - Writes bytes and objects to a stream -------------===//
+//===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -11,21 +11,42 @@
 
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
 
 using namespace llvm;
-using namespace llvm::msf;
 
-StreamWriter::StreamWriter(WritableStreamRef S) : Stream(S), Offset(0) {}
+BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef S)
+    : Stream(S), Offset(0) {}
 
-Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
+Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
   if (auto EC = Stream.writeBytes(Offset, Buffer))
     return EC;
   Offset += Buffer.size();
   return Error::success();
 }
 
-Error StreamWriter::writeZeroString(StringRef Str) {
+Error BinaryStreamWriter::writeInteger(uint64_t Value, uint32_t ByteSize) {
+  assert(ByteSize == 1 || ByteSize == 2 || ByteSize == 4 || ByteSize == 8);
+  uint8_t Bytes[8];
+  MutableArrayRef<uint8_t> Buffer(Bytes);
+  Buffer = Buffer.take_front(ByteSize);
+  switch (ByteSize) {
+  case 1:
+    Buffer[0] = static_cast<uint8_t>(Value);
+    break;
+  case 2:
+    llvm::support::endian::write16(Buffer.data(), Value, Stream.getEndian());
+    break;
+  case 4:
+    llvm::support::endian::write32(Buffer.data(), Value, Stream.getEndian());
+    break;
+  case 8:
+    llvm::support::endian::write64(Buffer.data(), Value, Stream.getEndian());
+    break;
+  }
+  return writeBytes(Buffer);
+}
+
+Error BinaryStreamWriter::writeCString(StringRef Str) {
   if (auto EC = writeFixedString(Str))
     return EC;
   if (auto EC = writeObject('\0'))
@@ -34,31 +55,21 @@ Error StreamWriter::writeZeroString(Stri
   return Error::success();
 }
 
-Error StreamWriter::writeFixedString(StringRef Str) {
-  ArrayRef<uint8_t> Bytes(Str.bytes_begin(), Str.bytes_end());
-  if (auto EC = Stream.writeBytes(Offset, Bytes))
-    return EC;
-
-  Offset += Str.size();
-  return Error::success();
+Error BinaryStreamWriter::writeFixedString(StringRef Str) {
+  return writeBytes(ArrayRef<uint8_t>(Str.bytes_begin(), Str.bytes_end()));
 }
 
-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
-  // writeStreamRef.
-  return Error::success();
+Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
+  return writeStreamRef(Ref, Ref.getLength());
 }
 
-Error StreamWriter::writeStreamRef(ReadableStreamRef Ref, uint32_t Length) {
-  Ref = Ref.slice(0, Length);
-
-  StreamReader SrcReader(Ref);
+Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
+  BinaryStreamReader SrcReader(Ref.slice(0, Length));
   // This is a bit tricky.  If we just call readBytes, we are requiring that it
-  // return us the entire stream as a contiguous buffer.  For large streams this
-  // will allocate a huge amount of space from the pool.  Instead, iterate over
-  // each contiguous chunk until we've consumed the entire stream.
+  // return us the entire stream as a contiguous buffer.  There is no guarantee
+  // this can be satisfied by returning a reference straight from the buffer, as
+  // an implementation may not store all data in a single contiguous buffer.  So
+  // we iterate over each contiguous chunk, writing each one in succession.
   while (SrcReader.bytesRemaining() > 0) {
     ArrayRef<uint8_t> Chunk;
     if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))

Modified: llvm/trunk/lib/DebugInfo/MSF/MappedBlockStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/MSF/MappedBlockStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/MSF/MappedBlockStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/MSF/MappedBlockStream.cpp Fri Feb 24 18:44:30 2017
@@ -47,22 +47,20 @@ static Interval intersect(const Interval
 
 MappedBlockStream::MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
                                      const MSFStreamLayout &Layout,
-                                     const ReadableStream &MsfData)
+                                     BinaryStreamRef 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) {
+                                BinaryStreamRef 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) {
+std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream(
+    const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex) {
   assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
   MSFStreamLayout SL;
   SL.Blocks = Layout.StreamMap[StreamIndex];
@@ -73,7 +71,7 @@ MappedBlockStream::createIndexedStream(c
 
 std::unique_ptr<MappedBlockStream>
 MappedBlockStream::createDirectoryStream(const MSFLayout &Layout,
-                                         const ReadableStream &MsfData) {
+                                         BinaryStreamRef MsfData) {
   MSFStreamLayout SL;
   SL.Blocks = Layout.DirectoryBlocks;
   SL.Length = Layout.SB->NumDirectoryBytes;
@@ -82,14 +80,14 @@ MappedBlockStream::createDirectoryStream
 
 std::unique_ptr<MappedBlockStream>
 MappedBlockStream::createFpmStream(const MSFLayout &Layout,
-                                   const ReadableStream &MsfData) {
+                                   BinaryStreamRef MsfData) {
   MSFStreamLayout SL;
   initializeFpmStreamLayout(Layout, SL);
   return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
 }
 
 Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
-                                   ArrayRef<uint8_t> &Buffer) const {
+                                   ArrayRef<uint8_t> &Buffer) {
   // Make sure we aren't trying to read beyond the end of the stream.
   if (Size > StreamLayout.Length)
     return make_error<MSFError>(msf_error_code::insufficient_buffer);
@@ -168,8 +166,8 @@ Error MappedBlockStream::readBytes(uint3
   return Error::success();
 }
 
-Error MappedBlockStream::readLongestContiguousChunk(
-    uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
+Error MappedBlockStream::readLongestContiguousChunk(uint32_t Offset,
+                                                    ArrayRef<uint8_t> &Buffer) {
   // Make sure we aren't trying to read beyond the end of the stream.
   if (Offset >= StreamLayout.Length)
     return make_error<MSFError>(msf_error_code::insufficient_buffer);
@@ -197,10 +195,10 @@ Error MappedBlockStream::readLongestCont
   return Error::success();
 }
 
-uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; }
+uint32_t MappedBlockStream::getLength() { return StreamLayout.Length; }
 
 bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
-                                            ArrayRef<uint8_t> &Buffer) const {
+                                            ArrayRef<uint8_t> &Buffer) {
   if (Size == 0) {
     Buffer = ArrayRef<uint8_t>();
     return true;
@@ -241,7 +239,7 @@ bool MappedBlockStream::tryReadContiguou
 }
 
 Error MappedBlockStream::readBytes(uint32_t Offset,
-                                   MutableArrayRef<uint8_t> Buffer) const {
+                                   MutableArrayRef<uint8_t> Buffer) {
   uint32_t BlockNum = Offset / BlockSize;
   uint32_t OffsetInBlock = Offset % BlockSize;
 
@@ -319,21 +317,21 @@ void MappedBlockStream::fixCacheAfterWri
 
 WritableMappedBlockStream::WritableMappedBlockStream(
     uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &Layout,
-    const WritableStream &MsfData)
+    WritableBinaryStreamRef 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) {
+                                        WritableBinaryStreamRef MsfData) {
   return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
       BlockSize, NumBlocks, Layout, MsfData);
 }
 
 std::unique_ptr<WritableMappedBlockStream>
 WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout,
-                                               const WritableStream &MsfData,
+                                               WritableBinaryStreamRef MsfData,
                                                uint32_t StreamIndex) {
   assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
   MSFStreamLayout SL;
@@ -344,7 +342,7 @@ WritableMappedBlockStream::createIndexed
 
 std::unique_ptr<WritableMappedBlockStream>
 WritableMappedBlockStream::createDirectoryStream(
-    const MSFLayout &Layout, const WritableStream &MsfData) {
+    const MSFLayout &Layout, WritableBinaryStreamRef MsfData) {
   MSFStreamLayout SL;
   SL.Blocks = Layout.DirectoryBlocks;
   SL.Length = Layout.SB->NumDirectoryBytes;
@@ -353,28 +351,28 @@ WritableMappedBlockStream::createDirecto
 
 std::unique_ptr<WritableMappedBlockStream>
 WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout,
-                                           const WritableStream &MsfData) {
+                                           WritableBinaryStreamRef MsfData) {
   MSFStreamLayout SL;
   initializeFpmStreamLayout(Layout, SL);
   return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
 }
 
 Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
-                                           ArrayRef<uint8_t> &Buffer) const {
+                                           ArrayRef<uint8_t> &Buffer) {
   return ReadInterface.readBytes(Offset, Size, Buffer);
 }
 
 Error WritableMappedBlockStream::readLongestContiguousChunk(
-    uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
+    uint32_t Offset, ArrayRef<uint8_t> &Buffer) {
   return ReadInterface.readLongestContiguousChunk(Offset, Buffer);
 }
 
-uint32_t WritableMappedBlockStream::getLength() const {
+uint32_t WritableMappedBlockStream::getLength() {
   return ReadInterface.getLength();
 }
 
 Error WritableMappedBlockStream::writeBytes(uint32_t Offset,
-                                            ArrayRef<uint8_t> Buffer) const {
+                                            ArrayRef<uint8_t> Buffer) {
   // 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);
@@ -410,6 +408,4 @@ Error WritableMappedBlockStream::writeBy
   return Error::success();
 }
 
-Error WritableMappedBlockStream::commit() const {
-  return WriteInterface.commit();
-}
+Error WritableMappedBlockStream::commit() { return WriteInterface.commit(); }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp Fri Feb 24 18:44:30 2017
@@ -10,6 +10,8 @@
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
@@ -34,7 +36,7 @@ using namespace llvm::support;
 
 template <typename ContribType>
 static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
-                                 StreamReader &Reader) {
+                                 BinaryStreamReader &Reader) {
   if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
     return make_error<RawError>(
         raw_error_code::corrupt_file,
@@ -52,7 +54,7 @@ DbiStream::DbiStream(PDBFile &File, std:
 DbiStream::~DbiStream() = default;
 
 Error DbiStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   if (Stream->getLength() < sizeof(DbiStreamHeader))
     return make_error<RawError>(raw_error_code::corrupt_file,
@@ -145,7 +147,7 @@ Error DbiStream::reload() {
                                 "Found unexpected bytes in DBI Stream.");
 
   if (ECSubstream.getLength() > 0) {
-    StreamReader ECReader(ECSubstream);
+    BinaryStreamReader ECReader(ECSubstream);
     if (auto EC = ECNames.load(ECReader))
       return EC;
   }
@@ -207,16 +209,16 @@ PDB_Machine DbiStream::getMachineType()
   return static_cast<PDB_Machine>(Machine);
 }
 
-msf::FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
+FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
   return SectionHeaders;
 }
 
-msf::FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
+FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
   return FpoRecords;
 }
 
 ArrayRef<ModuleInfoEx> DbiStream::modules() const { return ModuleInfos; }
-msf::FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
+FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
   return SectionMap;
 }
 
@@ -235,8 +237,8 @@ Error DbiStream::initializeSectionContri
   if (SecContrSubstream.getLength() == 0)
     return Error::success();
 
-  StreamReader SCReader(SecContrSubstream);
-  if (auto EC = SCReader.readEnum(SectionContribVersion, llvm::support::little))
+  BinaryStreamReader SCReader(SecContrSubstream);
+  if (auto EC = SCReader.readEnum(SectionContribVersion))
     return EC;
 
   if (SectionContribVersion == DbiSecContribVer60)
@@ -254,7 +256,7 @@ Error DbiStream::initializeModInfoArray(
 
   // Since each ModInfo in the stream is a variable length, we have to iterate
   // them to know how many there actually are.
-  StreamReader Reader(ModInfoSubstream);
+  BinaryStreamReader Reader(ModInfoSubstream);
 
   VarStreamArray<ModInfo> ModInfoArray;
   if (auto EC = Reader.readArray(ModInfoArray, ModInfoSubstream.getLength()))
@@ -284,7 +286,7 @@ Error DbiStream::initializeSectionHeader
                                 "Corrupted section header stream.");
 
   size_t NumSections = StreamLen / sizeof(object::coff_section);
-  msf::StreamReader Reader(*SHS);
+  BinaryStreamReader Reader(*SHS);
   if (auto EC = Reader.readArray(SectionHeaders, NumSections))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Could not read a bitmap.");
@@ -316,7 +318,7 @@ Error DbiStream::initializeFpoRecords()
                                 "Corrupted New FPO stream.");
 
   size_t NumRecords = StreamLen / sizeof(object::FpoData);
-  msf::StreamReader Reader(*FS);
+  BinaryStreamReader Reader(*FS);
   if (auto EC = Reader.readArray(FpoRecords, NumRecords))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Corrupted New FPO stream.");
@@ -328,7 +330,7 @@ Error DbiStream::initializeSectionMapDat
   if (SecMapSubstream.getLength() == 0)
     return Error::success();
 
-  StreamReader SMReader(SecMapSubstream);
+  BinaryStreamReader SMReader(SecMapSubstream);
   const SecMapHeader *Header;
   if (auto EC = SMReader.readObject(Header))
     return EC;
@@ -342,7 +344,7 @@ Error DbiStream::initializeFileInfo() {
     return Error::success();
 
   const FileInfoSubstreamHeader *FH;
-  StreamReader FISR(FileInfoSubstream);
+  BinaryStreamReader FISR(FileInfoSubstream);
   if (auto EC = FISR.readObject(FH))
     return EC;
 
@@ -411,14 +413,14 @@ uint32_t DbiStream::getDebugStreamIndex(
 }
 
 Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
-  StreamReader Names(NamesBuffer);
+  BinaryStreamReader Names(NamesBuffer);
   if (Index >= FileNameOffsets.size())
     return make_error<RawError>(raw_error_code::index_out_of_bounds);
 
   uint32_t FileOffset = FileNameOffsets[Index];
   Names.setOffset(FileOffset);
   StringRef Name;
-  if (auto EC = Names.readZeroString(Name))
+  if (auto EC = Names.readCString(Name))
     return std::move(EC);
   return Name;
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp Fri Feb 24 18:44:30 2017
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
@@ -153,18 +154,19 @@ Error DbiStreamBuilder::generateModiSubs
   uint32_t Size = calculateModiSubstreamSize();
   auto Data = Allocator.Allocate<uint8_t>(Size);
 
-  ModInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
+  ModInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),
+                                          llvm::support::little);
 
-  StreamWriter ModiWriter(ModInfoBuffer);
+  BinaryStreamWriter ModiWriter(ModInfoBuffer);
   for (const auto &M : ModuleInfoList) {
     ModuleInfoHeader Layout = {};
     Layout.ModDiStream = kInvalidStreamIndex;
     Layout.NumFiles = M->SourceFiles.size();
     if (auto EC = ModiWriter.writeObject(Layout))
       return EC;
-    if (auto EC = ModiWriter.writeZeroString(M->Mod))
+    if (auto EC = ModiWriter.writeCString(M->Mod))
       return EC;
-    if (auto EC = ModiWriter.writeZeroString(M->Obj))
+    if (auto EC = ModiWriter.writeCString(M->Obj))
       return EC;
   }
   if (ModiWriter.bytesRemaining() > sizeof(uint32_t))
@@ -179,29 +181,26 @@ Error DbiStreamBuilder::generateFileInfo
   auto Data = Allocator.Allocate<uint8_t>(Size);
   uint32_t NamesOffset = Size - NameSize;
 
-  FileInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
+  FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),
+                                           llvm::support::little);
 
-  WritableStreamRef MetadataBuffer =
-      WritableStreamRef(FileInfoBuffer).keep_front(NamesOffset);
-  StreamWriter MetadataWriter(MetadataBuffer);
+  WritableBinaryStreamRef MetadataBuffer =
+      WritableBinaryStreamRef(FileInfoBuffer).keep_front(NamesOffset);
+  BinaryStreamWriter MetadataWriter(MetadataBuffer);
 
   uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModuleInfos.size());
   uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());
-  if (auto EC = MetadataWriter.writeInteger(
-          ModiCount, llvm::support::little)) // NumModules
+  if (auto EC = MetadataWriter.writeInteger(ModiCount)) // NumModules
     return EC;
-  if (auto EC = MetadataWriter.writeInteger(
-          FileCount, llvm::support::little)) // NumSourceFiles
+  if (auto EC = MetadataWriter.writeInteger(FileCount)) // NumSourceFiles
     return EC;
   for (uint16_t I = 0; I < ModiCount; ++I) {
-    if (auto EC = MetadataWriter.writeInteger(
-            I, llvm::support::little)) // Mod Indices
+    if (auto EC = MetadataWriter.writeInteger(I)) // Mod Indices
       return EC;
   }
   for (const auto MI : ModuleInfoList) {
     FileCount = static_cast<uint16_t>(MI->SourceFiles.size());
-    if (auto EC = MetadataWriter.writeInteger(
-            FileCount, llvm::support::little)) // Mod File Counts
+    if (auto EC = MetadataWriter.writeInteger(FileCount)) // Mod File Counts
       return EC;
   }
 
@@ -209,11 +208,11 @@ 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 = WritableStreamRef(FileInfoBuffer).drop_front(NamesOffset);
-  StreamWriter NameBufferWriter(NamesBuffer);
+  NamesBuffer = WritableBinaryStreamRef(FileInfoBuffer).drop_front(NamesOffset);
+  BinaryStreamWriter NameBufferWriter(NamesBuffer);
   for (auto &Name : SourceFileNames) {
     Name.second = NameBufferWriter.getOffset();
-    if (auto EC = NameBufferWriter.writeZeroString(Name.getKey()))
+    if (auto EC = NameBufferWriter.writeCString(Name.getKey()))
       return EC;
   }
 
@@ -223,8 +222,7 @@ Error DbiStreamBuilder::generateFileInfo
       if (Result == SourceFileNames.end())
         return make_error<RawError>(raw_error_code::no_entry,
                                     "The source file was not found.");
-      if (auto EC = MetadataWriter.writeInteger(Result->second,
-                                                llvm::support::little))
+      if (auto EC = MetadataWriter.writeInteger(Result->second))
         return EC;
     }
   }
@@ -363,14 +361,14 @@ std::vector<SecMapEntry> DbiStreamBuilde
 }
 
 Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
-                               const msf::WritableStream &Buffer) {
+                               WritableBinaryStreamRef Buffer) {
   if (auto EC = finalize())
     return EC;
 
   auto InfoS =
       WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamDBI);
 
-  StreamWriter Writer(*InfoS);
+  BinaryStreamWriter Writer(*InfoS);
   if (auto EC = Writer.writeObject(*Header))
     return EC;
 
@@ -378,7 +376,7 @@ Error DbiStreamBuilder::commit(const msf
     return EC;
 
   if (!SectionContribs.empty()) {
-    if (auto EC = Writer.writeEnum(DbiSecContribVer60, llvm::support::little))
+    if (auto EC = Writer.writeEnum(DbiSecContribVer60))
       return EC;
     if (auto EC = Writer.writeArray(SectionContribs))
       return EC;
@@ -397,8 +395,7 @@ Error DbiStreamBuilder::commit(const msf
     return EC;
 
   for (auto &Stream : DbgStreams)
-    if (auto EC =
-            Writer.writeInteger(Stream.StreamNumber, llvm::support::little))
+    if (auto EC = Writer.writeInteger(Stream.StreamNumber))
       return EC;
 
   for (auto &Stream : DbgStreams) {
@@ -406,7 +403,7 @@ Error DbiStreamBuilder::commit(const msf
       continue;
     auto WritableStream = WritableMappedBlockStream::createIndexedStream(
         Layout, Buffer, Stream.StreamNumber);
-    StreamWriter DbgStreamWriter(*WritableStream);
+    BinaryStreamWriter DbgStreamWriter(*WritableStream);
     if (auto EC = DbgStreamWriter.writeArray(Stream.Data))
       return EC;
   }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/GSI.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/GSI.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/GSI.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/GSI.cpp Fri Feb 24 18:44:30 2017
@@ -28,9 +28,9 @@ static Error checkHashHdrVersion(const G
   return Error::success();
 }
 
-Error readGSIHashBuckets(
-    msf::FixedStreamArray<support::ulittle32_t> &HashBuckets,
-    const GSIHashHeader *HashHdr, msf::StreamReader &Reader) {
+Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+                         const GSIHashHeader *HashHdr,
+                         BinaryStreamReader &Reader) {
   if (auto EC = checkHashHdrVersion(HashHdr))
     return EC;
 
@@ -57,7 +57,7 @@ Error readGSIHashBuckets(
 }
 
 Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
-                        msf::StreamReader &Reader) {
+                        BinaryStreamReader &Reader) {
   if (Reader.readObject(HashHdr))
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Stream does not contain a GSIHashHeader.");
@@ -70,9 +70,9 @@ Error readGSIHashHeader(const GSIHashHea
   return Error::success();
 }
 
-Error readGSIHashRecords(msf::FixedStreamArray<PSHashRecord> &HashRecords,
+Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
                          const GSIHashHeader *HashHdr,
-                         msf::StreamReader &Reader) {
+                         BinaryStreamReader &Reader) {
   if (auto EC = checkHashHdrVersion(HashHdr))
     return EC;
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/GSI.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/GSI.h?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/GSI.h (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/GSI.h Fri Feb 24 18:44:30 2017
@@ -33,9 +33,7 @@
 
 namespace llvm {
 
-namespace msf {
-class StreamReader;
-}
+class BinaryStreamReader;
 
 namespace pdb {
 
@@ -56,14 +54,14 @@ struct GSIHashHeader {
   support::ulittle32_t NumBuckets;
 };
 
-Error readGSIHashBuckets(
-    msf::FixedStreamArray<support::ulittle32_t> &HashBuckets,
-    const GSIHashHeader *HashHdr, msf::StreamReader &Reader);
+Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+                         const GSIHashHeader *HashHdr,
+                         BinaryStreamReader &Reader);
 Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
-                        msf::StreamReader &Reader);
-Error readGSIHashRecords(msf::FixedStreamArray<PSHashRecord> &HashRecords,
+                        BinaryStreamReader &Reader);
+Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
                          const GSIHashHeader *HashHdr,
-                         msf::StreamReader &Reader);
+                         BinaryStreamReader &Reader);
 }
 }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/GlobalsStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/GlobalsStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/GlobalsStream.cpp Fri Feb 24 18:44:30 2017
@@ -23,7 +23,7 @@ GlobalsStream::GlobalsStream(std::unique
 GlobalsStream::~GlobalsStream() = default;
 
 Error GlobalsStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   const GSIHashHeader *HashHdr;
   if (auto EC = readGSIHashHeader(HashHdr, Reader))

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/HashTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/HashTable.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/HashTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/HashTable.cpp Fri Feb 24 18:44:30 2017
@@ -22,7 +22,7 @@ HashTable::HashTable() : HashTable(8) {}
 
 HashTable::HashTable(uint32_t Capacity) { Buckets.resize(Capacity); }
 
-Error HashTable::load(msf::StreamReader &Stream) {
+Error HashTable::load(BinaryStreamReader &Stream) {
   const Header *H;
   if (auto EC = Stream.readObject(H))
     return EC;
@@ -48,9 +48,9 @@ Error HashTable::load(msf::StreamReader
                                 "Present bit vector interesects deleted!");
 
   for (uint32_t P : Present) {
-    if (auto EC = Stream.readInteger(Buckets[P].first, llvm::support::little))
+    if (auto EC = Stream.readInteger(Buckets[P].first))
       return EC;
-    if (auto EC = Stream.readInteger(Buckets[P].second, llvm::support::little))
+    if (auto EC = Stream.readInteger(Buckets[P].second))
       return EC;
   }
 
@@ -77,7 +77,7 @@ uint32_t HashTable::calculateSerializedL
   return Size;
 }
 
-Error HashTable::commit(msf::StreamWriter &Writer) const {
+Error HashTable::commit(BinaryStreamWriter &Writer) const {
   Header H;
   H.Size = size();
   H.Capacity = capacity();
@@ -91,9 +91,9 @@ Error HashTable::commit(msf::StreamWrite
     return EC;
 
   for (const auto &Entry : *this) {
-    if (auto EC = Writer.writeInteger(Entry.first, llvm::support::little))
+    if (auto EC = Writer.writeInteger(Entry.first))
       return EC;
-    if (auto EC = Writer.writeInteger(Entry.second, llvm::support::little))
+    if (auto EC = Writer.writeInteger(Entry.second))
       return EC;
   }
   return Error::success();
@@ -209,10 +209,10 @@ void HashTable::grow() {
   assert(size() == S);
 }
 
-Error HashTable::readSparseBitVector(msf::StreamReader &Stream,
+Error HashTable::readSparseBitVector(BinaryStreamReader &Stream,
                                      SparseBitVector<> &V) {
   uint32_t NumWords;
-  if (auto EC = Stream.readInteger(NumWords, llvm::support::little))
+  if (auto EC = Stream.readInteger(NumWords))
     return joinErrors(
         std::move(EC),
         make_error<RawError>(raw_error_code::corrupt_file,
@@ -220,7 +220,7 @@ Error HashTable::readSparseBitVector(msf
 
   for (uint32_t I = 0; I != NumWords; ++I) {
     uint32_t Word;
-    if (auto EC = Stream.readInteger(Word, llvm::support::little))
+    if (auto EC = Stream.readInteger(Word))
       return joinErrors(std::move(EC),
                         make_error<RawError>(raw_error_code::corrupt_file,
                                              "Expected hash table word"));
@@ -231,11 +231,11 @@ Error HashTable::readSparseBitVector(msf
   return Error::success();
 }
 
-Error HashTable::writeSparseBitVector(msf::StreamWriter &Writer,
+Error HashTable::writeSparseBitVector(BinaryStreamWriter &Writer,
                                       SparseBitVector<> &Vec) {
   int ReqBits = Vec.find_last() + 1;
   uint32_t NumWords = alignTo(ReqBits, sizeof(uint32_t)) / sizeof(uint32_t);
-  if (auto EC = Writer.writeInteger(NumWords, llvm::support::little))
+  if (auto EC = Writer.writeInteger(NumWords))
     return joinErrors(
         std::move(EC),
         make_error<RawError>(raw_error_code::corrupt_file,
@@ -248,7 +248,7 @@ Error HashTable::writeSparseBitVector(ms
       if (Vec.test(Idx))
         Word |= (1 << WordIdx);
     }
-    if (auto EC = Writer.writeInteger(Word, llvm::support::little))
+    if (auto EC = Writer.writeInteger(Word))
       return joinErrors(std::move(EC), make_error<RawError>(
                                            raw_error_code::corrupt_file,
                                            "Could not write linear map word"));

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp Fri Feb 24 18:44:30 2017
@@ -26,7 +26,7 @@ InfoStream::InfoStream(std::unique_ptr<M
     : Stream(std::move(Stream)) {}
 
 Error InfoStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   const InfoStreamHeader *H;
   if (auto EC = Reader.readObject(H))

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp Fri Feb 24 18:44:30 2017
@@ -10,6 +10,7 @@
 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
 
 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -44,10 +45,10 @@ Error InfoStreamBuilder::finalizeMsfLayo
 }
 
 Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
-                                const msf::WritableStream &Buffer) const {
+                                WritableBinaryStreamRef Buffer) const {
   auto InfoS =
       WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamPDB);
-  StreamWriter Writer(*InfoS);
+  BinaryStreamWriter Writer(*InfoS);
 
   InfoStreamHeader H;
   H.Age = Age;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/ModInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/ModInfo.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/ModInfo.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/ModInfo.cpp Fri Feb 24 18:44:30 2017
@@ -16,7 +16,6 @@
 #include <cstdint>
 
 using namespace llvm;
-using namespace llvm::msf;
 using namespace llvm::pdb;
 using namespace llvm::support;
 
@@ -26,15 +25,15 @@ ModInfo::ModInfo(const ModInfo &Info) =
 
 ModInfo::~ModInfo() = default;
 
-Error ModInfo::initialize(ReadableStreamRef Stream, ModInfo &Info) {
-  StreamReader Reader(Stream);
+Error ModInfo::initialize(BinaryStreamRef Stream, ModInfo &Info) {
+  BinaryStreamReader Reader(Stream);
   if (auto EC = Reader.readObject(Info.Layout))
     return EC;
 
-  if (auto EC = Reader.readZeroString(Info.ModuleName))
+  if (auto EC = Reader.readCString(Info.ModuleName))
     return EC;
 
-  if (auto EC = Reader.readZeroString(Info.ObjFileName))
+  if (auto EC = Reader.readCString(Info.ObjFileName))
     return EC;
   return Error::success();
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/ModStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/ModStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/ModStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/ModStream.cpp Fri Feb 24 18:44:30 2017
@@ -31,7 +31,7 @@ ModStream::ModStream(const ModInfo &Modu
 ModStream::~ModStream() = default;
 
 Error ModStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
   uint32_t C11Size = Mod.getLineInfoByteSize();
@@ -41,9 +41,9 @@ Error ModStream::reload() {
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Module has both C11 and C13 line info");
 
-  ReadableStreamRef S;
+  BinaryStreamRef S;
 
-  if (auto EC = Reader.readInteger(Signature, llvm::support::little))
+  if (auto EC = Reader.readInteger(Signature))
     return EC;
   if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
     return EC;
@@ -53,12 +53,12 @@ Error ModStream::reload() {
   if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
     return EC;
 
-  StreamReader LineReader(C13LinesSubstream);
+  BinaryStreamReader LineReader(C13LinesSubstream);
   if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining()))
     return EC;
 
   uint32_t GlobalRefsSize;
-  if (auto EC = Reader.readInteger(GlobalRefsSize, llvm::support::little))
+  if (auto EC = Reader.readInteger(GlobalRefsSize))
     return EC;
   if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
     return EC;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp Fri Feb 24 18:44:30 2017
@@ -21,23 +21,22 @@
 #include <cstdint>
 
 using namespace llvm;
-using namespace llvm::msf;
 using namespace llvm::pdb;
 
 NamedStreamMap::NamedStreamMap() = default;
 
-Error NamedStreamMap::load(StreamReader &Stream) {
+Error NamedStreamMap::load(BinaryStreamReader &Stream) {
   Mapping.clear();
   FinalizedHashTable.clear();
   FinalizedInfo.reset();
 
   uint32_t StringBufferSize;
-  if (auto EC = Stream.readInteger(StringBufferSize, llvm::support::little))
+  if (auto EC = Stream.readInteger(StringBufferSize))
     return joinErrors(std::move(EC),
                       make_error<RawError>(raw_error_code::corrupt_file,
                                            "Expected string buffer size"));
 
-  msf::ReadableStreamRef StringsBuffer;
+  BinaryStreamRef StringsBuffer;
   if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
     return EC;
 
@@ -51,11 +50,11 @@ Error NamedStreamMap::load(StreamReader
     std::tie(NameOffset, NameIndex) = Entry;
 
     // Compute the offset of the start of the string relative to the stream.
-    msf::StreamReader NameReader(StringsBuffer);
+    BinaryStreamReader NameReader(StringsBuffer);
     NameReader.setOffset(NameOffset);
     // Pump out our c-string from the stream.
     StringRef Str;
-    if (auto EC = NameReader.readZeroString(Str))
+    if (auto EC = NameReader.readCString(Str))
       return joinErrors(std::move(EC),
                         make_error<RawError>(raw_error_code::corrupt_file,
                                              "Expected name map name"));
@@ -67,17 +66,16 @@ Error NamedStreamMap::load(StreamReader
   return Error::success();
 }
 
-Error NamedStreamMap::commit(msf::StreamWriter &Writer) const {
+Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
   assert(FinalizedInfo.hasValue());
 
   // The first field is the number of bytes of string data.
-  if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes,
-                                    llvm::support::little))
+  if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
     return EC;
 
   // Now all of the string data itself.
   for (const auto &Item : Mapping) {
-    if (auto EC = Writer.writeZeroString(Item.getKey()))
+    if (auto EC = Writer.writeCString(Item.getKey()))
       return EC;
   }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp Fri Feb 24 18:44:30 2017
@@ -45,7 +45,8 @@ Error NativeSession::createFromPdb(Strin
     return make_error<GenericError>(generic_error_code::invalid_path);
 
   std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
-  auto Stream = llvm::make_unique<MemoryBufferByteStream>(std::move(Buffer));
+  auto Stream = llvm::make_unique<MemoryBufferByteStream>(
+      std::move(Buffer), llvm::support::little);
 
   auto Allocator = llvm::make_unique<BumpPtrAllocator>();
   auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp Fri Feb 24 18:44:30 2017
@@ -11,8 +11,11 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/MSFCommon.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
@@ -39,7 +42,7 @@ namespace {
 typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
 } // end anonymous namespace
 
-PDBFile::PDBFile(StringRef Path, std::unique_ptr<ReadableStream> PdbFileBuffer,
+PDBFile::PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
                  BumpPtrAllocator &Allocator)
     : FilePath(Path), Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
 
@@ -113,7 +116,7 @@ Error PDBFile::setBlockData(uint32_t Blo
 }
 
 Error PDBFile::parseFileHeaders() {
-  StreamReader Reader(*Buffer);
+  BinaryStreamReader Reader(*Buffer);
 
   // Initialize SB.
   const msf::SuperBlock *SB = nullptr;
@@ -147,7 +150,7 @@ Error PDBFile::parseFileHeaders() {
   // See the function fpmPn() for more information:
   // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
   auto FpmStream = MappedBlockStream::createFpmStream(ContainerLayout, *Buffer);
-  StreamReader FpmReader(*FpmStream);
+  BinaryStreamReader FpmReader(*FpmStream);
   ArrayRef<uint8_t> FpmBytes;
   if (auto EC = FpmReader.readBytes(FpmBytes,
                                     msf::getFullFpmByteSize(ContainerLayout)))
@@ -185,8 +188,8 @@ Error PDBFile::parseStreamData() {
   // subclass of IPDBStreamData which only accesses the fields that have already
   // been parsed, we can avoid this and reuse MappedBlockStream.
   auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer);
-  StreamReader Reader(*DS);
-  if (auto EC = Reader.readInteger(NumStreams, llvm::support::little))
+  BinaryStreamReader Reader(*DS);
+  if (auto EC = Reader.readInteger(NumStreams))
     return EC;
 
   if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
@@ -350,7 +353,7 @@ Expected<StringTable &> PDBFile::getStri
     if (!NS)
       return NS.takeError();
 
-    StreamReader Reader(**NS);
+    BinaryStreamReader Reader(**NS);
     auto N = llvm::make_unique<StringTable>();
     if (auto EC = N->load(Reader))
       return std::move(EC);
@@ -403,7 +406,7 @@ bool PDBFile::hasStringTable() {
 /// contain the stream returned by createIndexedStream().
 Expected<std::unique_ptr<MappedBlockStream>>
 PDBFile::safelyCreateIndexedStream(const MSFLayout &Layout,
-                                   const ReadableStream &MsfData,
+                                   BinaryStreamRef MsfData,
                                    uint32_t StreamIndex) const {
   if (StreamIndex >= getNumStreams())
     return make_error<RawError>(raw_error_code::no_stream);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp Fri Feb 24 18:44:30 2017
@@ -12,6 +12,8 @@
 #include "llvm/ADT/BitVector.h"
 
 #include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/PDB/GenericError.h"
@@ -118,8 +120,9 @@ Error PDBFileBuilder::commit(StringRef F
   if (OutFileOrError.getError())
     return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
                                                Filename);
-  FileBufferByteStream Buffer(std::move(*OutFileOrError));
-  StreamWriter Writer(Buffer);
+  FileBufferByteStream Buffer(std::move(*OutFileOrError),
+                              llvm::support::little);
+  BinaryStreamWriter Writer(Buffer);
 
   if (auto EC = Writer.writeObject(*Layout.SB))
     return EC;
@@ -131,9 +134,8 @@ Error PDBFileBuilder::commit(StringRef F
 
   auto DirStream =
       WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
-  StreamWriter DW(*DirStream);
-  if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size(),
-                                          llvm::support::little))
+  BinaryStreamWriter DW(*DirStream);
+  if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
     return EC;
 
   if (auto EC = DW.writeArray(Layout.StreamSizes))
@@ -150,7 +152,7 @@ Error PDBFileBuilder::commit(StringRef F
 
   auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
                                                            StringTableStreamNo);
-  StreamWriter NSWriter(*NS);
+  BinaryStreamWriter NSWriter(*NS);
   if (auto EC = Strings.commit(NSWriter))
     return EC;
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PublicsStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PublicsStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PublicsStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PublicsStream.cpp Fri Feb 24 18:44:30 2017
@@ -27,6 +27,7 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/RawError.h"
@@ -69,7 +70,7 @@ uint32_t PublicsStream::getAddrMap() con
 // we skip over the hash table which we believe contains information about
 // public symbols.
 Error PublicsStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   // Check stream size.
   if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader))

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp Fri Feb 24 18:44:30 2017
@@ -17,13 +17,12 @@
 #include "llvm/Support/Endian.h"
 
 using namespace llvm;
-using namespace llvm::msf;
 using namespace llvm::support;
 using namespace llvm::pdb;
 
 StringTable::StringTable() : Signature(0), HashVersion(0), NameCount(0) {}
 
-Error StringTable::load(StreamReader &Stream) {
+Error StringTable::load(BinaryStreamReader &Stream) {
   const StringTableHeader *H;
   if (auto EC = Stream.readObject(H))
     return EC;
@@ -55,7 +54,7 @@ Error StringTable::load(StreamReader &St
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Missing name count");
 
-  if (auto EC = Stream.readInteger(NameCount, llvm::support::little))
+  if (auto EC = Stream.readInteger(NameCount))
     return EC;
   return Error::success();
 }
@@ -68,9 +67,9 @@ StringRef StringTable::getStringForID(ui
   // the starting offset of the string we're looking for.  So just seek into
   // the desired offset and a read a null terminated stream from that offset.
   StringRef Result;
-  StreamReader NameReader(NamesBuffer);
+  BinaryStreamReader NameReader(NamesBuffer);
   NameReader.setOffset(ID);
-  if (auto EC = NameReader.readZeroString(Result))
+  if (auto EC = NameReader.readCString(Result))
     consumeError(std::move(EC));
   return Result;
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/StringTableBuilder.cpp Fri Feb 24 18:44:30 2017
@@ -52,7 +52,7 @@ uint32_t StringTableBuilder::finalize()
   return Size;
 }
 
-Error StringTableBuilder::commit(msf::StreamWriter &Writer) const {
+Error StringTableBuilder::commit(BinaryStreamWriter &Writer) const {
   // Write a header
   StringTableHeader H;
   H.Signature = StringTableSignature;
@@ -67,14 +67,14 @@ Error StringTableBuilder::commit(msf::St
     StringRef S = Pair.first;
     uint32_t Offset = Pair.second;
     Writer.setOffset(StringStart + Offset);
-    if (auto EC = Writer.writeZeroString(S))
+    if (auto EC = Writer.writeCString(S))
       return EC;
   }
   Writer.setOffset(StringStart + StringSize);
 
   // Write a hash table.
   uint32_t BucketCount = computeBucketCount(Strings.size());
-  if (auto EC = Writer.writeInteger(BucketCount, llvm::support::little))
+  if (auto EC = Writer.writeInteger(BucketCount))
     return EC;
   std::vector<ulittle32_t> Buckets(BucketCount);
 
@@ -96,8 +96,7 @@ Error StringTableBuilder::commit(msf::St
 
   if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets)))
     return EC;
-  if (auto EC = Writer.writeInteger(static_cast<uint32_t>(Strings.size()),
-                                    llvm::support::little))
+  if (auto EC = Writer.writeInteger(static_cast<uint32_t>(Strings.size())))
     return EC;
   return Error::success();
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/SymbolStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/SymbolStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/SymbolStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/SymbolStream.cpp Fri Feb 24 18:44:30 2017
@@ -17,6 +17,7 @@
 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Native/RawError.h"
 
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/Support/Endian.h"
 
 using namespace llvm;
@@ -30,7 +31,7 @@ SymbolStream::SymbolStream(std::unique_p
 SymbolStream::~SymbolStream() {}
 
 Error SymbolStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   if (auto EC = Reader.readArray(SymbolRecords, Stream->getLength()))
     return EC;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp Fri Feb 24 18:44:30 2017
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"
@@ -54,7 +55,7 @@ Error TpiStream::verifyHashValues() {
 }
 
 Error TpiStream::reload() {
-  StreamReader Reader(*Stream);
+  BinaryStreamReader Reader(*Stream);
 
   if (Reader.bytesRemaining() < sizeof(TpiStreamHeader))
     return make_error<RawError>(raw_error_code::corrupt_file,
@@ -93,7 +94,7 @@ Error TpiStream::reload() {
 
     auto HS = MappedBlockStream::createIndexedStream(
         Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex);
-    StreamReader HSR(*HS);
+    BinaryStreamReader HSR(*HS);
 
     uint32_t NumHashValues =
         Header->HashValueBuffer.Length / sizeof(ulittle32_t);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp Fri Feb 24 18:44:30 2017
@@ -34,7 +34,8 @@ using namespace llvm::pdb;
 using namespace llvm::support;
 
 TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
-    : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
+    : Msf(Msf), Allocator(Msf.getAllocator()),
+      TypeRecordStream(llvm::support::little), Header(nullptr), Idx(StreamIdx) {
 }
 
 TpiStreamBuilder::~TpiStreamBuilder() = default;
@@ -82,7 +83,7 @@ Error TpiStreamBuilder::finalize() {
   return Error::success();
 }
 
-uint32_t TpiStreamBuilder::calculateSerializedLength() const {
+uint32_t TpiStreamBuilder::calculateSerializedLength() {
   return sizeof(TpiStreamHeader) + TypeRecordStream.getLength();
 }
 
@@ -113,19 +114,20 @@ Error TpiStreamBuilder::finalizeMsfLayou
   }
   ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(HashBuffer.data()),
                           HashBufferSize);
-  HashValueStream = llvm::make_unique<ByteStream>(Bytes);
+  HashValueStream =
+      llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
   return Error::success();
 }
 
 Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
-                               const msf::WritableStream &Buffer) {
+                               WritableBinaryStreamRef Buffer) {
   if (auto EC = finalize())
     return EC;
 
   auto InfoS =
       WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Idx);
 
-  StreamWriter Writer(*InfoS);
+  BinaryStreamWriter Writer(*InfoS);
   if (auto EC = Writer.writeObject(*Header))
     return EC;
 
@@ -136,7 +138,7 @@ Error TpiStreamBuilder::commit(const msf
   if (HashStreamIndex != kInvalidStreamIndex) {
     auto HVS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
                                                               HashStreamIndex);
-    StreamWriter HW(*HVS);
+    BinaryStreamWriter HW(*HVS);
     if (auto EC = HW.writeStreamRef(*HashValueStream))
       return EC;
   }

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Fri Feb 24 18:44:30 2017
@@ -22,6 +22,7 @@
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/EnumTables.h"
@@ -450,7 +451,7 @@ Error LLVMOutputStyle::dumpStreamBytes()
     auto Blocks = File.getMsfLayout().StreamMap[SI];
     P.printList("Blocks", Blocks);
 
-    StreamReader R(*S);
+    BinaryStreamReader R(*S);
     ArrayRef<uint8_t> StreamData;
     if (auto EC = R.readBytes(StreamData, S->getLength()))
       return EC;
@@ -745,10 +746,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
           public:
             RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
             Error visitUnknown(ModuleSubstreamKind Kind,
-                               ReadableStreamRef Stream) override {
+                               BinaryStreamRef Stream) override {
               DictScope DD(P, "Unknown");
               ArrayRef<uint8_t> Data;
-              StreamReader R(Stream);
+              BinaryStreamReader R(Stream);
               if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
                 return make_error<RawError>(
                     raw_error_code::corrupt_file,
@@ -758,7 +759,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
               return Error::success();
             }
             Error
-            visitFileChecksums(ReadableStreamRef Data,
+            visitFileChecksums(BinaryStreamRef Data,
                                const FileChecksumArray &Checksums) override {
               DictScope DD(P, "FileChecksums");
               for (const auto &C : Checksums) {
@@ -774,7 +775,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
               return Error::success();
             }
 
-            Error visitLines(ReadableStreamRef Data,
+            Error visitLines(BinaryStreamRef Data,
                              const LineSubstreamHeader *Header,
                              const LineInfoArray &Lines) override {
               DictScope DD(P, "Lines");

Modified: llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp Fri Feb 24 18:44:30 2017
@@ -573,8 +573,8 @@ struct MappingContextTraits<pdb::yaml::P
     assert(IO.outputting());
     codeview::TypeVisitorCallbackPipeline Pipeline;
 
-    msf::ByteStream Data(Obj.Record.Data);
-    msf::StreamReader FieldReader(Data);
+    BinaryByteStream Data(Obj.Record.Data, llvm::support::little);
+    BinaryStreamReader FieldReader(Data);
     codeview::FieldListDeserializer Deserializer(FieldReader);
 
     // For PDB to Yaml, deserialize into a high level record type, then dump

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Fri Feb 24 18:44:30 2017
@@ -56,7 +56,6 @@
 using namespace llvm;
 using namespace llvm::object;
 using namespace llvm::codeview;
-using namespace llvm::msf;
 using namespace llvm::support;
 using namespace llvm::Win64EH;
 
@@ -155,7 +154,7 @@ public:
     Sec = Obj->getCOFFSection(SR);
   }
 
-  uint32_t getRecordOffset(msf::StreamReader Reader) override {
+  uint32_t getRecordOffset(BinaryStreamReader Reader) override {
     ArrayRef<uint8_t> Data;
     if (auto EC = Reader.readLongestContiguousChunk(Data)) {
       llvm::consumeError(std::move(EC));
@@ -841,13 +840,13 @@ void COFFDumper::printCodeViewSymbolSect
     }
     case ModuleSubstreamKind::FrameData: {
       // First four bytes is a relocation against the function.
-      msf::ByteStream S(Contents);
-      msf::StreamReader SR(S);
-      const uint32_t *CodePtr;
-      error(SR.readObject(CodePtr));
+      BinaryByteStream S(Contents, llvm::support::little);
+      BinaryStreamReader SR(S);
+      StringRef CodePtr;
+      error(SR.readFixedString(CodePtr, 4));
       StringRef LinkageName;
       error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents,
-                              CodePtr, LinkageName));
+                              CodePtr.data(), LinkageName));
       W.printString("LinkageName", LinkageName);
 
       // To find the active frame description, search this array for the
@@ -966,9 +965,9 @@ void COFFDumper::printCodeViewSymbolsSub
 
   CVSymbolDumper CVSD(W, TypeDB, std::move(CODD),
                       opts::CodeViewSubsectionBytes);
-  ByteStream Stream(BinaryData);
+  BinaryByteStream Stream(BinaryData, llvm::support::little);
   CVSymbolArray Symbols;
-  StreamReader Reader(Stream);
+  BinaryStreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
     consumeError(std::move(EC));
     W.flush();
@@ -983,8 +982,8 @@ void COFFDumper::printCodeViewSymbolsSub
 }
 
 void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
-  msf::ByteStream S(Subsection);
-  msf::StreamReader SR(S);
+  BinaryByteStream S(Subsection, llvm::support::little);
+  BinaryStreamReader SR(S);
   while (!SR.empty()) {
     DictScope S(W, "FileChecksum");
     const FileChecksum *FC;
@@ -1012,10 +1011,10 @@ void COFFDumper::printCodeViewFileChecks
 }
 
 void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
-  msf::ByteStream S(Subsection);
-  msf::StreamReader SR(S);
+  BinaryByteStream S(Subsection, llvm::support::little);
+  BinaryStreamReader SR(S);
   uint32_t Signature;
-  error(SR.readInteger(Signature, llvm::support::little));
+  error(SR.readInteger(Signature));
   bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles);
 
   while (!SR.empty()) {
@@ -1028,12 +1027,12 @@ void COFFDumper::printCodeViewInlineeLin
 
     if (HasExtraFiles) {
       uint32_t ExtraFileCount;
-      error(SR.readInteger(ExtraFileCount, llvm::support::little));
+      error(SR.readInteger(ExtraFileCount));
       W.printNumber("ExtraFileCount", ExtraFileCount);
       ListScope ExtraFiles(W, "ExtraFiles");
       for (unsigned I = 0; I < ExtraFileCount; ++I) {
         uint32_t FileID;
-        error(SR.readInteger(FileID, llvm::support::little));
+        error(SR.readInteger(FileID));
         printFileNameForOffset("FileID", FileID);
       }
     }
@@ -1078,9 +1077,9 @@ void COFFDumper::mergeCodeViewTypes(Type
         error(object_error::parse_failed);
       ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
                               Data.size());
-      ByteStream Stream(Bytes);
+      BinaryByteStream Stream(Bytes, llvm::support::little);
       CVTypeArray Types;
-      StreamReader Reader(Stream);
+      BinaryStreamReader Reader(Stream);
       if (auto EC = Reader.readArray(Types, Reader.getLength())) {
         consumeError(std::move(EC));
         W.flush();

Added: llvm/trunk/unittests/DebugInfo/PDB/BinaryStreamTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/BinaryStreamTest.cpp?rev=296215&view=auto
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/BinaryStreamTest.cpp (added)
+++ llvm/trunk/unittests/DebugInfo/PDB/BinaryStreamTest.cpp Fri Feb 24 18:44:30 2017
@@ -0,0 +1,764 @@
+//===- llvm/unittest/Support/BinaryStreamTest.cpp -------------------------===//
+//
+//                     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/BinaryByteStream.h"
+#include "llvm/DebugInfo/MSF/BinaryItemStream.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
+#include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
+#include "gtest/gtest.h"
+
+#include <unordered_map>
+
+using namespace llvm;
+using namespace llvm::support;
+
+#define EXPECT_NO_ERROR(Err)                                                   \
+  {                                                                            \
+    auto E = Err;                                                              \
+    EXPECT_FALSE(static_cast<bool>(E));                                        \
+    if (E)                                                                     \
+      consumeError(std::move(E));                                              \
+  }
+
+#define ASSERT_NO_ERROR(Err)                                                   \
+  {                                                                            \
+    auto E = Err;                                                              \
+    ASSERT_FALSE(static_cast<bool>(E));                                        \
+    if (E)                                                                     \
+      consumeError(std::move(E));                                              \
+  }
+
+#define EXPECT_ERROR(Err)                                                      \
+  {                                                                            \
+    auto E = Err;                                                              \
+    EXPECT_TRUE(static_cast<bool>(E));                                         \
+    if (E)                                                                     \
+      consumeError(std::move(E));                                              \
+  }
+
+namespace {
+
+class DiscontiguousStream : public WritableBinaryStream {
+public:
+  explicit DiscontiguousStream(uint32_t Size = 0) : PartitionIndex(Size / 2) {
+    Data.resize(Size);
+  }
+
+  endianness getEndian() const override { return little; }
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) override {
+    if (Offset + Size > Data.size())
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+    uint32_t S = startIndex(Offset);
+    auto Ref = makeArrayRef(Data).drop_front(S);
+    if (Ref.size() >= Size) {
+      Buffer = Ref.take_front(Size);
+      return Error::success();
+    }
+
+    uint32_t BytesLeft = Size - Ref.size();
+    uint8_t *Ptr = Allocator.Allocate<uint8_t>(Size);
+    ::memcpy(Ptr, Ref.data(), Ref.size());
+    ::memcpy(Ptr + Ref.size(), Data.data(), BytesLeft);
+    Buffer = makeArrayRef<uint8_t>(Ptr, Size);
+    return Error::success();
+  }
+
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) override {
+    if (Offset >= Data.size())
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+    uint32_t S = startIndex(Offset);
+    Buffer = makeArrayRef(Data).drop_front(S);
+    return Error::success();
+  }
+
+  uint32_t getLength() override { return Data.size(); }
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) override {
+    if (Offset + SrcData.size() > Data.size())
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
+    if (SrcData.empty())
+      return Error::success();
+
+    uint32_t S = startIndex(Offset);
+    MutableArrayRef<uint8_t> Ref(Data);
+    Ref = Ref.drop_front(S);
+    if (Ref.size() >= SrcData.size()) {
+      ::memcpy(Ref.data(), SrcData.data(), SrcData.size());
+      return Error::success();
+    }
+
+    uint32_t BytesLeft = SrcData.size() - Ref.size();
+    ::memcpy(Ref.data(), SrcData.data(), Ref.size());
+    ::memcpy(&Data[0], SrcData.data() + Ref.size(), BytesLeft);
+    return Error::success();
+  }
+  Error commit() override { return Error::success(); }
+
+private:
+  uint32_t startIndex(uint32_t Offset) const {
+    return (Offset + PartitionIndex) % Data.size();
+  }
+
+  uint32_t endIndex(uint32_t Offset, uint32_t Size) const {
+    return (startIndex(Offset) + Size - 1) % Data.size();
+  }
+
+  uint32_t PartitionIndex = 0;
+  // Buffer is organized like this:
+  // -------------------------------------------------
+  // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N-2-1 |
+  // -------------------------------------------------
+  // So reads from the beginning actually come from the middle.
+  std::vector<uint8_t> Data;
+  BumpPtrAllocator Allocator;
+};
+
+class BinaryStreamTest : public testing::Test {
+public:
+  BinaryStreamTest() {}
+
+  void SetUp() override {
+    InputData.clear();
+    OutputData.clear();
+    InputByteStream = BinaryByteStream();
+    InputBrokenStream = DiscontiguousStream();
+    OutputByteStream = MutableBinaryByteStream();
+    OutputBrokenStream = DiscontiguousStream();
+  }
+
+protected:
+  void initialize(ArrayRef<uint8_t> Input, uint32_t OutputSize) {
+    InputData = Input;
+
+    InputByteStream = BinaryByteStream(InputData, little);
+    InputBrokenStream = DiscontiguousStream(InputData.size());
+    consumeError(InputBrokenStream.writeBytes(0, Input));
+
+    OutputData.resize(OutputSize);
+    OutputByteStream = MutableBinaryByteStream(OutputData, little);
+    OutputBrokenStream = DiscontiguousStream(OutputSize);
+
+    InputStreams.push_back(&InputByteStream);
+    InputStreams.push_back(&InputBrokenStream);
+    OutputStreams.push_back(&OutputByteStream);
+    OutputStreams.push_back(&OutputBrokenStream);
+  }
+
+  void initialize(uint32_t OutputSize) {
+    OutputData.resize(OutputSize);
+    OutputByteStream = MutableBinaryByteStream(OutputData, little);
+    OutputBrokenStream = DiscontiguousStream(OutputSize);
+    OutputStreams.push_back(&OutputByteStream);
+    OutputStreams.push_back(&OutputBrokenStream);
+
+    InputByteStream = BinaryByteStream(OutputData, little);
+    InputBrokenStream = DiscontiguousStream(OutputData.size());
+  }
+
+  std::vector<uint8_t> InputData;
+  std::vector<uint8_t> OutputData;
+
+  BinaryByteStream InputByteStream;
+  DiscontiguousStream InputBrokenStream;
+
+  MutableBinaryByteStream OutputByteStream;
+  DiscontiguousStream OutputBrokenStream;
+
+  std::vector<BinaryStream *> InputStreams;
+  std::vector<WritableBinaryStream *> OutputStreams;
+};
+
+// Tests that a we can read from a BinaryByteStream without a StreamReader.
+TEST_F(BinaryStreamTest, BinaryByteStreamProperties) {
+  std::vector<uint8_t> InputData = {1, 2, 3, 4, 5};
+  initialize(InputData, InputData.size());
+
+  for (auto Stream : InputStreams) {
+    ArrayRef<uint8_t> Buffer;
+
+    // 1. If the read fits it should work.
+    ASSERT_EQ(InputData.size(), Stream->getLength());
+    ASSERT_NO_ERROR(Stream->readBytes(2, 1, Buffer));
+    EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
+    ASSERT_NO_ERROR(Stream->readBytes(0, 4, Buffer));
+    EXPECT_EQ(makeArrayRef(InputData).slice(0, 4), Buffer);
+
+    // 2. Reading past the bounds of the input should fail.
+    EXPECT_ERROR(Stream->readBytes(4, 2, Buffer));
+  }
+}
+
+// Test that we can write to a BinaryStream without a StreamWriter.
+TEST_F(BinaryStreamTest, MutableBinaryByteStreamProperties) {
+  std::vector<uint8_t> InputData = {'T', 'e', 's', 't', '\0'};
+  initialize(InputData, InputData.size());
+  ASSERT_EQ(2U, InputStreams.size());
+  ASSERT_EQ(2U, OutputStreams.size());
+
+  // For every combination of input stream and output stream.
+  for (auto IS : InputStreams) {
+    MutableArrayRef<uint8_t> Buffer;
+    ASSERT_EQ(InputData.size(), IS->getLength());
+
+    for (auto OS : OutputStreams) {
+
+      // 1. Try two reads that are supposed to work.  One from offset 0, and one
+      // from the middle.
+      uint32_t Offsets[] = {0, 3};
+      for (auto Offset : Offsets) {
+        uint32_t ExpectedSize = IS->getLength() - Offset;
+
+        // Read everything from Offset until the end of the input data.
+        ArrayRef<uint8_t> Data;
+        ASSERT_NO_ERROR(IS->readBytes(Offset, ExpectedSize, Data));
+        ASSERT_EQ(ExpectedSize, Data.size());
+
+        // Then write it to the destination.
+        ASSERT_NO_ERROR(OS->writeBytes(0, Data));
+
+        // Then we read back what we wrote, it should match the corresponding
+        // slice
+        // of the original input data.
+        ArrayRef<uint8_t> Data2;
+        ASSERT_NO_ERROR(OS->readBytes(Offset, ExpectedSize, Data2));
+        EXPECT_EQ(makeArrayRef(InputData).drop_front(Offset), Data2);
+      }
+
+      std::vector<uint8_t> BigData = {0, 1, 2, 3, 4};
+      // 2. If the write is too big, it should fail.
+      EXPECT_ERROR(OS->writeBytes(3, BigData));
+    }
+  }
+}
+
+// Test that FixedStreamArray works correctly.
+TEST_F(BinaryStreamTest, FixedStreamArray) {
+  std::vector<uint32_t> Ints = {90823, 12908, 109823, 209823};
+  ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(Ints.data()),
+                             Ints.size() * sizeof(uint32_t));
+
+  initialize(IntBytes, 0);
+  ASSERT_EQ(2U, InputStreams.size());
+
+  for (auto IS : InputStreams) {
+    MutableArrayRef<uint8_t> Buffer;
+    ASSERT_EQ(InputData.size(), IS->getLength());
+
+    FixedStreamArray<uint32_t> Array(*IS);
+    auto Iter = Array.begin();
+    ASSERT_EQ(Ints[0], *Iter++);
+    ASSERT_EQ(Ints[1], *Iter++);
+    ASSERT_EQ(Ints[2], *Iter++);
+    ASSERT_EQ(Ints[3], *Iter++);
+    ASSERT_EQ(Array.end(), Iter);
+  }
+}
+
+// Test that VarStreamArray works correctly.
+TEST_F(BinaryStreamTest, VarStreamArray) {
+  StringLiteral Strings("1. Test2. Longer Test3. Really Long Test4. Super "
+                        "Extra Longest Test Of All");
+  ArrayRef<uint8_t> StringBytes(
+      reinterpret_cast<const uint8_t *>(Strings.data()), Strings.size());
+  initialize(StringBytes, 0);
+
+  struct StringExtractor {
+  public:
+    Error operator()(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item) {
+      if (Index == 0)
+        Len = strlen("1. Test");
+      else if (Index == 1)
+        Len = strlen("2. Longer Test");
+      else if (Index == 2)
+        Len = strlen("3. Really Long Test");
+      else
+        Len = strlen("4. Super Extra Longest Test Of All");
+      ArrayRef<uint8_t> Bytes;
+      if (auto EC = Stream.readBytes(0, Len, Bytes))
+        return EC;
+      Item =
+          StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
+      ++Index;
+      return Error::success();
+    }
+
+  private:
+    uint32_t Index = 0;
+  };
+
+  for (auto IS : InputStreams) {
+    VarStreamArray<StringRef, StringExtractor> Array(*IS);
+    auto Iter = Array.begin();
+    ASSERT_EQ("1. Test", *Iter++);
+    ASSERT_EQ("2. Longer Test", *Iter++);
+    ASSERT_EQ("3. Really Long Test", *Iter++);
+    ASSERT_EQ("4. Super Extra Longest Test Of All", *Iter++);
+    ASSERT_EQ(Array.end(), Iter);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderBounds) {
+  std::vector<uint8_t> Bytes;
+
+  initialize(Bytes, 0);
+  for (auto IS : InputStreams) {
+    StringRef S;
+    BinaryStreamReader Reader(*IS);
+    EXPECT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_ERROR(Reader.readFixedString(S, 1));
+  }
+
+  Bytes.resize(5);
+  initialize(Bytes, 0);
+  for (auto IS : InputStreams) {
+    StringRef S;
+    BinaryStreamReader Reader(*IS);
+    EXPECT_EQ(Bytes.size(), Reader.bytesRemaining());
+    EXPECT_NO_ERROR(Reader.readFixedString(S, 5));
+    EXPECT_ERROR(Reader.readFixedString(S, 6));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderIntegers) {
+  support::ulittle64_t Little{908234};
+  support::ubig32_t Big{28907823};
+  short NS = 2897;
+  int NI = -89723;
+  unsigned long NUL = 902309023UL;
+  constexpr uint32_t Size =
+      sizeof(Little) + sizeof(Big) + sizeof(NS) + sizeof(NI) + sizeof(NUL);
+  std::vector<uint8_t> Bytes(Size);
+  uint8_t *Ptr = &Bytes[0];
+  memcpy(Ptr, &Little, sizeof(Little));
+  Ptr += sizeof(Little);
+  memcpy(Ptr, &Big, sizeof(Big));
+  Ptr += sizeof(Big);
+  memcpy(Ptr, &NS, sizeof(NS));
+  Ptr += sizeof(NS);
+  memcpy(Ptr, &NI, sizeof(NI));
+  Ptr += sizeof(NI);
+  memcpy(Ptr, &NUL, sizeof(NUL));
+  Ptr += sizeof(NUL);
+
+  initialize(Bytes, 0);
+  for (auto IS : InputStreams) {
+    const support::ulittle64_t *Little2;
+    const support::ubig32_t *Big2;
+    short NS2;
+    int NI2;
+    unsigned long NUL2;
+
+    // 1. Reading fields individually.
+    BinaryStreamReader Reader(*IS);
+    ASSERT_NO_ERROR(Reader.readObject(Little2));
+    ASSERT_NO_ERROR(Reader.readObject(Big2));
+    ASSERT_NO_ERROR(Reader.readInteger(NS2));
+    ASSERT_NO_ERROR(Reader.readInteger(NI2));
+    ASSERT_NO_ERROR(Reader.readInteger(NUL2));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ(Little, *Little2);
+    EXPECT_EQ(Big, *Big2);
+    EXPECT_EQ(NS, NS2);
+    EXPECT_EQ(NI, NI2);
+    EXPECT_EQ(NUL, NUL2);
+
+    // 2. Reading with explicit endianness.
+    Reader.setOffset(0);
+    const ulittle64_t *Little3;
+    const ubig32_t *Big3;
+    ASSERT_NO_ERROR(Reader.readObject(Little3));
+    ASSERT_NO_ERROR(Reader.readObject(Big3));
+    EXPECT_EQ(Little, *Little3);
+    EXPECT_EQ(Big, *Big3);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderIntegerArray) {
+  // 1. Arrays of integers
+  std::vector<int> Ints = {1, 2, 3, 4, 5};
+  ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(&Ints[0]),
+                             Ints.size() * sizeof(int));
+  initialize(IntBytes, 0);
+  for (auto IS : InputStreams) {
+    BinaryStreamReader Reader(*IS);
+    ArrayRef<int> IntsRef;
+    ASSERT_NO_ERROR(Reader.readArray(IntsRef, Ints.size()));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_EQ(makeArrayRef(Ints), IntsRef);
+
+    Reader.setOffset(0);
+    FixedStreamArray<int> FixedIntsRef;
+    ASSERT_NO_ERROR(Reader.readArray(FixedIntsRef, Ints.size()));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+    ASSERT_EQ(Ints, std::vector<int>(FixedIntsRef.begin(), FixedIntsRef.end()));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderEnum) {
+  enum class MyEnum : int64_t { Foo = -10, Bar = 0, Baz = 10 };
+
+  std::vector<MyEnum> Enums = {MyEnum::Bar, MyEnum::Baz, MyEnum::Foo};
+
+  ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(&Enums[0]),
+                          sizeof(MyEnum) * Enums.size());
+
+  initialize(Bytes, 0);
+  for (auto IS : InputStreams) {
+    BinaryStreamReader Reader(*IS);
+
+    MyEnum V1;
+    MyEnum V2;
+    MyEnum V3;
+    ArrayRef<MyEnum> Array;
+    FixedStreamArray<MyEnum> FSA;
+
+    ASSERT_NO_ERROR(Reader.readEnum(V1));
+    ASSERT_NO_ERROR(Reader.readEnum(V2));
+    ASSERT_NO_ERROR(Reader.readEnum(V3));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ(MyEnum::Bar, V1);
+    EXPECT_EQ(MyEnum::Baz, V2);
+    EXPECT_EQ(MyEnum::Foo, V3);
+
+    Reader.setOffset(0);
+    ASSERT_NO_ERROR(Reader.readArray(Array, 3));
+    EXPECT_EQ(makeArrayRef(Enums), Array);
+
+    Reader.setOffset(0);
+    ASSERT_NO_ERROR(Reader.readArray(FSA, 3));
+    EXPECT_EQ(Enums, std::vector<MyEnum>(FSA.begin(), FSA.end()));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderObject) {
+  struct Foo {
+    int X;
+    double Y;
+    char Z;
+  };
+
+  std::vector<Foo> Foos;
+  Foos.push_back({-42, 42.42, 42});
+  Foos.push_back({100, 3.1415, -89});
+
+  std::vector<uint8_t> Bytes;
+  Bytes.resize(2 * sizeof(Foo));
+  Foo *FPtr = reinterpret_cast<Foo *>(&Bytes[0]);
+  Foo *GPtr = FPtr + 1;
+
+  ::memcpy(FPtr, &Foos[0], sizeof(Foo));
+  ::memcpy(GPtr + sizeof(Foo), &Foos[1], sizeof(Foo));
+
+  initialize(Bytes, 0);
+
+  for (auto IS : InputStreams) {
+    // 1. Reading object pointers.
+    BinaryStreamReader Reader(*IS);
+    const Foo *FPtrOut = nullptr;
+    const Foo *GPtrOut = nullptr;
+    ASSERT_NO_ERROR(Reader.readObject(FPtrOut));
+    ASSERT_NO_ERROR(Reader.readObject(GPtrOut));
+    EXPECT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_EQ(0, ::memcmp(FPtr, FPtrOut, sizeof(Foo)));
+    EXPECT_EQ(0, ::memcmp(GPtr, GPtrOut, sizeof(Foo)));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderStrings) {
+  std::vector<uint8_t> Bytes = {'O',  'n', 'e', '\0', 'T', 'w', 'o',
+                                '\0', 'T', 'h', 'r',  'e', 'e', '\0',
+                                'F',  'o', 'u', 'r',  '\0'};
+  initialize(Bytes, 0);
+
+  for (auto IS : InputStreams) {
+    BinaryStreamReader Reader(*IS);
+
+    StringRef S1;
+    StringRef S2;
+    StringRef S3;
+    StringRef S4;
+    ASSERT_NO_ERROR(Reader.readCString(S1));
+    ASSERT_NO_ERROR(Reader.readCString(S2));
+    ASSERT_NO_ERROR(Reader.readCString(S3));
+    ASSERT_NO_ERROR(Reader.readCString(S4));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ("One", S1);
+    EXPECT_EQ("Two", S2);
+    EXPECT_EQ("Three", S3);
+    EXPECT_EQ("Four", S4);
+
+    S1 = S2 = S3 = S4 = "";
+    Reader.setOffset(0);
+    ASSERT_NO_ERROR(Reader.readFixedString(S1, 3));
+    ASSERT_NO_ERROR(Reader.skip(1));
+    ASSERT_NO_ERROR(Reader.readFixedString(S2, 3));
+    ASSERT_NO_ERROR(Reader.skip(1));
+    ASSERT_NO_ERROR(Reader.readFixedString(S3, 5));
+    ASSERT_NO_ERROR(Reader.skip(1));
+    ASSERT_NO_ERROR(Reader.readFixedString(S4, 4));
+    ASSERT_NO_ERROR(Reader.skip(1));
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ("One", S1);
+    EXPECT_EQ("Two", S2);
+    EXPECT_EQ("Three", S3);
+    EXPECT_EQ("Four", S4);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterBounds) {
+  initialize(5);
+
+  for (auto OS : OutputStreams) {
+    BinaryStreamWriter Writer(*OS);
+
+    // 1. Can write a string that exactly fills the buffer.
+    EXPECT_EQ(5U, Writer.bytesRemaining());
+    EXPECT_NO_ERROR(Writer.writeFixedString("abcde"));
+    EXPECT_EQ(0U, Writer.bytesRemaining());
+
+    // 2. Can write an empty string even when you're full
+    EXPECT_NO_ERROR(Writer.writeFixedString(""));
+    EXPECT_ERROR(Writer.writeFixedString("a"));
+
+    // 3. Can't write a string that is one character too long.
+    Writer.setOffset(0);
+    EXPECT_ERROR(Writer.writeFixedString("abcdef"));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterIntegers) {
+  support::ulittle64_t Little{908234};
+  support::ubig32_t Big{28907823};
+  short NS = 2897;
+  int NI = -89723;
+  unsigned long NUL = 902309023UL;
+  constexpr uint32_t Size =
+      sizeof(Little) + sizeof(Big) + sizeof(NS) + sizeof(NI) + sizeof(NUL);
+
+  initialize(Size);
+
+  for (auto OS : OutputStreams) {
+    BinaryStreamWriter Writer(*OS);
+
+    // 1. Writing fields individually.
+    ASSERT_NO_ERROR(Writer.writeObject(Little));
+    ASSERT_NO_ERROR(Writer.writeObject(Big));
+    ASSERT_NO_ERROR(Writer.writeInteger(NS));
+    ASSERT_NO_ERROR(Writer.writeInteger(NI));
+    ASSERT_NO_ERROR(Writer.writeInteger(NUL));
+    ASSERT_EQ(0U, Writer.bytesRemaining());
+
+    // Read them back in and confirm they're correct.
+    const ulittle64_t *Little2;
+    const ubig32_t *Big2;
+    short NS2;
+    int NI2;
+    unsigned long NUL2;
+    BinaryStreamReader Reader(*OS);
+    ASSERT_NO_ERROR(Reader.readObject(Little2));
+    ASSERT_NO_ERROR(Reader.readObject(Big2));
+    ASSERT_NO_ERROR(Reader.readInteger(NS2));
+    ASSERT_NO_ERROR(Reader.readInteger(NI2));
+    ASSERT_NO_ERROR(Reader.readInteger(NUL2));
+    EXPECT_EQ(Little, *Little2);
+    EXPECT_EQ(Big, *Big2);
+    EXPECT_EQ(NS, NS2);
+    EXPECT_EQ(NI, NI2);
+    EXPECT_EQ(NUL, NUL2);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterIntegerArrays) {
+  // 3. Arrays of integers
+  std::vector<int> SourceInts = {1, 2, 3, 4, 5};
+  ArrayRef<uint8_t> SourceBytes(reinterpret_cast<uint8_t *>(&SourceInts[0]),
+                                SourceInts.size() * sizeof(int));
+
+  initialize(SourceBytes, SourceBytes.size());
+
+  for (auto IS : InputStreams) {
+    for (auto OS : OutputStreams) {
+      BinaryStreamReader Reader(*IS);
+      BinaryStreamWriter Writer(*OS);
+      ArrayRef<int> Ints;
+      ArrayRef<int> Ints2;
+      // First read them, then write them, then read them back.
+      ASSERT_NO_ERROR(Reader.readArray(Ints, SourceInts.size()));
+      ASSERT_NO_ERROR(Writer.writeArray(Ints));
+
+      BinaryStreamReader ReaderBacker(*OS);
+      ASSERT_NO_ERROR(ReaderBacker.readArray(Ints2, SourceInts.size()));
+
+      EXPECT_EQ(makeArrayRef(SourceInts), Ints2);
+    }
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterEnum) {
+  enum class MyEnum : int64_t { Foo = -10, Bar = 0, Baz = 10 };
+
+  std::vector<MyEnum> Expected = {MyEnum::Bar, MyEnum::Foo, MyEnum::Baz};
+
+  initialize(Expected.size() * sizeof(MyEnum));
+
+  for (auto OS : OutputStreams) {
+    BinaryStreamWriter Writer(*OS);
+    ArrayRef<MyEnum> Enums;
+    ArrayRef<MyEnum> Enums2;
+
+    // First read them, then write them, then read them back.
+    for (auto ME : Expected)
+      ASSERT_NO_ERROR(Writer.writeEnum(ME));
+
+    ArrayRef<MyEnum> Array;
+    BinaryStreamReader Reader(*OS);
+    ASSERT_NO_ERROR(Reader.readArray(Array, Expected.size()));
+
+    EXPECT_EQ(makeArrayRef(Expected), Array);
+  }
+}
+
+TEST_F(BinaryStreamTest, StringWriterStrings) {
+  StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
+
+  size_t Length = 0;
+  for (auto S : Strings)
+    Length += S.size() + 1;
+  initialize(Length);
+
+  for (auto OS : OutputStreams) {
+    BinaryStreamWriter Writer(*OS);
+    for (auto S : Strings)
+      ASSERT_NO_ERROR(Writer.writeCString(S));
+
+    for (auto IS : InputStreams) {
+      std::vector<StringRef> InStrings;
+      BinaryStreamReader Reader(*IS);
+      while (!Reader.empty()) {
+        StringRef S;
+        ASSERT_NO_ERROR(Reader.readCString(S));
+        InStrings.push_back(S);
+      }
+      EXPECT_EQ(makeArrayRef(Strings), makeArrayRef(InStrings));
+    }
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderIntegersVariadic) {
+  uint8_t A = 201;
+  int8_t A2 = -92;
+  uint16_t B = 20823;
+  int16_t B2 = -20823;
+  uint32_t C = 8978251;
+  int32_t C2 = -8978251;
+  uint64_t D = 90278410232ULL;
+  int64_t D2 = -90278410232LL;
+
+  initialize(2 * (sizeof(A) + sizeof(B) + sizeof(C) + sizeof(D)));
+
+  for (auto OS : OutputStreams) {
+    BinaryStreamWriter Writer(*OS);
+    ASSERT_NO_ERROR(Writer.writeIntegers(A, A2, B, B2, C, C2, D, D2));
+
+    for (auto IS : InputStreams) {
+      BinaryStreamReader Reader(*IS);
+      uint8_t AX;
+      int8_t AX2;
+      uint16_t BX;
+      int16_t BX2;
+      uint32_t CX;
+      int32_t CX2;
+      uint64_t DX;
+      int64_t DX2;
+
+      ASSERT_NO_ERROR(Reader.readIntegers(AX, AX2, BX, BX2, CX, CX2, DX, DX2));
+      EXPECT_EQ(A, AX);
+      EXPECT_EQ(A2, AX2);
+      EXPECT_EQ(B, BX);
+      EXPECT_EQ(B2, BX2);
+      EXPECT_EQ(C, CX);
+      EXPECT_EQ(C2, CX2);
+      EXPECT_EQ(D, DX);
+      EXPECT_EQ(D2, DX2);
+    }
+  }
+}
+}
+
+namespace {
+struct BinaryItemStreamObject {
+  BinaryItemStreamObject(int X, float Y) : X(X), Y(Y) {}
+
+  int X;
+  float Y;
+};
+}
+
+namespace llvm {
+template <> struct BinaryItemTraits<std::unique_ptr<BinaryItemStreamObject>> {
+  size_t length(const std::unique_ptr<BinaryItemStreamObject> &Item) {
+    size_t S = sizeof(Item->X);
+    S += sizeof(Item->Y);
+    return S;
+  }
+
+  ArrayRef<uint8_t> bytes(const std::unique_ptr<BinaryItemStreamObject> &Item) {
+    // In practice we probably would use a more cheaply serializable type,
+    // or at the very least not allocate every single time.  This is just
+    // for illustration and testing though.
+    size_t Size = length(Item);
+    uint8_t *Buffer = Alloc.Allocate<uint8_t>(Size);
+    MutableBinaryByteStream Stream(MutableArrayRef<uint8_t>(Buffer, Size),
+                                   little);
+    BinaryStreamWriter Writer(Stream);
+    consumeError(Writer.writeInteger(Item->X));
+    consumeError(Writer.writeObject(Item->Y));
+    return makeArrayRef(Buffer, Size);
+  }
+
+private:
+  BumpPtrAllocator Alloc;
+};
+}
+
+namespace {
+
+TEST_F(BinaryStreamTest, BinaryItemStream) {
+  // Note that this is a vector of pointers, so individual records do not live
+  // contiguously in memory.
+  std::vector<std::unique_ptr<BinaryItemStreamObject>> Objects;
+  Objects.push_back(llvm::make_unique<BinaryItemStreamObject>(1, 1.0));
+  Objects.push_back(llvm::make_unique<BinaryItemStreamObject>(2, 2.0));
+  Objects.push_back(llvm::make_unique<BinaryItemStreamObject>(3, 3.0));
+
+  BinaryItemStream<std::unique_ptr<BinaryItemStreamObject>> ItemStream(little);
+  ItemStream.setItems(Objects);
+  BinaryStreamReader Reader(ItemStream);
+
+  for (int I = 0; I < 3; ++I) {
+    int X;
+    const float *Y;
+    ASSERT_NO_ERROR(Reader.readInteger(X));
+    ASSERT_NO_ERROR(Reader.readObject(Y));
+
+    EXPECT_EQ(Objects[I]->X, X);
+    EXPECT_DOUBLE_EQ(Objects[I]->Y, *Y);
+  }
+}
+
+} // end anonymous namespace

Modified: llvm/trunk/unittests/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/CMakeLists.txt?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/CMakeLists.txt Fri Feb 24 18:44:30 2017
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 set(DebugInfoPDBSources
+  BinaryStreamTest.cpp
   HashTableTest.cpp
   MappedBlockStreamTest.cpp
   StringTableBuilderTest.cpp

Modified: llvm/trunk/unittests/DebugInfo/PDB/HashTableTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/HashTableTest.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/HashTableTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/HashTableTest.cpp Fri Feb 24 18:44:30 2017
@@ -19,6 +19,7 @@
 
 using namespace llvm;
 using namespace llvm::pdb;
+using namespace llvm::support;
 
 namespace {
 class HashTableInternals : public HashTable {
@@ -147,14 +148,14 @@ TEST(HashTableTest, Serialization) {
   }
 
   std::vector<uint8_t> Buffer(Table.calculateSerializedLength());
-  msf::MutableByteStream Stream(Buffer);
-  msf::StreamWriter Writer(Stream);
+  MutableBinaryByteStream Stream(Buffer, little);
+  BinaryStreamWriter Writer(Stream);
   EXPECT_NO_ERROR(Table.commit(Writer));
   // We should have written precisely the number of bytes we calculated earlier.
   EXPECT_EQ(Buffer.size(), Writer.getOffset());
 
   HashTableInternals Table2;
-  msf::StreamReader Reader(Stream);
+  BinaryStreamReader Reader(Stream);
   EXPECT_NO_ERROR(Table2.load(Reader));
   // We should have read precisely the number of bytes we calculated earlier.
   EXPECT_EQ(Buffer.size(), Reader.getOffset());

Modified: llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp Fri Feb 24 18:44:30 2017
@@ -22,13 +22,14 @@
 
 using namespace llvm;
 using namespace llvm::msf;
+using namespace llvm::support;
 
 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 DiscontiguousStream : public WritableStream {
+class DiscontiguousStream : public WritableBinaryStream {
 public:
   DiscontiguousStream(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
       : Blocks(Blocks.begin(), Blocks.end()), Data(Data.begin(), Data.end()) {}
@@ -36,31 +37,33 @@ public:
   uint32_t block_size() const { return 1; }
   uint32_t block_count() const { return Blocks.size(); }
 
+  endianness getEndian() const { return little; }
+
   Error readBytes(uint32_t Offset, uint32_t Size,
-                  ArrayRef<uint8_t> &Buffer) const override {
+                  ArrayRef<uint8_t> &Buffer) override {
     if (Offset + Size > Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     Buffer = Data.slice(Offset, Size);
     return Error::success();
   }
 
   Error readLongestContiguousChunk(uint32_t Offset,
-                                   ArrayRef<uint8_t> &Buffer) const override {
+                                   ArrayRef<uint8_t> &Buffer) override {
     if (Offset >= Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     Buffer = Data.drop_front(Offset);
     return Error::success();
   }
 
-  uint32_t getLength() const override { return Data.size(); }
+  uint32_t getLength() override { return Data.size(); }
 
-  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) const override {
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) override {
     if (Offset + SrcData.size() > Data.size())
-      return make_error<MSFError>(msf_error_code::insufficient_buffer);
+      return errorCodeToError(make_error_code(std::errc::no_buffer_space));
     ::memcpy(&Data[Offset], SrcData.data(), SrcData.size());
     return Error::success();
   }
-  Error commit() const override { return Error::success(); }
+  Error commit() override { return Error::success(); }
 
   MSFStreamLayout layout() const {
     return MSFStreamLayout{static_cast<uint32_t>(Data.size()), Blocks};
@@ -78,8 +81,8 @@ TEST(MappedBlockStreamTest, ReadBeyondEn
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
 
-  StreamReader R(*S);
-  ReadableStreamRef SR;
+  BinaryStreamReader R(*S);
+  BinaryStreamRef SR;
   EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
   ArrayRef<uint8_t> Buffer;
   EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
@@ -94,7 +97,7 @@ TEST(MappedBlockStreamTest, ReadOntoNonE
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
 
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
   EXPECT_NO_ERROR(R.readFixedString(Str, 1));
   EXPECT_EQ(Str, StringRef("A"));
@@ -108,7 +111,7 @@ TEST(MappedBlockStreamTest, ZeroCopyRead
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 2));
   EXPECT_EQ(Str, StringRef("AB"));
@@ -127,7 +130,7 @@ TEST(MappedBlockStreamTest, CopyReadNonC
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 10));
   EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
@@ -140,7 +143,7 @@ TEST(MappedBlockStreamTest, InvalidReadS
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
 
   R.setOffset(10);
@@ -154,7 +157,7 @@ TEST(MappedBlockStreamTest, InvalidReadS
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
 
   R.setOffset(6);
@@ -168,7 +171,7 @@ TEST(MappedBlockStreamTest, InvalidReadS
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
 
   EXPECT_ERROR(R.readFixedString(Str, 11));
@@ -181,7 +184,7 @@ TEST(MappedBlockStreamTest, ZeroCopyRead
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str;
   EXPECT_NO_ERROR(R.readFixedString(Str, 1));
   EXPECT_EQ(Str, StringRef("A"));
@@ -195,7 +198,7 @@ TEST(MappedBlockStreamTest, UnalignedOve
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str1;
   StringRef Str2;
   EXPECT_NO_ERROR(R.readFixedString(Str1, 7));
@@ -216,7 +219,7 @@ TEST(MappedBlockStreamTest, UnalignedOve
   DiscontiguousStream F(BlocksAry, DataAry);
   auto S = MappedBlockStream::createStream(F.block_size(), F.block_count(),
                                            F.layout(), F);
-  StreamReader R(*S);
+  BinaryStreamReader R(*S);
   StringRef Str1;
   StringRef Str2;
   EXPECT_NO_ERROR(R.readFixedString(Str1, 6));
@@ -323,10 +326,10 @@ TEST(MappedBlockStreamTest, TestWriteThe
   uint32_t intArr1[] = {890723408, 29082234};
   ArrayRef<uint32_t> intArray[] = {intArr0, intArr1};
 
-  StreamReader Reader(*S);
-  StreamWriter Writer(*S);
-  EXPECT_NO_ERROR(Writer.writeInteger(u16[0], llvm::support::little));
-  EXPECT_NO_ERROR(Reader.readInteger(u16[1], llvm::support::little));
+  BinaryStreamReader Reader(*S);
+  BinaryStreamWriter Writer(*S);
+  EXPECT_NO_ERROR(Writer.writeInteger(u16[0]));
+  EXPECT_NO_ERROR(Reader.readInteger(u16[1]));
   EXPECT_EQ(u16[0], u16[1]);
   EXPECT_EQ(std::vector<uint8_t>({0, 0x7A, 0xEC, 0, 0, 0, 0, 0, 0, 0}),
             DataBytes);
@@ -334,8 +337,8 @@ TEST(MappedBlockStreamTest, TestWriteThe
   Reader.setOffset(0);
   Writer.setOffset(0);
   ::memset(DataBytes.data(), 0, 10);
-  EXPECT_NO_ERROR(Writer.writeInteger(u32[0], llvm::support::little));
-  EXPECT_NO_ERROR(Reader.readInteger(u32[1], llvm::support::little));
+  EXPECT_NO_ERROR(Writer.writeInteger(u32[0]));
+  EXPECT_NO_ERROR(Reader.readInteger(u32[1]));
   EXPECT_EQ(u32[0], u32[1]);
   EXPECT_EQ(std::vector<uint8_t>({0x17, 0x5C, 0x50, 0, 0, 0, 0x35, 0, 0, 0}),
             DataBytes);
@@ -343,8 +346,8 @@ TEST(MappedBlockStreamTest, TestWriteThe
   Reader.setOffset(0);
   Writer.setOffset(0);
   ::memset(DataBytes.data(), 0, 10);
-  EXPECT_NO_ERROR(Writer.writeEnum(Enum[0], llvm::support::little));
-  EXPECT_NO_ERROR(Reader.readEnum(Enum[1], llvm::support::little));
+  EXPECT_NO_ERROR(Writer.writeEnum(Enum[0]));
+  EXPECT_NO_ERROR(Reader.readEnum(Enum[1]));
   EXPECT_EQ(Enum[0], Enum[1]);
   EXPECT_EQ(std::vector<uint8_t>({0x2C, 0x60, 0x4A, 0, 0, 0, 0, 0, 0, 0}),
             DataBytes);
@@ -352,8 +355,8 @@ TEST(MappedBlockStreamTest, TestWriteThe
   Reader.setOffset(0);
   Writer.setOffset(0);
   ::memset(DataBytes.data(), 0, 10);
-  EXPECT_NO_ERROR(Writer.writeZeroString(ZStr[0]));
-  EXPECT_NO_ERROR(Reader.readZeroString(ZStr[1]));
+  EXPECT_NO_ERROR(Writer.writeCString(ZStr[0]));
+  EXPECT_NO_ERROR(Reader.readCString(ZStr[1]));
   EXPECT_EQ(ZStr[0], ZStr[1]);
   EXPECT_EQ(
       std::vector<uint8_t>({'r', 'e', 'Z', ' ', 'S', 't', 'o', 'r', 0, 0}),
@@ -399,22 +402,22 @@ TEST(MappedBlockStreamTest, TestWriteCon
       F.block_size(), F.block_count(), F.layout(), F);
 
   // First write "Test Str" into the source stream.
-  MutableByteStream SourceStream(SrcData);
-  StreamWriter SourceWriter(SourceStream);
-  EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
+  MutableBinaryByteStream SourceStream(SrcData, little);
+  BinaryStreamWriter SourceWriter(SourceStream);
+  EXPECT_NO_ERROR(SourceWriter.writeCString("Test Str"));
   EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
                               {'T', 'e', 's', 't', ' ', 'S', 't', 'r', 0, 0}));
 
   // Then write the source stream into the dest stream.
-  StreamWriter DestWriter(*DestStream);
+  BinaryStreamWriter DestWriter(*DestStream);
   EXPECT_NO_ERROR(DestWriter.writeStreamRef(SourceStream));
   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);
-  EXPECT_NO_ERROR(DestReader.readZeroString(Result));
+  BinaryStreamReader DestReader(*DestStream);
+  EXPECT_NO_ERROR(DestReader.readCString(Result));
   EXPECT_EQ(Result, "Test Str");
 }
 
@@ -436,21 +439,21 @@ TEST(MappedBlockStreamTest, TestWriteDis
       SrcF.block_size(), SrcF.block_count(), SrcF.layout(), SrcF);
 
   // First write "Test Str" into the source stream.
-  StreamWriter SourceWriter(*Src);
-  EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
+  BinaryStreamWriter SourceWriter(*Src);
+  EXPECT_NO_ERROR(SourceWriter.writeCString("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(*Dest);
+  BinaryStreamWriter 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(*Dest);
-  EXPECT_NO_ERROR(DestReader.readZeroString(Result));
+  BinaryStreamReader DestReader(*Dest);
+  EXPECT_NO_ERROR(DestReader.readCString(Result));
   EXPECT_EQ(Result, "Test Str");
 }
 

Modified: llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp?rev=296215&r1=296214&r2=296215&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp Fri Feb 24 18:44:30 2017
@@ -19,6 +19,7 @@
 
 using namespace llvm;
 using namespace llvm::pdb;
+using namespace llvm::support;
 
 namespace {
 class StringTableBuilderTest : public ::testing::Test {};
@@ -33,13 +34,13 @@ TEST_F(StringTableBuilderTest, Simple) {
   EXPECT_EQ(9U, Builder.insert("baz"));
 
   std::vector<uint8_t> Buffer(Builder.finalize());
-  msf::MutableByteStream OutStream(Buffer);
-  msf::StreamWriter Writer(OutStream);
+  MutableBinaryByteStream OutStream(Buffer, little);
+  BinaryStreamWriter Writer(OutStream);
   EXPECT_NO_ERROR(Builder.commit(Writer));
 
   // Reads the contents back.
-  msf::ByteStream InStream(Buffer);
-  msf::StreamReader Reader(InStream);
+  BinaryByteStream InStream(Buffer, little);
+  BinaryStreamReader Reader(InStream);
   StringTable Table;
   EXPECT_NO_ERROR(Table.load(Reader));
 




More information about the llvm-commits mailing list