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