198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//
398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//                     The LLVM Compiler Infrastructure
498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//
598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor// This file is distributed under the University of Illinois Open Source
698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor// License. See LICENSE.TXT for details.
798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//
898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//===----------------------------------------------------------------------===//
998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//
1098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//  This file defines the ModuleManager class, which manages a set of loaded
1198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//  modules for the ASTReader.
1298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//
1398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor//===----------------------------------------------------------------------===//
14677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor#include "clang/Lex/ModuleMap.h"
1598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include "clang/Serialization/ModuleManager.h"
16188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor#include "clang/Serialization/GlobalModuleIndex.h"
1798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include "llvm/Support/MemoryBuffer.h"
188229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include "llvm/Support/Path.h"
1998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include "llvm/Support/raw_ostream.h"
2098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor#include "llvm/Support/system_error.h"
2198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
222492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#ifndef NDEBUG
232492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#include "llvm/Support/GraphWriter.h"
242492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#endif
252492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
2698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorusing namespace clang;
2798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorusing namespace serialization;
2898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
291a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModuleFile *ModuleManager::lookup(StringRef Name) {
30ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor  const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
31ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor                                           /*cacheFailure=*/false);
32c544ba09695e300f31355af342258bd57619e737Douglas Gregor  if (Entry)
33c544ba09695e300f31355af342258bd57619e737Douglas Gregor    return lookup(Entry);
34c544ba09695e300f31355af342258bd57619e737Douglas Gregor
35c544ba09695e300f31355af342258bd57619e737Douglas Gregor  return 0;
36c544ba09695e300f31355af342258bd57619e737Douglas Gregor}
37c544ba09695e300f31355af342258bd57619e737Douglas Gregor
38c544ba09695e300f31355af342258bd57619e737Douglas GregorModuleFile *ModuleManager::lookup(const FileEntry *File) {
39c544ba09695e300f31355af342258bd57619e737Douglas Gregor  llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known
40c544ba09695e300f31355af342258bd57619e737Douglas Gregor    = Modules.find(File);
41c544ba09695e300f31355af342258bd57619e737Douglas Gregor  if (Known == Modules.end())
42c544ba09695e300f31355af342258bd57619e737Douglas Gregor    return 0;
43c544ba09695e300f31355af342258bd57619e737Douglas Gregor
44c544ba09695e300f31355af342258bd57619e737Douglas Gregor  return Known->second;
4598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
4698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
4798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorllvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
48ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor  const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
49ea14a8799f2a6d139491483151cee4341ef1a73eDouglas Gregor                                           /*cacheFailure=*/false);
5098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  return InMemoryBuffers[Entry];
5198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
5298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
53677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas GregorModuleManager::AddModuleResult
5487e2cfcec7231daaa3f367dc32df74b411251e46Douglas GregorModuleManager::addModule(StringRef FileName, ModuleKind Type,
5587e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor                         SourceLocation ImportLoc, ModuleFile *ImportedBy,
56677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                         unsigned Generation,
57677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                         off_t ExpectedSize, time_t ExpectedModTime,
58677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                         ModuleFile *&Module,
59677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                         std::string &ErrorStr) {
60677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  Module = 0;
61677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
62677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  // Look for the file entry. This only fails if the expected size or
63677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  // modification time differ.
64677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  const FileEntry *Entry;
65677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry))
66677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    return OutOfDate;
67677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
6898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  if (!Entry && FileName != "-") {
6998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    ErrorStr = "file not found";
70677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    return Missing;
7198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
72677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
73677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  // Check whether we already loaded this module, before
741a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  ModuleFile *&ModuleEntry = Modules[Entry];
7598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  bool NewModule = false;
7698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  if (!ModuleEntry) {
7798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    // Allocate a new module.
78057df20b3107cef764052d271c89b8591b98b3ceDouglas Gregor    ModuleFile *New = new ModuleFile(Type, Generation);
79cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    New->Index = Chain.size();
8098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    New->FileName = FileName.str();
81d64c26f6676eef69d1713f353ca8a3c2fe963f17Argyrios Kyrtzidis    New->File = Entry;
8287e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor    New->ImportLoc = ImportLoc;
8398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    Chain.push_back(New);
8498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    NewModule = true;
8598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    ModuleEntry = New;
8687e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor
8798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    // Load the contents of the module
8898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
8998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      // The buffer was already provided for us.
9098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      assert(Buffer && "Passed null buffer");
9198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      New->Buffer.reset(Buffer);
9298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    } else {
9398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      // Open the AST file.
9498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      llvm::error_code ec;
9598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      if (FileName == "-") {
9698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor        ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
9798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor        if (ec)
9898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor          ErrorStr = ec.message();
9998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      } else
10098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor        New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
10198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
10298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      if (!New->Buffer)
103677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor        return Missing;
10498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    }
10598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
10698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    // Initialize the stream
10798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
108677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                         (const unsigned char *)New->Buffer->getBufferEnd());
109677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  }
11098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
11198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  if (ImportedBy) {
11298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    ModuleEntry->ImportedBy.insert(ImportedBy);
11398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    ImportedBy->Imports.insert(ModuleEntry);
11498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  } else {
11587e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor    if (!ModuleEntry->DirectlyImported)
11687e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor      ModuleEntry->ImportLoc = ImportLoc;
11787e2cfcec7231daaa3f367dc32df74b411251e46Douglas Gregor
11898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    ModuleEntry->DirectlyImported = true;
11998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
120677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
121677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  Module = ModuleEntry;
122677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  return NewModule? NewlyLoaded : AlreadyLoaded;
12398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
12498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
1257cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregornamespace {
1267cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  /// \brief Predicate that checks whether a module file occurs within
1277cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  /// the given set.
1287cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  class IsInModuleFileSet : public std::unary_function<ModuleFile *, bool> {
1297cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    llvm::SmallPtrSet<ModuleFile *, 4> &Removed;
1307cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1317cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  public:
1327cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    IsInModuleFileSet(llvm::SmallPtrSet<ModuleFile *, 4> &Removed)
1337cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    : Removed(Removed) { }
1347cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1357cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    bool operator()(ModuleFile *MF) const {
1367cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor      return Removed.count(MF);
1377cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    }
1387cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  };
1397cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor}
1407cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
141677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregorvoid ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
142677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                                  ModuleMap *modMap) {
1437cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  if (first == last)
1447cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    return;
1457cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1467cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  // Collect the set of module file pointers that we'll be removing.
1477cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
1487cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1497cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  // Remove any references to the now-destroyed modules.
1507cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  IsInModuleFileSet checkInSet(victimSet);
1517cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
1527cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    Chain[i]->ImportedBy.remove_if(checkInSet);
1537cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  }
1547cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1557cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  // Delete the modules and erase them from the various structures.
1567cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  for (ModuleIterator victim = first; victim != last; ++victim) {
1577cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    Modules.erase((*victim)->File);
158677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
159677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    FileMgr.invalidateCache((*victim)->File);
160677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    if (modMap) {
161677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor      StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName);
162677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor      if (Module *mod = modMap->findModule(ModuleName)) {
163677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor        mod->setASTFile(0);
164677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor      }
165677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    }
1667cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor    delete *victim;
1677cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  }
1687cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
1697cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  // Remove the modules from the chain.
1707cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor  Chain.erase(first, last);
1717cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor}
1727cdd28162dc7ade4b14bf237e87b4bbc17b2f023Douglas Gregor
17398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregorvoid ModuleManager::addInMemoryBuffer(StringRef FileName,
17498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                                      llvm::MemoryBuffer *Buffer) {
17598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
17698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  const FileEntry *Entry = FileMgr.getVirtualFile(FileName,
17798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                                                  Buffer->getBufferSize(), 0);
17898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  InMemoryBuffers[Entry] = Buffer;
17998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
18098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
181d3cf5fba332fc77f7e72ef58077822606718671dDouglas GregorModuleManager::VisitState *ModuleManager::allocateVisitState() {
182d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  // Fast path: if we have a cached state, use it.
183d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  if (FirstVisitState) {
184d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    VisitState *Result = FirstVisitState;
185d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    FirstVisitState = FirstVisitState->NextState;
186d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    Result->NextState = 0;
187d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    return Result;
188d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  }
189d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor
190d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  // Allocate and return a new state.
191d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  return new VisitState(size());
192d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor}
193d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor
194d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregorvoid ModuleManager::returnVisitState(VisitState *State) {
195d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  assert(State->NextState == 0 && "Visited state is in list?");
196d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  State->NextState = FirstVisitState;
197d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  FirstVisitState = State;
198d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor}
199d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor
200188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregorvoid ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) {
201188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  GlobalIndex = Index;
202fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  if (!GlobalIndex) {
203fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor    ModulesInCommonWithGlobalIndex.clear();
204fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor    return;
205677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  }
206fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor
207fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  // Notify the global module index about all of the modules we've already
208fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  // loaded.
209fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
210fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor    if (!GlobalIndex->loadedModuleFile(Chain[I])) {
211fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor      ModulesInCommonWithGlobalIndex.push_back(Chain[I]);
212fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor    }
213fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  }
214fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor}
215fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor
216fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregorvoid ModuleManager::moduleFileAccepted(ModuleFile *MF) {
217fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))
218fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor    return;
219fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor
220fa69fc19121da3fc5673ccc00d4e8afa5b540a4fDouglas Gregor  ModulesInCommonWithGlobalIndex.push_back(MF);
221188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor}
222188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor
223188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas GregorModuleManager::ModuleManager(FileManager &FileMgr)
224d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(0) { }
22598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
22698339b96a8089a6da715487e432c5abfca0ca0dfDouglas GregorModuleManager::~ModuleManager() {
22798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
22898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    delete Chain[e - i - 1];
229d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  delete FirstVisitState;
23098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
23198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
232188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregorvoid
233188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas GregorModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData),
234188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor                     void *UserData,
235677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                     llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit) {
236188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  // If the visitation order vector is the wrong size, recompute the order.
237d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor  if (VisitOrder.size() != Chain.size()) {
238d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    unsigned N = size();
239d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    VisitOrder.clear();
240d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    VisitOrder.reserve(N);
241d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
242d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // Record the number of incoming edges for each module. When we
243d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // encounter a module with no incoming edges, push it into the queue
244d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // to seed the queue.
245d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    SmallVector<ModuleFile *, 4> Queue;
246d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    Queue.reserve(N);
247d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
248d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    UnusedIncomingEdges.reserve(size());
249d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) {
250d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      if (unsigned Size = (*M)->ImportedBy.size())
251d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        UnusedIncomingEdges.push_back(Size);
252d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      else {
253d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        UnusedIncomingEdges.push_back(0);
254d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        Queue.push_back(*M);
255d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      }
256cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    }
257d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
258d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // Traverse the graph, making sure to visit a module before visiting any
259d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // of its dependencies.
260d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    unsigned QueueStart = 0;
261d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    while (QueueStart < Queue.size()) {
262d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      ModuleFile *CurrentModule = Queue[QueueStart++];
263d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      VisitOrder.push_back(CurrentModule);
264d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
265d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      // For any module that this module depends on, push it on the
266d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      // stack (if it hasn't already been marked as visited).
267d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      for (llvm::SetVector<ModuleFile *>::iterator
268d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor             M = CurrentModule->Imports.begin(),
269d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor             MEnd = CurrentModule->Imports.end();
270d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor           M != MEnd; ++M) {
271d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        // Remove our current module as an impediment to visiting the
272d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        // module we depend on. If we were the last unvisited module
273d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        // that depends on this particular module, push it into the
274d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        // queue to be visited.
275d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        unsigned &NumUnusedEdges = UnusedIncomingEdges[(*M)->Index];
276d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        if (NumUnusedEdges && (--NumUnusedEdges == 0))
277d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor          Queue.push_back(*M);
278d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      }
279d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    }
280d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
281d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    assert(VisitOrder.size() == N && "Visitation order is wrong?");
282188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor
283d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    delete FirstVisitState;
284d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    FirstVisitState = 0;
28598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
286cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor
287d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  VisitState *State = allocateVisitState();
288d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  unsigned VisitNumber = State->NextVisitNumber++;
289d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
290188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  // If the caller has provided us with a hit-set that came from the global
291188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  // module index, mark every module file in common with the global module
292188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  // index that is *not* in that set as 'visited'.
293188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  if (ModuleFilesHit && !ModulesInCommonWithGlobalIndex.empty()) {
294188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor    for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I)
295188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor    {
296188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor      ModuleFile *M = ModulesInCommonWithGlobalIndex[I];
297677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor      if (!ModuleFilesHit->count(M))
298d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor        State->VisitNumber[M->Index] = VisitNumber;
299188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor    }
300188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor  }
301188bdcd1aaf5e9f457cec6851707d7dc3e7bbb15Douglas Gregor
302d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor  for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) {
303d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    ModuleFile *CurrentModule = VisitOrder[I];
304d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // Should we skip this module file?
305d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    if (State->VisitNumber[CurrentModule->Index] == VisitNumber)
30698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      continue;
307d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
308d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // Visit the module.
309d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1);
310d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor    State->VisitNumber[CurrentModule->Index] = VisitNumber;
311d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    if (!Visitor(*CurrentModule, UserData))
312d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      continue;
313d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
314d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // The visitor has requested that cut off visitation of any
315d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // module that the current module depends on. To indicate this
316d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    // behavior, we mark all of the reachable modules as having been visited.
317d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    ModuleFile *NextModule = CurrentModule;
318d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    do {
319d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      // For any module that this module depends on, push it on the
320d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      // stack (if it hasn't already been marked as visited).
321d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      for (llvm::SetVector<ModuleFile *>::iterator
322d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor             M = NextModule->Imports.begin(),
323d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor             MEnd = NextModule->Imports.end();
324d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor           M != MEnd; ++M) {
325d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor        if (State->VisitNumber[(*M)->Index] != VisitNumber) {
326d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor          State->Stack.push_back(*M);
327d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor          State->VisitNumber[(*M)->Index] = VisitNumber;
32898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor        }
32998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      }
330d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
331d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor      if (State->Stack.empty())
332d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor        break;
333d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor
334d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor      // Pop the next module off the stack.
335d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor      NextModule = State->Stack.back();
336d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor      State->Stack.pop_back();
337d07865b42dcb32154c75134fded51b38cc55a0c4Douglas Gregor    } while (true);
33898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
339d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor
340d3cf5fba332fc77f7e72ef58077822606718671dDouglas Gregor  returnVisitState(State);
34198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
34298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
34398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor/// \brief Perform a depth-first visit of the current module.
3441a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorstatic bool visitDepthFirst(ModuleFile &M,
3451a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor                            bool (*Visitor)(ModuleFile &M, bool Preorder,
34698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                                            void *UserData),
34798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                            void *UserData,
348cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor                            SmallVectorImpl<bool> &Visited) {
34998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  // Preorder visitation
35098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  if (Visitor(M, /*Preorder=*/true, UserData))
35198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    return true;
35298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
35398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  // Visit children
3541a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  for (llvm::SetVector<ModuleFile *>::iterator IM = M.Imports.begin(),
355cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor                                            IMEnd = M.Imports.end();
35698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor       IM != IMEnd; ++IM) {
357cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    if (Visited[(*IM)->Index])
35898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      continue;
359cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    Visited[(*IM)->Index] = true;
360cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor
36198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    if (visitDepthFirst(**IM, Visitor, UserData, Visited))
36298339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      return true;
36398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
36498339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
36598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  // Postorder visitation
36698339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  return Visitor(M, /*Preorder=*/false, UserData);
36798339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
36898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor
3691a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorvoid ModuleManager::visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
37098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                                                    void *UserData),
37198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor                                    void *UserData) {
372cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor  SmallVector<bool, 16> Visited(size(), false);
37398339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
374cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    if (Visited[Chain[I]->Index])
37598339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      continue;
376cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor    Visited[Chain[I]->Index] = true;
377cc71dbee441e97285e86bff48eecfbeab82de7ceDouglas Gregor
37898339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor    if (::visitDepthFirst(*Chain[I], Visitor, UserData, Visited))
37998339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor      return;
38098339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor  }
38198339b96a8089a6da715487e432c5abfca0ca0dfDouglas Gregor}
3822492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
383677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregorbool ModuleManager::lookupModuleFile(StringRef FileName,
384677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                                     off_t ExpectedSize,
385677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                                     time_t ExpectedModTime,
386677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor                                     const FileEntry *&File) {
387677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  File = FileMgr.getFile(FileName, /*openFile=*/false, /*cacheFailure=*/false);
388677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
389677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  if (!File && FileName != "-") {
390677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    return false;
391677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  }
392677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
393677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  if ((ExpectedSize && ExpectedSize != File->getSize()) ||
394677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor      (ExpectedModTime && ExpectedModTime != File->getModificationTime())) {
395677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor    return true;
396677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  }
397677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
398677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor  return false;
399677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor}
400677e15ffee2ecc9c1c8f46fd77cab4b5afb59640Douglas Gregor
4012492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#ifndef NDEBUG
4022492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregornamespace llvm {
4032492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  template<>
4042492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  struct GraphTraits<ModuleManager> {
4051a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor    typedef ModuleFile NodeType;
4061a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor    typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
4072492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    typedef ModuleManager::ModuleConstIterator nodes_iterator;
4082492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4092492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    static ChildIteratorType child_begin(NodeType *Node) {
4102492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return Node->Imports.begin();
4112492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4122492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4132492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    static ChildIteratorType child_end(NodeType *Node) {
4142492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return Node->Imports.end();
4152492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4162492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4172492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    static nodes_iterator nodes_begin(const ModuleManager &Manager) {
4182492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return Manager.begin();
4192492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4202492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4212492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    static nodes_iterator nodes_end(const ModuleManager &Manager) {
4222492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return Manager.end();
4232492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4242492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  };
4252492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4262492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  template<>
4272492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
4282492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    explicit DOTGraphTraits(bool IsSimple = false)
4292492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      : DefaultDOTGraphTraits(IsSimple) { }
4302492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4312492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    static bool renderGraphFromBottomUp() {
4322492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return true;
4332492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4342492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4351a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor    std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
4362492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor      return llvm::sys::path::stem(M->FileName);
4372492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor    }
4382492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  };
4392492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor}
4402492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor
4412492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregorvoid ModuleManager::viewGraph() {
4422492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor  llvm::ViewGraph(*this, "Modules");
4432492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor}
4442492c89882b5c5ce03afb4704fee67b7eff8f5eeDouglas Gregor#endif
445