This patch extends the previous patch by starting to incorporate more functionality, like lookup-by-name and exporting lookup tables, into the module manager.  Methods now have documentation.  A few more functions have been switched over to the new iterator style and away from manual/explicit iteration.  Ultimately we want to move away from name lookup here, as symlinks make filenames not a safe unique value, but we use it here as a stopgap before better measures are in place (namely instead using FileEntry* from a global FileManager).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136107 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 34a510b..a97435b 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -393,38 +393,59 @@
   /// \brief The chain of AST files. The first entry is the one named by the
   /// user, the last one is the one that doesn't depend on anything further.
   SmallVector<Module*, 2> Chain;
+
+  /// \brief All loaded modules, indexed by name.
+  llvm::StringMap<Module*> Modules;
+
 public:
   typedef SmallVector<Module*, 2>::iterator ModuleIterator;
   typedef SmallVector<Module*, 2>::const_iterator ModuleConstIterator;
   typedef SmallVector<Module*, 2>::reverse_iterator ModuleReverseIterator;
+  typedef std::pair<uint32_t, StringRef> ModuleOffset;
 
+  ~ModuleManager();
+
+  /// \brief Forward iterator to traverse all loaded modules
   ModuleIterator begin() { return Chain.begin(); }
+  /// \brief Forward iterator end-point to traverse all loaded modules
   ModuleIterator end() { return Chain.end(); }
 
+  /// \brief Const forward iterator to traverse all loaded modules
   ModuleConstIterator begin() const { return Chain.begin(); }
+  /// \brief Const forward iterator end-point to traverse all loaded modules
   ModuleConstIterator end() const { return Chain.end(); }
 
+  /// \brief Reverse iterator to traverse all loaded modules
   ModuleReverseIterator rbegin() { return Chain.rbegin(); }
+  /// \brief Reverse iterator end-point to traverse all loaded modules
   ModuleReverseIterator rend() { return Chain.rend(); }
 
-  const std::string &getPrimaryFileName() const { return Chain[0]->FileName; }
-
+  /// \brief Returns the primary module associated with the manager, that is,
+  /// the first module loaded
   Module &getPrimaryModule() { return *Chain[0]; }
+
+  /// \brief Returns the primary module associated with the manager, that is,
+  /// the first module loaded.
+  Module &getPrimaryModule() const { return *Chain[0]; }
+
+  /// \brief Returns the latest module associated with the manager, that is,
+  /// the last module loaded
   Module &getLastModule() { return *Chain.back(); }
+
+  /// \brief Returns the module associated with the given index
   Module &operator[](unsigned Index) const { return *Chain[Index]; }
 
+  /// \brief Returns the module associated with the given name
+  Module *lookup(StringRef Name) { return Modules.lookup(Name); }
+
+  /// \brief Number of modules loaded
   unsigned size() const { return Chain.size(); }
 
-  Module &addModule(ModuleKind Type) {
-    Module *newModule = new Module(Type);
-    Chain.push_back(newModule);
-    return *newModule;
-  }
+  /// \brief Creates a new module and adds it to the list of known modules
+  Module &addModule(StringRef FileName, ModuleKind Type);
 
-  ~ModuleManager() {
-    for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-      delete Chain[e - i - 1];
-  }
+  /// \brief Exports the list of loaded modules with their corresponding names
+  void exportLookup(SmallVector<ModuleOffset, 16> &Target);
 };
 
 } // end namespace serialization
@@ -497,12 +518,6 @@
   /// \brief AST buffers for chained PCHs created and stored in memory.
   /// First (not depending on another) PCH in chain is in front.
   std::vector<llvm::MemoryBuffer *> ASTBuffers;
-  
-  /// \brief All loaded modules, indexed by name.
-  llvm::StringMap<Module*> Modules;
-
-  /// \brief The first module in source order.
-  Module *FirstInSource;
 
   /// \brief The module manager which manages modules and their dependencies
   ModuleManager ModuleMgr;
@@ -684,9 +699,9 @@
                              std::pair<Module *, int32_t>, 4>
     GlobalCXXBaseSpecifiersMapType;
 
-  /// \brief Mapping from global CXX base specifier IDs to the module in which the
-  /// CXX base specifier resides along with the offset that should be added to the
-  /// global CXX base specifer ID to produce a local ID.
+  /// \brief Mapping from global CXX base specifier IDs to the module in which
+  /// the CXX base specifier resides along with the offset that should be added
+  /// to the global CXX base specifer ID to produce a local ID.
   GlobalCXXBaseSpecifiersMapType GlobalCXXBaseSpecifiersMap;
 
   /// \name CodeGen-relevant special data
@@ -1083,7 +1098,7 @@
 
   /// \brief Retrieve the name of the named (primary) AST file
   const std::string &getFileName() const {
-    return ModuleMgr.getPrimaryFileName();
+    return ModuleMgr.getPrimaryModule().FileName;
   }
 
   /// \brief Retrieve the name of the original source file name
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index cd4627b..c2901c1 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -2381,7 +2381,7 @@
   SmallVector<StoredDiagnostic, 4> Result;
   Result.reserve(Diags.size());
   assert(MMan && "Don't have a module manager");
-  serialization::Module *Mod = MMan->Modules.lookup(ModName);
+  serialization::Module *Mod = MMan->ModuleMgr.lookup(ModName);
   assert(Mod && "Don't have preamble module");
   SLocRemap &Remap = Mod->SLocRemap;
   for (unsigned I = 0, N = Diags.size(); I != N; ++I) {
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 14ba59c..3994fe6 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2223,7 +2223,7 @@
         uint32_t Offset = io::ReadUnalignedLE32(Data);
         uint16_t Len = io::ReadUnalignedLE16(Data);
         StringRef Name = StringRef((const char*)Data, Len);
-        Module *OM = Modules.lookup(Name);
+        Module *OM = ModuleMgr.lookup(Name);
         if (!OM) {
           Error("SourceLocation remap refers to unknown module");
           return Failure;
@@ -2236,7 +2236,6 @@
       break;
     }
 
-
     case SOURCE_MANAGER_LINE_TABLE:
       if (ParseLineTable(F, Record))
         return Failure;
@@ -2637,19 +2636,7 @@
 
 ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
                                                 ModuleKind Type) {
-  Module *Prev = !ModuleMgr.size() ? 0 : &ModuleMgr.getLastModule();
-  ModuleMgr.addModule(Type);
-  Module &F = ModuleMgr.getLastModule();
-  if (Prev)
-    Prev->NextInSource = &F;
-  else
-    FirstInSource = &F;
-  F.Loaders.push_back(Prev);
-
-  Modules[FileName.str()] = &F;
-
-  // Set the AST file name.
-  F.FileName = FileName;
+  Module &F = ModuleMgr.addModule(FileName, Type);
 
   if (FileName != "-") {
     CurrentDir = llvm::sys::path::parent_path(FileName);
@@ -4388,7 +4375,7 @@
     SemaObj->StdBadAlloc = SemaDeclRefs[1];
   }
 
-  for (Module *F = FirstInSource; F; F = F->NextInSource) {
+  for (Module *F = &ModuleMgr.getPrimaryModule(); F; F = F->NextInSource) {
 
     // If there are @selector references added them to its pool. This is for
     // implementation of -Wselector.
@@ -5275,7 +5262,7 @@
   : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
     SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
     Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
-    Consumer(0), FirstInSource(0), RelocatablePCH(false), isysroot(isysroot), 
+    Consumer(0), RelocatablePCH(false), isysroot(isysroot),
     DisableValidation(DisableValidation),
     DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0), 
     NumSLocEntriesRead(0), TotalNumSLocEntries(0), 
@@ -5294,7 +5281,7 @@
                      Diagnostic &Diags, StringRef isysroot,
                      bool DisableValidation, bool DisableStatCache)
   : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
-    Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), FirstInSource(0),
+    Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
     RelocatablePCH(false), isysroot(isysroot), 
     DisableValidation(DisableValidation), DisableStatCache(DisableStatCache), 
     NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), 
@@ -5352,3 +5339,37 @@
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
   delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
 }
+
+/// \brief Creates a new module and adds it to the list of known modules
+Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type) {
+  Module *Prev = !size() ? 0 : &getLastModule();
+  Module *Current = new Module(Type);
+
+  Current->FileName = FileName.str();
+
+  Chain.push_back(Current);
+  Modules[FileName.str()] = Current;
+
+  if (Prev)
+    Prev->NextInSource = Current;
+  Current->Loaders.push_back(Prev);
+
+  return *Current;
+}
+
+/// \brief Exports the list of loaded modules with their corresponding names
+void ModuleManager::exportLookup(SmallVector<ModuleOffset, 16> &Target) {
+  Target.reserve(size());
+  for (llvm::StringMap<Module*>::const_iterator
+           I = Modules.begin(), E = Modules.end();
+       I != E; ++I) {
+    Target.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset,
+                                   I->getKey()));
+  }
+  std::sort(Target.begin(), Target.end());
+}
+
+ModuleManager::~ModuleManager() {
+  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+    delete Chain[e - i - 1];
+}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index c94b96d..14824a0 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -969,7 +969,8 @@
   Record.push_back(CLANG_VERSION_MINOR);
   Record.push_back(!isysroot.empty());
   // FIXME: This writes the absolute path for chained headers.
-  const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple();
+  const std::string &BlobStr =
+                  Chain ? Chain->getFileName() : Target.getTriple().getTriple();
   Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr);
 
   // Original file name and file ID
@@ -1548,14 +1549,8 @@
     // Sorted by offset.
     typedef std::pair<uint32_t, StringRef> ModuleOffset;
     SmallVector<ModuleOffset, 16> Modules;
-    Modules.reserve(Chain->Modules.size());
-    for (llvm::StringMap<Module*>::const_iterator
-             I = Chain->Modules.begin(), E = Chain->Modules.end();
-         I != E; ++I) {
-      Modules.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset,
-                                     I->getKey()));
-    }
-    std::sort(Modules.begin(), Modules.end());
+
+    Chain->ModuleMgr.exportLookup(Modules);
 
     Abbrev = new BitCodeAbbrev();
     Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_MAP));