• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 namespace clang {
24 
25 class GlobalModuleIndex;
26 class ModuleMap;
27 
28 namespace serialization {
29 
30 /// \brief Manages the set of modules loaded by an AST reader.
31 class 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 {
VisitStateVisitState68     explicit VisitState(unsigned N)
69       : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
70     {
71       Stack.reserve(N);
72     }
73 
~VisitStateVisitState74     ~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 
99 public:
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.
begin()110   ModuleIterator begin() { return Chain.begin(); }
111   /// \brief Forward iterator end-point to traverse all loaded modules
end()112   ModuleIterator end() { return Chain.end(); }
113 
114   /// \brief Const forward iterator to traverse all loaded modules.  This is
115   /// in reverse source-order.
begin()116   ModuleConstIterator begin() const { return Chain.begin(); }
117   /// \brief Const forward iterator end-point to traverse all loaded modules
end()118   ModuleConstIterator end() const { return Chain.end(); }
119 
120   /// \brief Reverse iterator to traverse all loaded modules.  This is in
121   /// source order.
rbegin()122   ModuleReverseIterator rbegin() { return Chain.rbegin(); }
123   /// \brief Reverse iterator end-point to traverse all loaded modules.
rend()124   ModuleReverseIterator rend() { return Chain.rend(); }
125 
126   /// \brief Returns the primary module associated with the manager, that is,
127   /// the first module loaded
getPrimaryModule()128   ModuleFile &getPrimaryModule() { return *Chain[0]; }
129 
130   /// \brief Returns the primary module associated with the manager, that is,
131   /// the first module loaded.
getPrimaryModule()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
size()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