Refactor of how modules are handled in ASTReader to remove explicit uses of a chain of AST files, instead redirect calls through a module manager.  This should help move toward a DAG and the potential of loading multiple, unrelated PCH files.  It's still early in development.

llvm-svn: 135957
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 627a394..8b4167d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1740,16 +1740,16 @@
 }
 
 void ASTReader::ReadDefinedMacros() {
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    Module &F = *Chain[N - I - 1];
-    llvm::BitstreamCursor &MacroCursor = F.MacroCursor;
+  for (ModuleReverseIterator I = ModuleMgr.rbegin(),
+      E = ModuleMgr.rend(); I != E; ++I) {
+    llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor;
 
     // If there was no preprocessor block, skip this file.
     if (!MacroCursor.getBitStreamReader())
       continue;
 
     llvm::BitstreamCursor Cursor = MacroCursor;
-    Cursor.JumpToBit(F.MacroStartOffset);
+    Cursor.JumpToBit((*I)->MacroStartOffset);
 
     RecordData Record;
     while (true) {
@@ -2465,8 +2465,9 @@
 }
 
 ASTReader::ASTReadResult ASTReader::validateFileEntries() {
-  for (unsigned CI = 0, CN = Chain.size(); CI != CN; ++CI) {
-    Module *F = Chain[CI];
+  for (ModuleIterator I = ModuleMgr.begin(),
+      E = ModuleMgr.end(); I != E; ++I) {
+    Module *F = *I;
     llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
 
     for (unsigned i = 0, e = F->LocalNumSLocFileEntries; i != e; ++i) {
@@ -2582,9 +2583,10 @@
          Id != IdEnd; ++Id)
       Identifiers.push_back(Id->second);
     // We need to search the tables in all files.
-    for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
+    for (ModuleIterator J = ModuleMgr.begin(),
+        M = ModuleMgr.end(); J != M; ++J) {
       ASTIdentifierLookupTable *IdTable
-        = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
+        = (ASTIdentifierLookupTable *)(*J)->IdentifierLookupTable;
       // Not all AST files necessarily have identifier tables, only the useful
       // ones.
       if (!IdTable)
@@ -2592,7 +2594,7 @@
       for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
         IdentifierInfo *II = Identifiers[I];
         // Look in the on-disk hash tables for an entry for this identifier
-        ASTIdentifierLookupTrait Info(*this, *Chain[J], II);
+        ASTIdentifierLookupTrait Info(*this, *(*J), II);
         std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
         ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
         if (Pos == IdTable->end())
@@ -2622,7 +2624,7 @@
         OriginalFileID = SourceMgr.getDecomposedLoc(Loc).first;
     }
     else {
-      OriginalFileID = FileID::get(Chain[0]->SLocEntryBaseID 
+      OriginalFileID = FileID::get(ModuleMgr.getPrimaryModule().SLocEntryBaseID
                                         + OriginalFileID.getOpaqueValue() - 1);
     }
 
@@ -2635,9 +2637,9 @@
 
 ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
                                                 ModuleKind Type) {
-  Module *Prev = Chain.empty() ? 0 : Chain.back();
-  Chain.push_back(new Module(Type));
-  Module &F = *Chain.back();
+  Module *Prev = !ModuleMgr.size() ? 0 : &ModuleMgr.getLastModule();
+  ModuleMgr.addModule(Type);
+  Module &F = ModuleMgr.getLastModule();
   if (Prev)
     Prev->NextInSource = &F;
   else
@@ -3060,12 +3062,12 @@
 }
 
 void ASTReader::ReadPreprocessedEntities() {
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    Module &F = *Chain[I];
+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
+    Module &F = *(*I);
     if (!F.PreprocessorDetailCursor.getBitStreamReader())
       continue;
 
-    SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);  
+    SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);
     F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset);
     while (LoadPreprocessedEntity(F)) { }
   }
@@ -3083,8 +3085,8 @@
 
 HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
   HeaderFileInfoTrait Trait(FE->getName());
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    Module &F = *Chain[I];
+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
+    Module &F = *(*I);
     HeaderFileInfoLookupTable *Table
       = static_cast<HeaderFileInfoLookupTable *>(F.HeaderFileInfoTable);
     if (!Table)
@@ -3107,8 +3109,8 @@
 }
 
 void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) {
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    Module &F = *Chain[I];
+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
+    Module &F = *(*I);
     unsigned Idx = 0;
     while (Idx < F.PragmaDiagMappings.size()) {
       SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
@@ -4304,8 +4306,9 @@
 /// Return the amount of memory used by memory buffers, breaking down
 /// by heap-backed versus mmap'ed memory.
 void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
-  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-    if (llvm::MemoryBuffer *buf = Chain[i]->Buffer.get()) {
+  for (ModuleConstIterator I = ModuleMgr.begin(),
+      E = ModuleMgr.end(); I != E; ++I) {
+    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
       size_t bytes = buf->getBufferSize();
       switch (buf->getBufferKind()) {
         case llvm::MemoryBuffer::MemoryBuffer_Malloc:
@@ -4316,6 +4319,7 @@
           break;
       }
     }
+  }
 }
 
 void ASTReader::InitializeSema(Sema &S) {
@@ -4402,7 +4406,7 @@
 
   // The special data sets below always come from the most recent PCH,
   // which is at the front of the chain.
-  Module &F = *Chain.front();
+  Module &F = ModuleMgr.getPrimaryModule();
 
   // If there were any pending implicit instantiations, deserialize them
   // and add them to Sema's queue of such instantiations.
@@ -4459,9 +4463,9 @@
 IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
   // Try to find this name within our on-disk hash tables. We start with the
   // most recent one, since that one contains the most up-to-date info.
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
     ASTIdentifierLookupTable *IdTable
-        = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
+        = (ASTIdentifierLookupTable *)(*I)->IdentifierLookupTable;
     if (!IdTable)
       continue;
     std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
@@ -4504,9 +4508,9 @@
 }
 
 ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader)
-  : Reader(Reader), Index(Reader.Chain.size() - 1) {
+  : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) {
   ASTIdentifierLookupTable *IdTable
-    = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable;
+    = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable;
   Current = IdTable->key_begin();
   End = IdTable->key_end();
 }
@@ -4519,7 +4523,8 @@
 
     --Index;
     ASTIdentifierLookupTable *IdTable
-      = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable;
+      = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].
+        IdentifierLookupTable;
     Current = IdTable->key_begin();
     End = IdTable->key_end();
   }
@@ -4538,8 +4543,8 @@
 std::pair<ObjCMethodList, ObjCMethodList>
 ASTReader::ReadMethodPool(Selector Sel) {
   // Find this selector in a hash table. We want to find the most recent entry.
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    Module &F = *Chain[I];
+  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
+    Module &F = *(*I);
     if (!F.SelectorLookupTable)
       continue;
 
@@ -5305,8 +5310,6 @@
 }
 
 ASTReader::~ASTReader() {
-  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-    delete Chain[e - i - 1];
   // Delete all visible decl lookup tables
   for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
                                        E = DeclContextOffsets.end();