1 //===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ModuleManager class, which manages a set of loaded
11 // modules for the ASTReader.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
16 #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Serialization/Module.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallPtrSet.h"
25 class GlobalModuleIndex;
28 namespace serialization {
30 /// \brief Manages the set of modules loaded by an AST reader.
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;
36 /// \brief All loaded modules, indexed by name.
37 llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
39 /// \brief FileManager that handles translating between filenames and
43 /// \brief A lookup of in-memory (virtual file) buffers
44 llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
47 /// \brief The visitation order.
48 SmallVector<ModuleFile *, 4> VisitOrder;
50 /// \brief The list of module files that both we and the global module index
53 /// Either the global index or the module manager may have modules that the
54 /// other does not know about, because the global index can be out-of-date
55 /// (in which case the module manager could have modules it does not) and
56 /// this particular translation unit might not have loaded all of the modules
57 /// known to the global index.
58 SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
60 /// \brief The global module index, if one is attached.
62 /// The global module index will actually be owned by the ASTReader; this is
63 /// just an non-owning pointer.
64 GlobalModuleIndex *GlobalIndex;
66 /// \brief State used by the "visit" operation to avoid malloc traffic in
69 explicit VisitState(unsigned N)
70 : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
79 /// \brief The stack used when marking the imports of a particular module
80 /// as not-to-be-visited.
81 SmallVector<ModuleFile *, 4> Stack;
83 /// \brief The visit number of each module file, which indicates when
84 /// this module file was last visited.
85 SmallVector<unsigned, 4> VisitNumber;
87 /// \brief The next visit number to use to mark visited module files.
88 unsigned NextVisitNumber;
90 /// \brief The next visit state.
91 VisitState *NextState;
94 /// \brief The first visit() state in the chain.
95 VisitState *FirstVisitState;
97 VisitState *allocateVisitState();
98 void returnVisitState(VisitState *State);
101 typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
102 typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
103 typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
104 typedef std::pair<uint32_t, StringRef> ModuleOffset;
106 explicit ModuleManager(FileManager &FileMgr);
109 /// \brief Forward iterator to traverse all loaded modules. This is reverse
111 ModuleIterator begin() { return Chain.begin(); }
112 /// \brief Forward iterator end-point to traverse all loaded modules
113 ModuleIterator end() { return Chain.end(); }
115 /// \brief Const forward iterator to traverse all loaded modules. This is
116 /// in reverse source-order.
117 ModuleConstIterator begin() const { return Chain.begin(); }
118 /// \brief Const forward iterator end-point to traverse all loaded modules
119 ModuleConstIterator end() const { return Chain.end(); }
121 /// \brief Reverse iterator to traverse all loaded modules. This is in
123 ModuleReverseIterator rbegin() { return Chain.rbegin(); }
124 /// \brief Reverse iterator end-point to traverse all loaded modules.
125 ModuleReverseIterator rend() { return Chain.rend(); }
127 /// \brief Returns the primary module associated with the manager, that is,
128 /// the first module loaded
129 ModuleFile &getPrimaryModule() { return *Chain[0]; }
131 /// \brief Returns the primary module associated with the manager, that is,
132 /// the first module loaded.
133 ModuleFile &getPrimaryModule() const { return *Chain[0]; }
135 /// \brief Returns the module associated with the given index
136 ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
138 /// \brief Returns the module associated with the given name
139 ModuleFile *lookup(StringRef Name);
141 /// \brief Returns the module associated with the given module file.
142 ModuleFile *lookup(const FileEntry *File);
144 /// \brief Returns the in-memory (virtual file) buffer with the given name
145 std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
147 /// \brief Number of modules loaded
148 unsigned size() const { return Chain.size(); }
150 /// \brief The result of attempting to add a new module.
151 enum AddModuleResult {
152 /// \brief The module file had already been loaded.
154 /// \brief The module file was just loaded in response to this call.
156 /// \brief The module file is missing.
158 /// \brief The module file is out-of-date.
162 /// \brief Attempts to create a new module and add it to the list of known
165 /// \param FileName The file name of the module to be loaded.
167 /// \param Type The kind of module being loaded.
169 /// \param ImportLoc The location at which the module is imported.
171 /// \param ImportedBy The module that is importing this module, or NULL if
172 /// this module is imported directly by the user.
174 /// \param Generation The generation in which this module was loaded.
176 /// \param ExpectedSize The expected size of the module file, used for
177 /// validation. This will be zero if unknown.
179 /// \param ExpectedModTime The expected modification time of the module
180 /// file, used for validation. This will be zero if unknown.
182 /// \param ExpectedSignature The expected signature of the module file, used
183 /// for validation. This will be zero if unknown.
185 /// \param ReadSignature Reads the signature from an AST file without actually
188 /// \param Module A pointer to the module file if the module was successfully
191 /// \param ErrorStr Will be set to a non-empty string if any errors occurred
192 /// while trying to load the module.
194 /// \return A pointer to the module that corresponds to this file name,
195 /// and a value indicating whether the module was loaded.
196 AddModuleResult addModule(StringRef FileName, ModuleKind Type,
197 SourceLocation ImportLoc,
198 ModuleFile *ImportedBy, unsigned Generation,
199 off_t ExpectedSize, time_t ExpectedModTime,
200 ASTFileSignature ExpectedSignature,
201 std::function<ASTFileSignature(llvm::BitstreamReader &)>
204 std::string &ErrorStr);
206 /// \brief Remove the given set of modules.
207 void removeModules(ModuleIterator first, ModuleIterator last,
208 llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
211 /// \brief Add an in-memory buffer the list of known buffers
212 void addInMemoryBuffer(StringRef FileName,
213 std::unique_ptr<llvm::MemoryBuffer> Buffer);
215 /// \brief Set the global module index.
216 void setGlobalIndex(GlobalModuleIndex *Index);
218 /// \brief Notification from the AST reader that the given module file
219 /// has been "accepted", and will not (can not) be unloaded.
220 void moduleFileAccepted(ModuleFile *MF);
222 /// \brief Visit each of the modules.
224 /// This routine visits each of the modules, starting with the
225 /// "root" modules that no other loaded modules depend on, and
226 /// proceeding to the leaf modules, visiting each module only once
227 /// during the traversal.
229 /// This traversal is intended to support various "lookup"
230 /// operations that can find data in any of the loaded modules.
232 /// \param Visitor A visitor function that will be invoked with each
233 /// module and the given user data pointer. The return value must be
234 /// convertible to bool; when false, the visitation continues to
235 /// modules that the current module depends on. When true, the
236 /// visitation skips any modules that the current module depends on.
238 /// \param UserData User data associated with the visitor object, which
239 /// will be passed along to the visitor.
241 /// \param ModuleFilesHit If non-NULL, contains the set of module files
242 /// that we know we need to visit because the global module index told us to.
243 /// Any module that is known to both the global module index and the module
244 /// manager that is *not* in this set can be skipped.
245 void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
246 llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
248 /// \brief Visit each of the modules with a depth-first traversal.
250 /// This routine visits each of the modules known to the module
251 /// manager using a depth-first search, starting with the first
252 /// loaded module. The traversal invokes the callback both before
253 /// traversing the children (preorder traversal) and after
254 /// traversing the children (postorder traversal).
256 /// \param Visitor A visitor function that will be invoked with each
257 /// module and given a \c Preorder flag that indicates whether we're
258 /// visiting the module before or after visiting its children. The
259 /// visitor may return true at any time to abort the depth-first
262 /// \param UserData User data ssociated with the visitor object,
263 /// which will be passed along to the user.
264 void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
268 /// \brief Attempt to resolve the given module file name to a file entry.
270 /// \param FileName The name of the module file.
272 /// \param ExpectedSize The size that the module file is expected to have.
273 /// If the actual size differs, the resolver should return \c true.
275 /// \param ExpectedModTime The modification time that the module file is
276 /// expected to have. If the actual modification time differs, the resolver
277 /// should return \c true.
279 /// \param File Will be set to the file if there is one, or null
282 /// \returns True if a file exists but does not meet the size/
283 /// modification time criteria, false if the file is either available and
284 /// suitable, or is missing.
285 bool lookupModuleFile(StringRef FileName,
287 time_t ExpectedModTime,
288 const FileEntry *&File);
290 /// \brief View the graphviz representation of the module graph.
294 } } // end namespace clang::serialization