clang  3.7.0
ModuleManager.h
Go to the documentation of this file.
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_MODULEMANAGER_H
16 #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
17 
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 
23 namespace clang {
24 
25 class GlobalModuleIndex;
26 class ModuleMap;
27 class PCHContainerReader;
28 
29 namespace serialization {
30 
31 /// \brief Manages the set of modules loaded by an AST reader.
33  /// \brief The chain of AST files. The first entry is the one named by the
34  /// user, the last one is the one that doesn't depend on anything further.
36 
37  // \brief The roots of the dependency DAG of AST files. This is used
38  // to implement short-circuiting logic when running DFS over the dependencies.
40 
41  /// \brief All loaded modules, indexed by name.
42  llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
43 
44  typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet;
45 
46  /// \brief Additional module files that are known but not loaded. Tracked
47  /// here so that we can re-export them if necessary.
48  AdditionalKnownModuleFileSet AdditionalKnownModuleFiles;
49 
50  /// \brief FileManager that handles translating between filenames and
51  /// FileEntry *.
52  FileManager &FileMgr;
53 
54  /// \brief Knows how to unwrap module containers.
55  const PCHContainerReader &PCHContainerRdr;
56 
57  /// \brief A lookup of in-memory (virtual file) buffers
58  llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
59  InMemoryBuffers;
60 
61  /// \brief The visitation order.
63 
64  /// \brief The list of module files that both we and the global module index
65  /// know about.
66  ///
67  /// Either the global index or the module manager may have modules that the
68  /// other does not know about, because the global index can be out-of-date
69  /// (in which case the module manager could have modules it does not) and
70  /// this particular translation unit might not have loaded all of the modules
71  /// known to the global index.
72  SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
73 
74  /// \brief The global module index, if one is attached.
75  ///
76  /// The global module index will actually be owned by the ASTReader; this is
77  /// just an non-owning pointer.
78  GlobalModuleIndex *GlobalIndex;
79 
80  /// \brief State used by the "visit" operation to avoid malloc traffic in
81  /// calls to visit().
82  struct VisitState {
83  explicit VisitState(unsigned N)
84  : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
85  {
86  Stack.reserve(N);
87  }
88 
89  ~VisitState() {
90  delete NextState;
91  }
92 
93  /// \brief The stack used when marking the imports of a particular module
94  /// as not-to-be-visited.
96 
97  /// \brief The visit number of each module file, which indicates when
98  /// this module file was last visited.
99  SmallVector<unsigned, 4> VisitNumber;
100 
101  /// \brief The next visit number to use to mark visited module files.
102  unsigned NextVisitNumber;
103 
104  /// \brief The next visit state.
105  VisitState *NextState;
106  };
107 
108  /// \brief The first visit() state in the chain.
109  VisitState *FirstVisitState;
110 
111  VisitState *allocateVisitState();
112  void returnVisitState(VisitState *State);
113 
114 public:
118  typedef std::pair<uint32_t, StringRef> ModuleOffset;
119 
120  explicit ModuleManager(FileManager &FileMgr,
121  const PCHContainerReader &PCHContainerRdr);
122  ~ModuleManager();
123 
124  /// \brief Forward iterator to traverse all loaded modules. This is reverse
125  /// source-order.
126  ModuleIterator begin() { return Chain.begin(); }
127  /// \brief Forward iterator end-point to traverse all loaded modules
128  ModuleIterator end() { return Chain.end(); }
129 
130  /// \brief Const forward iterator to traverse all loaded modules. This is
131  /// in reverse source-order.
132  ModuleConstIterator begin() const { return Chain.begin(); }
133  /// \brief Const forward iterator end-point to traverse all loaded modules
134  ModuleConstIterator end() const { return Chain.end(); }
135 
136  /// \brief Reverse iterator to traverse all loaded modules. This is in
137  /// source order.
138  ModuleReverseIterator rbegin() { return Chain.rbegin(); }
139  /// \brief Reverse iterator end-point to traverse all loaded modules.
140  ModuleReverseIterator rend() { return Chain.rend(); }
141 
142  /// \brief Returns the primary module associated with the manager, that is,
143  /// the first module loaded
144  ModuleFile &getPrimaryModule() { return *Chain[0]; }
145 
146  /// \brief Returns the primary module associated with the manager, that is,
147  /// the first module loaded.
148  ModuleFile &getPrimaryModule() const { return *Chain[0]; }
149 
150  /// \brief Returns the module associated with the given index
151  ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
152 
153  /// \brief Returns the module associated with the given name
154  ModuleFile *lookup(StringRef Name);
155 
156  /// \brief Returns the module associated with the given module file.
157  ModuleFile *lookup(const FileEntry *File);
158 
159  /// \brief Returns the in-memory (virtual file) buffer with the given name
160  std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
161 
162  /// \brief Number of modules loaded
163  unsigned size() const { return Chain.size(); }
164 
165  /// \brief The result of attempting to add a new module.
167  /// \brief The module file had already been loaded.
169  /// \brief The module file was just loaded in response to this call.
171  /// \brief The module file is missing.
173  /// \brief The module file is out-of-date.
175  };
176 
177  typedef ASTFileSignature(*ASTFileSignatureReader)(llvm::BitstreamReader &);
178 
179  /// \brief Attempts to create a new module and add it to the list of known
180  /// modules.
181  ///
182  /// \param FileName The file name of the module to be loaded.
183  ///
184  /// \param Type The kind of module being loaded.
185  ///
186  /// \param ImportLoc The location at which the module is imported.
187  ///
188  /// \param ImportedBy The module that is importing this module, or NULL if
189  /// this module is imported directly by the user.
190  ///
191  /// \param Generation The generation in which this module was loaded.
192  ///
193  /// \param ExpectedSize The expected size of the module file, used for
194  /// validation. This will be zero if unknown.
195  ///
196  /// \param ExpectedModTime The expected modification time of the module
197  /// file, used for validation. This will be zero if unknown.
198  ///
199  /// \param ExpectedSignature The expected signature of the module file, used
200  /// for validation. This will be zero if unknown.
201  ///
202  /// \param ReadSignature Reads the signature from an AST file without actually
203  /// loading it.
204  ///
205  /// \param Module A pointer to the module file if the module was successfully
206  /// loaded.
207  ///
208  /// \param ErrorStr Will be set to a non-empty string if any errors occurred
209  /// while trying to load the module.
210  ///
211  /// \return A pointer to the module that corresponds to this file name,
212  /// and a value indicating whether the module was loaded.
213  AddModuleResult addModule(StringRef FileName, ModuleKind Type,
214  SourceLocation ImportLoc,
215  ModuleFile *ImportedBy, unsigned Generation,
216  off_t ExpectedSize, time_t ExpectedModTime,
217  ASTFileSignature ExpectedSignature,
218  ASTFileSignatureReader ReadSignature,
219  ModuleFile *&Module,
220  std::string &ErrorStr);
221 
222  /// \brief Remove the given set of modules.
224  llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
225  ModuleMap *modMap);
226 
227  /// \brief Add an in-memory buffer the list of known buffers
228  void addInMemoryBuffer(StringRef FileName,
229  std::unique_ptr<llvm::MemoryBuffer> Buffer);
230 
231  /// \brief Set the global module index.
232  void setGlobalIndex(GlobalModuleIndex *Index);
233 
234  /// \brief Notification from the AST reader that the given module file
235  /// has been "accepted", and will not (can not) be unloaded.
236  void moduleFileAccepted(ModuleFile *MF);
237 
238  /// \brief Notification from the frontend that the given module file is
239  /// part of this compilation (even if not imported) and, if this compilation
240  /// is exported, should be made available to importers of it.
241  bool addKnownModuleFile(StringRef FileName);
242 
243  /// \brief Get a list of additional module files that are not currently
244  /// loaded but are considered to be part of the current compilation.
245  llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator>
247  return llvm::make_range(AdditionalKnownModuleFiles.begin(),
248  AdditionalKnownModuleFiles.end());
249  }
250 
251  /// \brief Visit each of the modules.
252  ///
253  /// This routine visits each of the modules, starting with the
254  /// "root" modules that no other loaded modules depend on, and
255  /// proceeding to the leaf modules, visiting each module only once
256  /// during the traversal.
257  ///
258  /// This traversal is intended to support various "lookup"
259  /// operations that can find data in any of the loaded modules.
260  ///
261  /// \param Visitor A visitor function that will be invoked with each
262  /// module and the given user data pointer. The return value must be
263  /// convertible to bool; when false, the visitation continues to
264  /// modules that the current module depends on. When true, the
265  /// visitation skips any modules that the current module depends on.
266  ///
267  /// \param UserData User data associated with the visitor object, which
268  /// will be passed along to the visitor.
269  ///
270  /// \param ModuleFilesHit If non-NULL, contains the set of module files
271  /// that we know we need to visit because the global module index told us to.
272  /// Any module that is known to both the global module index and the module
273  /// manager that is *not* in this set can be skipped.
274  void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
275  llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
276 
277  /// \brief Control DFS behavior during preorder visitation.
279  Continue, /// Continue visiting all nodes.
280  Abort, /// Stop the visitation immediately.
281  SkipImports, /// Do not visit imports of the current node.
282  };
283 
284  /// \brief Visit each of the modules with a depth-first traversal.
285  ///
286  /// This routine visits each of the modules known to the module
287  /// manager using a depth-first search, starting with the first
288  /// loaded module. The traversal invokes one callback before
289  /// traversing the imports (preorder traversal) and one after
290  /// traversing the imports (postorder traversal).
291  ///
292  /// \param PreorderVisitor A visitor function that will be invoked with each
293  /// module before visiting its imports. The visitor can control how to
294  /// continue the visitation through its return value.
295  ///
296  /// \param PostorderVisitor A visitor function taht will be invoked with each
297  /// module after visiting its imports. The visitor may return true at any time
298  /// to abort the depth-first visitation.
299  ///
300  /// \param UserData User data ssociated with the visitor object,
301  /// which will be passed along to the user.
302  void visitDepthFirst(DFSPreorderControl (*PreorderVisitor)(ModuleFile &M,
303  void *UserData),
304  bool (*PostorderVisitor)(ModuleFile &M, void *UserData),
305  void *UserData);
306 
307  /// \brief Attempt to resolve the given module file name to a file entry.
308  ///
309  /// \param FileName The name of the module file.
310  ///
311  /// \param ExpectedSize The size that the module file is expected to have.
312  /// If the actual size differs, the resolver should return \c true.
313  ///
314  /// \param ExpectedModTime The modification time that the module file is
315  /// expected to have. If the actual modification time differs, the resolver
316  /// should return \c true.
317  ///
318  /// \param File Will be set to the file if there is one, or null
319  /// otherwise.
320  ///
321  /// \returns True if a file exists but does not meet the size/
322  /// modification time criteria, false if the file is either available and
323  /// suitable, or is missing.
324  bool lookupModuleFile(StringRef FileName,
325  off_t ExpectedSize,
326  time_t ExpectedModTime,
327  const FileEntry *&File);
328 
329  /// \brief View the graphviz representation of the module graph.
330  void viewGraph();
331 };
332 
333 } } // end namespace clang::serialization
334 
335 #endif
bool addKnownModuleFile(StringRef FileName)
Notification from the frontend that the given module file is part of this compilation (even if not im...
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:115
Defines the clang::FileManager interface and associated types.
unsigned size() const
Number of modules loaded.
The module file is out-of-date.
Manages the set of modules loaded by an AST reader.
Definition: ModuleManager.h:32
SmallVectorImpl< ModuleFile * >::const_iterator ModuleConstIterator
ModuleConstIterator begin() const
Const forward iterator to traverse all loaded modules. This is in reverse source-order.
AddModuleResult
The result of attempting to add a new module.
ModuleIterator begin()
Forward iterator to traverse all loaded modules. This is reverse source-order.
LineState State
void viewGraph()
View the graphviz representation of the module graph.
ModuleFile & getPrimaryModule() const
Returns the primary module associated with the manager, that is, the first module loaded...
void setGlobalIndex(GlobalModuleIndex *Index)
Set the global module index.
Describes a module or submodule.
Definition: Basic/Module.h:49
void visitDepthFirst(DFSPreorderControl(*PreorderVisitor)(ModuleFile &M, void *UserData), bool(*PostorderVisitor)(ModuleFile &M, void *UserData), void *UserData)
Visit each of the modules with a depth-first traversal.
Stop the visitation immediately.
ASTFileSignature(* ASTFileSignatureReader)(llvm::BitstreamReader &)
bool lookupModuleFile(StringRef FileName, off_t ExpectedSize, time_t ExpectedModTime, const FileEntry *&File)
Attempt to resolve the given module file name to a file entry.
ModuleIterator end()
Forward iterator end-point to traverse all loaded modules.
llvm::iterator_range< AdditionalKnownModuleFileSet::const_iterator > getAdditionalKnownModuleFiles()
Get a list of additional module files that are not currently loaded but are considered to be part of ...
ModuleReverseIterator rend()
Reverse iterator end-point to traverse all loaded modules.
ModuleKind
Specifies the kind of module that has been loaded.
std::vector< bool > & Stack
SmallVectorImpl< ModuleFile * >::reverse_iterator ModuleReverseIterator
ModuleFile * lookup(StringRef Name)
Returns the module associated with the given name.
Information about a module that has been loaded by the ASTReader.
DFSPreorderControl
Control DFS behavior during preorder visitation.
void visit(bool(*Visitor)(ModuleFile &M, void *UserData), void *UserData, llvm::SmallPtrSetImpl< ModuleFile * > *ModuleFilesHit=nullptr)
Visit each of the modules.
AddModuleResult addModule(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, ModuleFile *ImportedBy, unsigned Generation, off_t ExpectedSize, time_t ExpectedModTime, ASTFileSignature ExpectedSignature, ASTFileSignatureReader ReadSignature, ModuleFile *&Module, std::string &ErrorStr)
Attempts to create a new module and add it to the list of known modules.
ModuleManager(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr)
void addInMemoryBuffer(StringRef FileName, std::unique_ptr< llvm::MemoryBuffer > Buffer)
Add an in-memory buffer the list of known buffers.
ModuleFile & operator[](unsigned Index) const
Returns the module associated with the given index.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
ModuleReverseIterator rbegin()
Reverse iterator to traverse all loaded modules. This is in source order.
A global index for a set of module files, providing information about the identifiers within those mo...
The module file was just loaded in response to this call.
ModuleFile & getPrimaryModule()
Returns the primary module associated with the manager, that is, the first module loaded...
void moduleFileAccepted(ModuleFile *MF)
Notification from the AST reader that the given module file has been "accepted", and will not (can no...
void removeModules(ModuleIterator first, ModuleIterator last, llvm::SmallPtrSetImpl< ModuleFile * > &LoadedSuccessfully, ModuleMap *modMap)
Remove the given set of modules.
Continue visiting all nodes.
std::pair< uint32_t, StringRef > ModuleOffset
ModuleConstIterator end() const
Const forward iterator end-point to traverse all loaded modules.
The module file had already been loaded.
SmallVectorImpl< ModuleFile * >::iterator ModuleIterator
std::unique_ptr< llvm::MemoryBuffer > lookupBuffer(StringRef Name)
Returns the in-memory (virtual file) buffer with the given name.