ModuleManager.cpp revision 176edba5311f6eff0cad2631449885ddf4fbc9ea
1//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the ModuleManager class, which manages a set of loaded
11//  modules for the ASTReader.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/HeaderSearch.h"
15#include "clang/Lex/ModuleMap.h"
16#include "clang/Serialization/GlobalModuleIndex.h"
17#include "clang/Serialization/ModuleManager.h"
18#include "llvm/Support/MemoryBuffer.h"
19#include "llvm/Support/Path.h"
20#include "llvm/Support/raw_ostream.h"
21#include <system_error>
22
23#ifndef NDEBUG
24#include "llvm/Support/GraphWriter.h"
25#endif
26
27using namespace clang;
28using namespace serialization;
29
30ModuleFile *ModuleManager::lookup(StringRef Name) {
31  const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
32                                           /*cacheFailure=*/false);
33  if (Entry)
34    return lookup(Entry);
35
36  return nullptr;
37}
38
39ModuleFile *ModuleManager::lookup(const FileEntry *File) {
40  llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known
41    = Modules.find(File);
42  if (Known == Modules.end())
43    return nullptr;
44
45  return Known->second;
46}
47
48std::unique_ptr<llvm::MemoryBuffer>
49ModuleManager::lookupBuffer(StringRef Name) {
50  const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
51                                           /*cacheFailure=*/false);
52  return std::move(InMemoryBuffers[Entry]);
53}
54
55ModuleManager::AddModuleResult
56ModuleManager::addModule(StringRef FileName, ModuleKind Type,
57                         SourceLocation ImportLoc, ModuleFile *ImportedBy,
58                         unsigned Generation,
59                         off_t ExpectedSize, time_t ExpectedModTime,
60                         ASTFileSignature ExpectedSignature,
61                         std::function<ASTFileSignature(llvm::BitstreamReader &)>
62                             ReadSignature,
63                         ModuleFile *&Module,
64                         std::string &ErrorStr) {
65  Module = nullptr;
66
67  // Look for the file entry. This only fails if the expected size or
68  // modification time differ.
69  const FileEntry *Entry;
70  if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) {
71    ErrorStr = "module file out of date";
72    return OutOfDate;
73  }
74
75  if (!Entry && FileName != "-") {
76    ErrorStr = "module file not found";
77    return Missing;
78  }
79
80  // Check whether we already loaded this module, before
81  ModuleFile *&ModuleEntry = Modules[Entry];
82  bool NewModule = false;
83  if (!ModuleEntry) {
84    // Allocate a new module.
85    ModuleFile *New = new ModuleFile(Type, Generation);
86    New->Index = Chain.size();
87    New->FileName = FileName.str();
88    New->File = Entry;
89    New->ImportLoc = ImportLoc;
90    Chain.push_back(New);
91    NewModule = true;
92    ModuleEntry = New;
93
94    New->InputFilesValidationTimestamp = 0;
95    if (New->Kind == MK_ImplicitModule) {
96      std::string TimestampFilename = New->getTimestampFilename();
97      vfs::Status Status;
98      // A cached stat value would be fine as well.
99      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
100        New->InputFilesValidationTimestamp =
101            Status.getLastModificationTime().toEpochTime();
102    }
103
104    // Load the contents of the module
105    if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
106      // The buffer was already provided for us.
107      New->Buffer = std::move(Buffer);
108    } else {
109      // Open the AST file.
110      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf(
111          (std::error_code()));
112      if (FileName == "-") {
113        Buf = llvm::MemoryBuffer::getSTDIN();
114      } else {
115        // Leave the FileEntry open so if it gets read again by another
116        // ModuleManager it must be the same underlying file.
117        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
118        // give us an open file, this may not be 100% reliable.
119        Buf = FileMgr.getBufferForFile(New->File,
120                                       /*IsVolatile=*/false,
121                                       /*ShouldClose=*/false);
122      }
123
124      if (!Buf) {
125        ErrorStr = Buf.getError().message();
126        return Missing;
127      }
128
129      New->Buffer = std::move(*Buf);
130    }
131
132    // Initialize the stream
133    New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
134                         (const unsigned char *)New->Buffer->getBufferEnd());
135  }
136
137  if (ExpectedSignature) {
138    if (NewModule)
139      ModuleEntry->Signature = ReadSignature(ModuleEntry->StreamFile);
140    else
141      assert(ModuleEntry->Signature == ReadSignature(ModuleEntry->StreamFile));
142
143    if (ModuleEntry->Signature != ExpectedSignature) {
144      ErrorStr = ModuleEntry->Signature ? "signature mismatch"
145                                        : "could not read module signature";
146
147      if (NewModule) {
148        // Remove the module file immediately, since removeModules might try to
149        // invalidate the file cache for Entry, and that is not safe if this
150        // module is *itself* up to date, but has an out-of-date importer.
151        Modules.erase(Entry);
152        Chain.pop_back();
153        delete ModuleEntry;
154      }
155      return OutOfDate;
156    }
157  }
158
159  if (ImportedBy) {
160    ModuleEntry->ImportedBy.insert(ImportedBy);
161    ImportedBy->Imports.insert(ModuleEntry);
162  } else {
163    if (!ModuleEntry->DirectlyImported)
164      ModuleEntry->ImportLoc = ImportLoc;
165
166    ModuleEntry->DirectlyImported = true;
167  }
168
169  Module = ModuleEntry;
170  return NewModule? NewlyLoaded : AlreadyLoaded;
171}
172
173void ModuleManager::removeModules(
174    ModuleIterator first, ModuleIterator last,
175    llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
176    ModuleMap *modMap) {
177  if (first == last)
178    return;
179
180  // Collect the set of module file pointers that we'll be removing.
181  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
182
183  // Remove any references to the now-destroyed modules.
184  for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
185    Chain[i]->ImportedBy.remove_if([&](ModuleFile *MF) {
186      return victimSet.count(MF);
187    });
188  }
189
190  // Delete the modules and erase them from the various structures.
191  for (ModuleIterator victim = first; victim != last; ++victim) {
192    Modules.erase((*victim)->File);
193
194    if (modMap) {
195      StringRef ModuleName = (*victim)->ModuleName;
196      if (Module *mod = modMap->findModule(ModuleName)) {
197        mod->setASTFile(nullptr);
198      }
199    }
200
201    // Files that didn't make it through ReadASTCore successfully will be
202    // rebuilt (or there was an error). Invalidate them so that we can load the
203    // new files that will be renamed over the old ones.
204    if (LoadedSuccessfully.count(*victim) == 0)
205      FileMgr.invalidateCache((*victim)->File);
206
207    delete *victim;
208  }
209
210  // Remove the modules from the chain.
211  Chain.erase(first, last);
212}
213
214void
215ModuleManager::addInMemoryBuffer(StringRef FileName,
216                                 std::unique_ptr<llvm::MemoryBuffer> Buffer) {
217
218  const FileEntry *Entry =
219      FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0);
220  InMemoryBuffers[Entry] = std::move(Buffer);
221}
222
223ModuleManager::VisitState *ModuleManager::allocateVisitState() {
224  // Fast path: if we have a cached state, use it.
225  if (FirstVisitState) {
226    VisitState *Result = FirstVisitState;
227    FirstVisitState = FirstVisitState->NextState;
228    Result->NextState = nullptr;
229    return Result;
230  }
231
232  // Allocate and return a new state.
233  return new VisitState(size());
234}
235
236void ModuleManager::returnVisitState(VisitState *State) {
237  assert(State->NextState == nullptr && "Visited state is in list?");
238  State->NextState = FirstVisitState;
239  FirstVisitState = State;
240}
241
242void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) {
243  GlobalIndex = Index;
244  if (!GlobalIndex) {
245    ModulesInCommonWithGlobalIndex.clear();
246    return;
247  }
248
249  // Notify the global module index about all of the modules we've already
250  // loaded.
251  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
252    if (!GlobalIndex->loadedModuleFile(Chain[I])) {
253      ModulesInCommonWithGlobalIndex.push_back(Chain[I]);
254    }
255  }
256}
257
258void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
259  if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))
260    return;
261
262  ModulesInCommonWithGlobalIndex.push_back(MF);
263}
264
265ModuleManager::ModuleManager(FileManager &FileMgr)
266  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(nullptr) {}
267
268ModuleManager::~ModuleManager() {
269  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
270    delete Chain[e - i - 1];
271  delete FirstVisitState;
272}
273
274void
275ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData),
276                     void *UserData,
277                     llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
278  // If the visitation order vector is the wrong size, recompute the order.
279  if (VisitOrder.size() != Chain.size()) {
280    unsigned N = size();
281    VisitOrder.clear();
282    VisitOrder.reserve(N);
283
284    // Record the number of incoming edges for each module. When we
285    // encounter a module with no incoming edges, push it into the queue
286    // to seed the queue.
287    SmallVector<ModuleFile *, 4> Queue;
288    Queue.reserve(N);
289    llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
290    UnusedIncomingEdges.reserve(size());
291    for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) {
292      if (unsigned Size = (*M)->ImportedBy.size())
293        UnusedIncomingEdges.push_back(Size);
294      else {
295        UnusedIncomingEdges.push_back(0);
296        Queue.push_back(*M);
297      }
298    }
299
300    // Traverse the graph, making sure to visit a module before visiting any
301    // of its dependencies.
302    unsigned QueueStart = 0;
303    while (QueueStart < Queue.size()) {
304      ModuleFile *CurrentModule = Queue[QueueStart++];
305      VisitOrder.push_back(CurrentModule);
306
307      // For any module that this module depends on, push it on the
308      // stack (if it hasn't already been marked as visited).
309      for (llvm::SetVector<ModuleFile *>::iterator
310             M = CurrentModule->Imports.begin(),
311             MEnd = CurrentModule->Imports.end();
312           M != MEnd; ++M) {
313        // Remove our current module as an impediment to visiting the
314        // module we depend on. If we were the last unvisited module
315        // that depends on this particular module, push it into the
316        // queue to be visited.
317        unsigned &NumUnusedEdges = UnusedIncomingEdges[(*M)->Index];
318        if (NumUnusedEdges && (--NumUnusedEdges == 0))
319          Queue.push_back(*M);
320      }
321    }
322
323    assert(VisitOrder.size() == N && "Visitation order is wrong?");
324
325    delete FirstVisitState;
326    FirstVisitState = nullptr;
327  }
328
329  VisitState *State = allocateVisitState();
330  unsigned VisitNumber = State->NextVisitNumber++;
331
332  // If the caller has provided us with a hit-set that came from the global
333  // module index, mark every module file in common with the global module
334  // index that is *not* in that set as 'visited'.
335  if (ModuleFilesHit && !ModulesInCommonWithGlobalIndex.empty()) {
336    for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I)
337    {
338      ModuleFile *M = ModulesInCommonWithGlobalIndex[I];
339      if (!ModuleFilesHit->count(M))
340        State->VisitNumber[M->Index] = VisitNumber;
341    }
342  }
343
344  for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) {
345    ModuleFile *CurrentModule = VisitOrder[I];
346    // Should we skip this module file?
347    if (State->VisitNumber[CurrentModule->Index] == VisitNumber)
348      continue;
349
350    // Visit the module.
351    assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1);
352    State->VisitNumber[CurrentModule->Index] = VisitNumber;
353    if (!Visitor(*CurrentModule, UserData))
354      continue;
355
356    // The visitor has requested that cut off visitation of any
357    // module that the current module depends on. To indicate this
358    // behavior, we mark all of the reachable modules as having been visited.
359    ModuleFile *NextModule = CurrentModule;
360    do {
361      // For any module that this module depends on, push it on the
362      // stack (if it hasn't already been marked as visited).
363      for (llvm::SetVector<ModuleFile *>::iterator
364             M = NextModule->Imports.begin(),
365             MEnd = NextModule->Imports.end();
366           M != MEnd; ++M) {
367        if (State->VisitNumber[(*M)->Index] != VisitNumber) {
368          State->Stack.push_back(*M);
369          State->VisitNumber[(*M)->Index] = VisitNumber;
370        }
371      }
372
373      if (State->Stack.empty())
374        break;
375
376      // Pop the next module off the stack.
377      NextModule = State->Stack.pop_back_val();
378    } while (true);
379  }
380
381  returnVisitState(State);
382}
383
384/// \brief Perform a depth-first visit of the current module.
385static bool visitDepthFirst(ModuleFile &M,
386                            bool (*Visitor)(ModuleFile &M, bool Preorder,
387                                            void *UserData),
388                            void *UserData,
389                            SmallVectorImpl<bool> &Visited) {
390  // Preorder visitation
391  if (Visitor(M, /*Preorder=*/true, UserData))
392    return true;
393
394  // Visit children
395  for (llvm::SetVector<ModuleFile *>::iterator IM = M.Imports.begin(),
396                                            IMEnd = M.Imports.end();
397       IM != IMEnd; ++IM) {
398    if (Visited[(*IM)->Index])
399      continue;
400    Visited[(*IM)->Index] = true;
401
402    if (visitDepthFirst(**IM, Visitor, UserData, Visited))
403      return true;
404  }
405
406  // Postorder visitation
407  return Visitor(M, /*Preorder=*/false, UserData);
408}
409
410void ModuleManager::visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
411                                                    void *UserData),
412                                    void *UserData) {
413  SmallVector<bool, 16> Visited(size(), false);
414  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
415    if (Visited[Chain[I]->Index])
416      continue;
417    Visited[Chain[I]->Index] = true;
418
419    if (::visitDepthFirst(*Chain[I], Visitor, UserData, Visited))
420      return;
421  }
422}
423
424bool ModuleManager::lookupModuleFile(StringRef FileName,
425                                     off_t ExpectedSize,
426                                     time_t ExpectedModTime,
427                                     const FileEntry *&File) {
428  // Open the file immediately to ensure there is no race between stat'ing and
429  // opening the file.
430  File = FileMgr.getFile(FileName, /*openFile=*/true, /*cacheFailure=*/false);
431
432  if (!File && FileName != "-") {
433    return false;
434  }
435
436  if ((ExpectedSize && ExpectedSize != File->getSize()) ||
437      (ExpectedModTime && ExpectedModTime != File->getModificationTime()))
438    // Do not destroy File, as it may be referenced. If we need to rebuild it,
439    // it will be destroyed by removeModules.
440    return true;
441
442  return false;
443}
444
445#ifndef NDEBUG
446namespace llvm {
447  template<>
448  struct GraphTraits<ModuleManager> {
449    typedef ModuleFile NodeType;
450    typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
451    typedef ModuleManager::ModuleConstIterator nodes_iterator;
452
453    static ChildIteratorType child_begin(NodeType *Node) {
454      return Node->Imports.begin();
455    }
456
457    static ChildIteratorType child_end(NodeType *Node) {
458      return Node->Imports.end();
459    }
460
461    static nodes_iterator nodes_begin(const ModuleManager &Manager) {
462      return Manager.begin();
463    }
464
465    static nodes_iterator nodes_end(const ModuleManager &Manager) {
466      return Manager.end();
467    }
468  };
469
470  template<>
471  struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
472    explicit DOTGraphTraits(bool IsSimple = false)
473      : DefaultDOTGraphTraits(IsSimple) { }
474
475    static bool renderGraphFromBottomUp() {
476      return true;
477    }
478
479    std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
480      return M->ModuleName;
481    }
482  };
483}
484
485void ModuleManager::viewGraph() {
486  llvm::ViewGraph(*this, "Modules");
487}
488#endif
489