1 //===- ModuleManager.cpp - Module Manager -----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the ModuleManager class, which manages a set of loaded 10 // modules for the ASTReader. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H 15 #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H 16 17 #include "clang/Basic/LLVM.h" 18 #include "clang/Basic/SourceLocation.h" 19 #include "clang/Serialization/ModuleFile.h" 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/ADT/IntrusiveRefCntPtr.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/ADT/SmallPtrSet.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/iterator.h" 27 #include "llvm/ADT/iterator_range.h" 28 #include <cstdint> 29 #include <ctime> 30 #include <memory> 31 #include <string> 32 #include <utility> 33 34 namespace clang { 35 36 class FileEntry; 37 class FileManager; 38 class GlobalModuleIndex; 39 class HeaderSearch; 40 class InMemoryModuleCache; 41 class PCHContainerReader; 42 43 namespace serialization { 44 45 /// Manages the set of modules loaded by an AST reader. 46 class ModuleManager { 47 /// The chain of AST files, in the order in which we started to load 48 /// them. 49 SmallVector<std::unique_ptr<ModuleFile>, 2> Chain; 50 51 /// The chain of non-module PCH files. The first entry is the one named 52 /// by the user, the last one is the one that doesn't depend on anything 53 /// further. 54 SmallVector<ModuleFile *, 2> PCHChain; 55 56 // The roots of the dependency DAG of AST files. This is used 57 // to implement short-circuiting logic when running DFS over the dependencies. 58 SmallVector<ModuleFile *, 2> Roots; 59 60 /// All loaded modules, indexed by name. 61 llvm::DenseMap<const FileEntry *, ModuleFile *> Modules; 62 63 /// FileManager that handles translating between filenames and 64 /// FileEntry *. 65 FileManager &FileMgr; 66 67 /// Cache of PCM files. 68 IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache; 69 70 /// Knows how to unwrap module containers. 71 const PCHContainerReader &PCHContainerRdr; 72 73 /// Preprocessor's HeaderSearchInfo containing the module map. 74 const HeaderSearch &HeaderSearchInfo; 75 76 /// A lookup of in-memory (virtual file) buffers 77 llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>> 78 InMemoryBuffers; 79 80 /// The visitation order. 81 SmallVector<ModuleFile *, 4> VisitOrder; 82 83 /// The list of module files that both we and the global module index 84 /// know about. 85 /// 86 /// Either the global index or the module manager may have modules that the 87 /// other does not know about, because the global index can be out-of-date 88 /// (in which case the module manager could have modules it does not) and 89 /// this particular translation unit might not have loaded all of the modules 90 /// known to the global index. 91 SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex; 92 93 /// The global module index, if one is attached. 94 /// 95 /// The global module index will actually be owned by the ASTReader; this is 96 /// just an non-owning pointer. 97 GlobalModuleIndex *GlobalIndex = nullptr; 98 99 /// State used by the "visit" operation to avoid malloc traffic in 100 /// calls to visit(). 101 struct VisitState { VisitStateVisitState102 explicit VisitState(unsigned N) : VisitNumber(N, 0) { 103 Stack.reserve(N); 104 } 105 106 /// The stack used when marking the imports of a particular module 107 /// as not-to-be-visited. 108 SmallVector<ModuleFile *, 4> Stack; 109 110 /// The visit number of each module file, which indicates when 111 /// this module file was last visited. 112 SmallVector<unsigned, 4> VisitNumber; 113 114 /// The next visit number to use to mark visited module files. 115 unsigned NextVisitNumber = 1; 116 117 /// The next visit state. 118 std::unique_ptr<VisitState> NextState; 119 }; 120 121 /// The first visit() state in the chain. 122 std::unique_ptr<VisitState> FirstVisitState; 123 124 std::unique_ptr<VisitState> allocateVisitState(); 125 void returnVisitState(std::unique_ptr<VisitState> State); 126 127 public: 128 using ModuleIterator = llvm::pointee_iterator< 129 SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>; 130 using ModuleConstIterator = llvm::pointee_iterator< 131 SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>; 132 using ModuleReverseIterator = llvm::pointee_iterator< 133 SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>; 134 using ModuleOffset = std::pair<uint32_t, StringRef>; 135 136 explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache, 137 const PCHContainerReader &PCHContainerRdr, 138 const HeaderSearch &HeaderSearchInfo); 139 140 /// Forward iterator to traverse all loaded modules. begin()141 ModuleIterator begin() { return Chain.begin(); } 142 143 /// Forward iterator end-point to traverse all loaded modules end()144 ModuleIterator end() { return Chain.end(); } 145 146 /// Const forward iterator to traverse all loaded modules. begin()147 ModuleConstIterator begin() const { return Chain.begin(); } 148 149 /// Const forward iterator end-point to traverse all loaded modules end()150 ModuleConstIterator end() const { return Chain.end(); } 151 152 /// Reverse iterator to traverse all loaded modules. rbegin()153 ModuleReverseIterator rbegin() { return Chain.rbegin(); } 154 155 /// Reverse iterator end-point to traverse all loaded modules. rend()156 ModuleReverseIterator rend() { return Chain.rend(); } 157 158 /// A range covering the PCH and preamble module files loaded. 159 llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator> pch_modules()160 pch_modules() const { 161 return llvm::make_range(PCHChain.begin(), PCHChain.end()); 162 } 163 164 /// Returns the primary module associated with the manager, that is, 165 /// the first module loaded getPrimaryModule()166 ModuleFile &getPrimaryModule() { return *Chain[0]; } 167 168 /// Returns the primary module associated with the manager, that is, 169 /// the first module loaded. getPrimaryModule()170 ModuleFile &getPrimaryModule() const { return *Chain[0]; } 171 172 /// Returns the module associated with the given index 173 ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; } 174 175 /// Returns the module associated with the given file name. 176 ModuleFile *lookupByFileName(StringRef FileName) const; 177 178 /// Returns the module associated with the given module name. 179 ModuleFile *lookupByModuleName(StringRef ModName) const; 180 181 /// Returns the module associated with the given module file. 182 ModuleFile *lookup(const FileEntry *File) const; 183 184 /// Returns the in-memory (virtual file) buffer with the given name 185 std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name); 186 187 /// Number of modules loaded size()188 unsigned size() const { return Chain.size(); } 189 190 /// The result of attempting to add a new module. 191 enum AddModuleResult { 192 /// The module file had already been loaded. 193 AlreadyLoaded, 194 195 /// The module file was just loaded in response to this call. 196 NewlyLoaded, 197 198 /// The module file is missing. 199 Missing, 200 201 /// The module file is out-of-date. 202 OutOfDate 203 }; 204 205 using ASTFileSignatureReader = ASTFileSignature (*)(StringRef); 206 207 /// Attempts to create a new module and add it to the list of known 208 /// modules. 209 /// 210 /// \param FileName The file name of the module to be loaded. 211 /// 212 /// \param Type The kind of module being loaded. 213 /// 214 /// \param ImportLoc The location at which the module is imported. 215 /// 216 /// \param ImportedBy The module that is importing this module, or NULL if 217 /// this module is imported directly by the user. 218 /// 219 /// \param Generation The generation in which this module was loaded. 220 /// 221 /// \param ExpectedSize The expected size of the module file, used for 222 /// validation. This will be zero if unknown. 223 /// 224 /// \param ExpectedModTime The expected modification time of the module 225 /// file, used for validation. This will be zero if unknown. 226 /// 227 /// \param ExpectedSignature The expected signature of the module file, used 228 /// for validation. This will be zero if unknown. 229 /// 230 /// \param ReadSignature Reads the signature from an AST file without actually 231 /// loading it. 232 /// 233 /// \param Module A pointer to the module file if the module was successfully 234 /// loaded. 235 /// 236 /// \param ErrorStr Will be set to a non-empty string if any errors occurred 237 /// while trying to load the module. 238 /// 239 /// \return A pointer to the module that corresponds to this file name, 240 /// and a value indicating whether the module was loaded. 241 AddModuleResult addModule(StringRef FileName, ModuleKind Type, 242 SourceLocation ImportLoc, 243 ModuleFile *ImportedBy, unsigned Generation, 244 off_t ExpectedSize, time_t ExpectedModTime, 245 ASTFileSignature ExpectedSignature, 246 ASTFileSignatureReader ReadSignature, 247 ModuleFile *&Module, 248 std::string &ErrorStr); 249 250 /// Remove the modules starting from First (to the end). 251 void removeModules(ModuleIterator First); 252 253 /// Add an in-memory buffer the list of known buffers 254 void addInMemoryBuffer(StringRef FileName, 255 std::unique_ptr<llvm::MemoryBuffer> Buffer); 256 257 /// Set the global module index. 258 void setGlobalIndex(GlobalModuleIndex *Index); 259 260 /// Notification from the AST reader that the given module file 261 /// has been "accepted", and will not (can not) be unloaded. 262 void moduleFileAccepted(ModuleFile *MF); 263 264 /// Visit each of the modules. 265 /// 266 /// This routine visits each of the modules, starting with the 267 /// "root" modules that no other loaded modules depend on, and 268 /// proceeding to the leaf modules, visiting each module only once 269 /// during the traversal. 270 /// 271 /// This traversal is intended to support various "lookup" 272 /// operations that can find data in any of the loaded modules. 273 /// 274 /// \param Visitor A visitor function that will be invoked with each 275 /// module. The return value must be convertible to bool; when false, the 276 /// visitation continues to modules that the current module depends on. When 277 /// true, the visitation skips any modules that the current module depends on. 278 /// 279 /// \param ModuleFilesHit If non-NULL, contains the set of module files 280 /// that we know we need to visit because the global module index told us to. 281 /// Any module that is known to both the global module index and the module 282 /// manager that is *not* in this set can be skipped. 283 void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, 284 llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr); 285 286 /// Attempt to resolve the given module file name to a file entry. 287 /// 288 /// \param FileName The name of the module file. 289 /// 290 /// \param ExpectedSize The size that the module file is expected to have. 291 /// If the actual size differs, the resolver should return \c true. 292 /// 293 /// \param ExpectedModTime The modification time that the module file is 294 /// expected to have. If the actual modification time differs, the resolver 295 /// should return \c true. 296 /// 297 /// \param File Will be set to the file if there is one, or null 298 /// otherwise. 299 /// 300 /// \returns True if a file exists but does not meet the size/ 301 /// modification time criteria, false if the file is either available and 302 /// suitable, or is missing. 303 bool lookupModuleFile(StringRef FileName, off_t ExpectedSize, 304 time_t ExpectedModTime, OptionalFileEntryRef &File); 305 306 /// View the graphviz representation of the module graph. 307 void viewGraph(); 308 getModuleCache()309 InMemoryModuleCache &getModuleCache() const { return *ModuleCache; } 310 }; 311 312 } // namespace serialization 313 314 } // namespace clang 315 316 #endif // LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H 317