[llvm-pdbutil] Add the ability to explain binary files.

Using this, you can use llvm-pdbutil to export the contents of a
stream to a binary file, then run explain on the binary file so
that it treats the offset as an offset into the stream instead
of an offset into a file.  This makes it easy to compare the
contents of the same stream from two different files.

llvm-svn: 329207
diff --git a/llvm/tools/llvm-pdbutil/InputFile.cpp b/llvm/tools/llvm-pdbutil/InputFile.cpp
index 2874782..8319fc5 100644
--- a/llvm/tools/llvm-pdbutil/InputFile.cpp
+++ b/llvm/tools/llvm-pdbutil/InputFile.cpp
@@ -242,7 +242,7 @@
   }
 }
 
-Expected<InputFile> InputFile::open(StringRef Path) {
+Expected<InputFile> InputFile::open(StringRef Path, bool AllowUnknownFile) {
   InputFile IF;
   if (!llvm::sys::fs::exists(Path))
     return make_error<StringError>(formatv("File {0} not found", Path),
@@ -274,9 +274,19 @@
     return std::move(IF);
   }
 
-  return make_error<StringError>(
-      formatv("File {0} is not a supported file type", Path),
-      inconvertibleErrorCode());
+  if (!AllowUnknownFile)
+    return make_error<StringError>(
+        formatv("File {0} is not a supported file type", Path),
+        inconvertibleErrorCode());
+
+  auto Result = MemoryBuffer::getFile(Path, -1i64, false);
+  if (!Result)
+    return make_error<StringError>(
+        formatv("File {0} could not be opened", Path), Result.getError());
+
+  IF.UnknownFile = std::move(*Result);
+  IF.PdbOrObj = IF.UnknownFile.get();
+  return std::move(IF);
 }
 
 PDBFile &InputFile::pdb() {
@@ -299,6 +309,25 @@
   return *PdbOrObj.get<object::COFFObjectFile *>();
 }
 
+MemoryBuffer &InputFile::unknown() {
+  assert(isUnknown());
+  return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+const MemoryBuffer &InputFile::unknown() const {
+  assert(isUnknown());
+  return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+StringRef InputFile::getFilePath() const {
+  if (isPdb())
+    return pdb().getFilePath();
+  if (isObj())
+    return obj().getFileName();
+  assert(isUnknown());
+  return unknown().getBufferIdentifier();
+}
+
 bool InputFile::hasTypes() const {
   if (isPdb())
     return pdb().hasPDBTpiStream();
@@ -323,6 +352,8 @@
   return PdbOrObj.is<object::COFFObjectFile *>();
 }
 
+bool InputFile::isUnknown() const { return PdbOrObj.is<MemoryBuffer *>(); }
+
 codeview::LazyRandomTypeCollection &
 InputFile::getOrCreateTypeCollection(TypeCollectionKind Kind) {
   if (Types && Kind == kTypes)