ModuleManager.h revision ef8225444452a1486bd721f3285301fe84643b00
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
15#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
16#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
17
18#include "clang/Basic/FileManager.h"
19#include "clang/Serialization/Module.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallPtrSet.h"
22
23namespace clang {
24
25class GlobalModuleIndex;
26class ModuleMap;
27
28namespace serialization {
29
30/// \brief Manages the set of modules loaded by an AST reader.
31class ModuleManager {
32  /// \brief The chain of AST files. The first entry is the one named by the
33  /// user, the last one is the one that doesn't depend on anything further.
34  SmallVector<ModuleFile *, 2> Chain;
35
36  /// \brief All loaded modules, indexed by name.
37  llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
38
39  /// \brief FileManager that handles translating between filenames and
40  /// FileEntry *.
41  FileManager &FileMgr;
42
43  /// \brief A lookup of in-memory (virtual file) buffers
44  llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers;
45
46  /// \brief The visitation order.
47  SmallVector<ModuleFile *, 4> VisitOrder;
48
49  /// \brief The list of module files that both we and the global module index
50  /// know about.
51  ///
52  /// Either the global index or the module manager may have modules that the
53  /// other does not know about, because the global index can be out-of-date
54  /// (in which case the module manager could have modules it does not) and
55  /// this particular translation unit might not have loaded all of the modules
56  /// known to the global index.
57  SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
58
59  /// \brief The global module index, if one is attached.
60  ///
61  /// The global module index will actually be owned by the ASTReader; this is
62  /// just an non-owning pointer.
63  GlobalModuleIndex *GlobalIndex;
64
65  /// \brief State used by the "visit" operation to avoid malloc traffic in
66  /// calls to visit().
67  struct VisitState {
68    explicit VisitState(unsigned N)
69      : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
70    {
71      Stack.reserve(N);
72    }
73
74    ~VisitState() {
75      delete NextState;
76    }
77
78    /// \brief The stack used when marking the imports of a particular module
79    /// as not-to-be-visited.
80    SmallVector<ModuleFile *, 4> Stack;
81
82    /// \brief The visit number of each module file, which indicates when
83    /// this module file was last visited.
84    SmallVector<unsigned, 4> VisitNumber;
85
86    /// \brief The next visit number to use to mark visited module files.
87    unsigned NextVisitNumber;
88
89    /// \brief The next visit state.
90    VisitState *NextState;
91  };
92
93  /// \brief The first visit() state in the chain.
94  VisitState *FirstVisitState;
95
96  VisitState *allocateVisitState();
97  void returnVisitState(VisitState *State);
98
99public:
100  typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
101  typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
102  typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
103  typedef std::pair<uint32_t, StringRef> ModuleOffset;
104
105  explicit ModuleManager(FileManager &FileMgr);
106  ~ModuleManager();
107
108  /// \brief Forward iterator to traverse all loaded modules.  This is reverse
109  /// source-order.
110  ModuleIterator begin() { return Chain.begin(); }
111  /// \brief Forward iterator end-point to traverse all loaded modules
112  ModuleIterator end() { return Chain.end(); }
113
114  /// \brief Const forward iterator to traverse all loaded modules.  This is
115  /// in reverse source-order.
116  ModuleConstIterator begin() const { return Chain.begin(); }
117  /// \brief Const forward iterator end-point to traverse all loaded modules
118  ModuleConstIterator end() const { return Chain.end(); }
119
120  /// \brief Reverse iterator to traverse all loaded modules.  This is in
121  /// source order.
122  ModuleReverseIterator rbegin() { return Chain.rbegin(); }
123  /// \brief Reverse iterator end-point to traverse all loaded modules.
124  ModuleReverseIterator rend() { return Chain.rend(); }
125
126  /// \brief Returns the primary module associated with the manager, that is,
127  /// the first module loaded
128  ModuleFile &getPrimaryModule() { return *Chain[0]; }
129
130  /// \brief Returns the primary module associated with the manager, that is,
131  /// the first module loaded.
132  ModuleFile &getPrimaryModule() const { return *Chain[0]; }
133
134  /// \brief Returns the module associated with the given index
135  ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
136
137  /// \brief Returns the module associated with the given name
138  ModuleFile *lookup(StringRef Name);
139
140  /// \brief Returns the module associated with the given module file.
141  ModuleFile *lookup(const FileEntry *File);
142
143  /// \brief Returns the in-memory (virtual file) buffer with the given name
144  llvm::MemoryBuffer *lookupBuffer(StringRef Name);
145
146  /// \brief Number of modules loaded
147  unsigned size() const { return Chain.size(); }
148
149  /// \brief The result of attempting to add a new module.
150  enum AddModuleResult {
151    /// \brief The module file had already been loaded.
152    AlreadyLoaded,
153    /// \brief The module file was just loaded in response to this call.
154    NewlyLoaded,
155    /// \brief The module file is missing.
156    Missing,
157    /// \brief The module file is out-of-date.
158    OutOfDate
159  };
160
161  /// \brief Attempts to create a new module and add it to the list of known
162  /// modules.
163  ///
164  /// \param FileName The file name of the module to be loaded.
165  ///
166  /// \param Type The kind of module being loaded.
167  ///
168  /// \param ImportLoc The location at which the module is imported.
169  ///
170  /// \param ImportedBy The module that is importing this module, or NULL if
171  /// this module is imported directly by the user.
172  ///
173  /// \param Generation The generation in which this module was loaded.
174  ///
175  /// \param ExpectedSize The expected size of the module file, used for
176  /// validation. This will be zero if unknown.
177  ///
178  /// \param ExpectedModTime The expected modification time of the module
179  /// file, used for validation. This will be zero if unknown.
180  ///
181  /// \param Module A pointer to the module file if the module was successfully
182  /// loaded.
183  ///
184  /// \param ErrorStr Will be set to a non-empty string if any errors occurred
185  /// while trying to load the module.
186  ///
187  /// \return A pointer to the module that corresponds to this file name,
188  /// and a value indicating whether the module was loaded.
189  AddModuleResult addModule(StringRef FileName, ModuleKind Type,
190                            SourceLocation ImportLoc,
191                            ModuleFile *ImportedBy, unsigned Generation,
192                            off_t ExpectedSize, time_t ExpectedModTime,
193                            ModuleFile *&Module,
194                            std::string &ErrorStr);
195
196  /// \brief Remove the given set of modules.
197  void removeModules(ModuleIterator first, ModuleIterator last,
198                     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
199                     ModuleMap *modMap);
200
201  /// \brief Add an in-memory buffer the list of known buffers
202  void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
203
204  /// \brief Set the global module index.
205  void setGlobalIndex(GlobalModuleIndex *Index);
206
207  /// \brief Notification from the AST reader that the given module file
208  /// has been "accepted", and will not (can not) be unloaded.
209  void moduleFileAccepted(ModuleFile *MF);
210
211  /// \brief Visit each of the modules.
212  ///
213  /// This routine visits each of the modules, starting with the
214  /// "root" modules that no other loaded modules depend on, and
215  /// proceeding to the leaf modules, visiting each module only once
216  /// during the traversal.
217  ///
218  /// This traversal is intended to support various "lookup"
219  /// operations that can find data in any of the loaded modules.
220  ///
221  /// \param Visitor A visitor function that will be invoked with each
222  /// module and the given user data pointer. The return value must be
223  /// convertible to bool; when false, the visitation continues to
224  /// modules that the current module depends on. When true, the
225  /// visitation skips any modules that the current module depends on.
226  ///
227  /// \param UserData User data associated with the visitor object, which
228  /// will be passed along to the visitor.
229  ///
230  /// \param ModuleFilesHit If non-NULL, contains the set of module files
231  /// that we know we need to visit because the global module index told us to.
232  /// Any module that is known to both the global module index and the module
233  /// manager that is *not* in this set can be skipped.
234  void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
235             llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = nullptr);
236
237  /// \brief Visit each of the modules with a depth-first traversal.
238  ///
239  /// This routine visits each of the modules known to the module
240  /// manager using a depth-first search, starting with the first
241  /// loaded module. The traversal invokes the callback both before
242  /// traversing the children (preorder traversal) and after
243  /// traversing the children (postorder traversal).
244  ///
245  /// \param Visitor A visitor function that will be invoked with each
246  /// module and given a \c Preorder flag that indicates whether we're
247  /// visiting the module before or after visiting its children.  The
248  /// visitor may return true at any time to abort the depth-first
249  /// visitation.
250  ///
251  /// \param UserData User data ssociated with the visitor object,
252  /// which will be passed along to the user.
253  void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
254                                       void *UserData),
255                       void *UserData);
256
257  /// \brief Attempt to resolve the given module file name to a file entry.
258  ///
259  /// \param FileName The name of the module file.
260  ///
261  /// \param ExpectedSize The size that the module file is expected to have.
262  /// If the actual size differs, the resolver should return \c true.
263  ///
264  /// \param ExpectedModTime The modification time that the module file is
265  /// expected to have. If the actual modification time differs, the resolver
266  /// should return \c true.
267  ///
268  /// \param File Will be set to the file if there is one, or null
269  /// otherwise.
270  ///
271  /// \returns True if a file exists but does not meet the size/
272  /// modification time criteria, false if the file is either available and
273  /// suitable, or is missing.
274  bool lookupModuleFile(StringRef FileName,
275                        off_t ExpectedSize,
276                        time_t ExpectedModTime,
277                        const FileEntry *&File);
278
279  /// \brief View the graphviz representation of the module graph.
280  void viewGraph();
281};
282
283} } // end namespace clang::serialization
284
285#endif
286