Wrap clang module files in a Mach-O, ELF, or COFF container.
This is a necessary prerequisite for debugging with modules.
The .pcm files become containers that hold the serialized AST which allows
us to store debug information in the module file that can be shared by all
object files that were built importing the module.

rdar://problem/19104245

llvm-svn: 230044
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index bb6a450..69d8f11 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -46,6 +46,8 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -632,6 +634,27 @@
 // AST reader implementation
 //===----------------------------------------------------------------------===//
 
+void ASTReader::InitStreamFileWithModule(llvm::MemoryBufferRef Buffer,
+                                         llvm::BitstreamReader &StreamFile) {
+  if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
+    bool IsCOFF = isa<llvm::object::COFFObjectFile>(OF.get().get());
+    // Find the clang AST section in the container.
+    for (auto &Section : OF->get()->sections()) {
+      StringRef Name;
+      Section.getName(Name);
+      if ((!IsCOFF && Name == "__clangast") ||
+          ( IsCOFF && Name ==   "clangast")) {
+        StringRef Buf;
+        Section.getContents(Buf);
+        return StreamFile.init((const unsigned char*)Buf.begin(),
+                               (const unsigned char*)Buf.end());
+      }
+    }
+  }
+  StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
+                  (const unsigned char *)Buffer.getBufferEnd());
+}
+
 void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
                                            bool TakeOwnership) {
   DeserializationListener = Listener;
@@ -3883,9 +3906,10 @@
 
   ModuleFile &F = *M;
   BitstreamCursor &Stream = F.Stream;
+  InitStreamFileWithModule(F.Buffer->getMemBufferRef(), F.StreamFile);
   Stream.init(&F.StreamFile);
-  F.SizeInBits = F.Buffer->getBufferSize() * 8;
-  
+  F.SizeInBits = F.StreamFile.getBitcodeBytes().getExtent() * 8;
+
   // Sniff for the signature.
   if (Stream.Read(8) != 'C' ||
       Stream.Read(8) != 'P' ||
@@ -4174,8 +4198,7 @@
 
   // Initialize the stream
   llvm::BitstreamReader StreamFile;
-  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
-                  (const unsigned char *)(*Buffer)->getBufferEnd());
+  InitStreamFileWithModule((*Buffer)->getMemBufferRef(), StreamFile);
   BitstreamCursor Stream(StreamFile);
 
   // Sniff for the signature.
@@ -4270,8 +4293,7 @@
 
   // Initialize the stream
   llvm::BitstreamReader StreamFile;
-  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
-                  (const unsigned char *)(*Buffer)->getBufferEnd());
+  InitStreamFileWithModule((*Buffer)->getMemBufferRef(), StreamFile);
   BitstreamCursor Stream(StreamFile);
 
   // Sniff for the signature.