1 //===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 GlobalModuleIndex class, which manages a global index 11 // containing all of the identifiers known to the various modules within a given 12 // subdirectory of the module cache. It is used to improve the performance of 13 // queries such as "do any modules know about this identifier?" 14 // 15 //===----------------------------------------------------------------------===// 16 #ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H 17 #define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H 18 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/SmallPtrSet.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/StringMap.h" 23 #include "llvm/ADT/StringRef.h" 24 #include <memory> 25 #include <utility> 26 27 namespace llvm { 28 class BitstreamCursor; 29 class MemoryBuffer; 30 } 31 32 namespace clang { 33 34 class DirectoryEntry; 35 class FileEntry; 36 class FileManager; 37 class IdentifierIterator; 38 class PCHContainerOperations; 39 40 namespace serialization { 41 class ModuleFile; 42 } 43 44 using llvm::SmallVector; 45 using llvm::SmallVectorImpl; 46 using llvm::StringRef; 47 using serialization::ModuleFile; 48 49 /// \brief A global index for a set of module files, providing information about 50 /// the identifiers within those module files. 51 /// 52 /// The global index is an aid for name lookup into modules, offering a central 53 /// place where one can look for identifiers determine which 54 /// module files contain any information about that identifier. This 55 /// allows the client to restrict the search to only those module files known 56 /// to have a information about that identifier, improving performance. Moreover, 57 /// the global module index may know about module files that have not been 58 /// imported, and can be queried to determine which modules the current 59 /// translation could or should load to fix a problem. 60 class GlobalModuleIndex { 61 /// \brief Buffer containing the index file, which is lazily accessed so long 62 /// as the global module index is live. 63 std::unique_ptr<llvm::MemoryBuffer> Buffer; 64 65 /// \brief The hash table. 66 /// 67 /// This pointer actually points to a IdentifierIndexTable object, 68 /// but that type is only accessible within the implementation of 69 /// GlobalModuleIndex. 70 void *IdentifierIndex; 71 72 /// \brief Information about a given module file. 73 struct ModuleInfo { ModuleInfoModuleInfo74 ModuleInfo() : File(), Size(), ModTime() { } 75 76 /// \brief The module file, once it has been resolved. 77 ModuleFile *File; 78 79 /// \brief The module file name. 80 std::string FileName; 81 82 /// \brief Size of the module file at the time the global index was built. 83 off_t Size; 84 85 /// \brief Modification time of the module file at the time the global 86 /// index was built. 87 time_t ModTime; 88 89 /// \brief The module IDs on which this module directly depends. 90 /// FIXME: We don't really need a vector here. 91 llvm::SmallVector<unsigned, 4> Dependencies; 92 }; 93 94 /// \brief A mapping from module IDs to information about each module. 95 /// 96 /// This vector may have gaps, if module files have been removed or have 97 /// been updated since the index was built. A gap is indicated by an empty 98 /// file name. 99 llvm::SmallVector<ModuleInfo, 16> Modules; 100 101 /// \brief Lazily-populated mapping from module files to their 102 /// corresponding index into the \c Modules vector. 103 llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile; 104 105 /// \brief The set of modules that have not yet been resolved. 106 /// 107 /// The string is just the name of the module itself, which maps to the 108 /// module ID. 109 llvm::StringMap<unsigned> UnresolvedModules; 110 111 /// \brief The number of identifier lookups we performed. 112 unsigned NumIdentifierLookups; 113 114 /// \brief The number of identifier lookup hits, where we recognize the 115 /// identifier. 116 unsigned NumIdentifierLookupHits; 117 118 /// \brief Internal constructor. Use \c readIndex() to read an index. 119 explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, 120 llvm::BitstreamCursor Cursor); 121 122 GlobalModuleIndex(const GlobalModuleIndex &) = delete; 123 GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete; 124 125 public: 126 ~GlobalModuleIndex(); 127 128 /// \brief An error code returned when trying to read an index. 129 enum ErrorCode { 130 /// \brief No error occurred. 131 EC_None, 132 /// \brief No index was found. 133 EC_NotFound, 134 /// \brief Some other process is currently building the index; it is not 135 /// available yet. 136 EC_Building, 137 /// \brief There was an unspecified I/O error reading or writing the index. 138 EC_IOError 139 }; 140 141 /// \brief Read a global index file for the given directory. 142 /// 143 /// \param Path The path to the specific module cache where the module files 144 /// for the intended configuration reside. 145 /// 146 /// \returns A pair containing the global module index (if it exists) and 147 /// the error code. 148 static std::pair<GlobalModuleIndex *, ErrorCode> 149 readIndex(StringRef Path); 150 151 /// \brief Returns an iterator for identifiers stored in the index table. 152 /// 153 /// The caller accepts ownership of the returned object. 154 IdentifierIterator *createIdentifierIterator() const; 155 156 /// \brief Retrieve the set of modules that have up-to-date indexes. 157 /// 158 /// \param ModuleFiles Will be populated with the set of module files that 159 /// have been indexed. 160 void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles); 161 162 /// \brief Retrieve the set of module files on which the given module file 163 /// directly depends. 164 void getModuleDependencies(ModuleFile *File, 165 SmallVectorImpl<ModuleFile *> &Dependencies); 166 167 /// \brief A set of module files in which we found a result. 168 typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet; 169 170 /// \brief Look for all of the module files with information about the given 171 /// identifier, e.g., a global function, variable, or type with that name. 172 /// 173 /// \param Name The identifier to look for. 174 /// 175 /// \param Hits Will be populated with the set of module files that have 176 /// information about this name. 177 /// 178 /// \returns true if the identifier is known to the index, false otherwise. 179 bool lookupIdentifier(StringRef Name, HitSet &Hits); 180 181 /// \brief Note that the given module file has been loaded. 182 /// 183 /// \returns false if the global module index has information about this 184 /// module file, and true otherwise. 185 bool loadedModuleFile(ModuleFile *File); 186 187 /// \brief Print statistics to standard error. 188 void printStats(); 189 190 /// \brief Print debugging view to standard error. 191 void dump(); 192 193 /// \brief Write a global index into the given 194 /// 195 /// \param FileMgr The file manager to use to load module files. 196 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and 197 /// creating modules. 198 /// \param Path The path to the directory containing module files, into 199 /// which the global index will be written. 200 static ErrorCode writeIndex(FileManager &FileMgr, 201 const PCHContainerReader &PCHContainerRdr, 202 StringRef Path); 203 }; 204 } 205 206 #endif 207