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_GLOBAL_MODULE_INDEX_H 17 #define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H 18 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/OwningPtr.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringRef.h" 24 #include <utility> 25 26 namespace llvm { 27 class BitstreamCursor; 28 class MemoryBuffer; 29 } 30 31 namespace clang { 32 33 class DirectoryEntry; 34 class FileEntry; 35 class FileManager; 36 37 using llvm::SmallVector; 38 using llvm::SmallVectorImpl; 39 using llvm::StringRef; 40 41 /// \brief A global index for a set of module files, providing information about 42 /// the identifiers within those module files. 43 /// 44 /// The global index is an aid for name lookup into modules, offering a central 45 /// place where one can look for identifiers determine which 46 /// module files contain any information about that identifier. This 47 /// allows the client to restrict the search to only those module files known 48 /// to have a information about that identifier, improving performance. Moreover, 49 /// the global module index may know about module files that have not been 50 /// imported, and can be queried to determine which modules the current 51 /// translation could or should load to fix a problem. 52 class GlobalModuleIndex { 53 /// \brief Buffer containing the index file, which is lazily accessed so long 54 /// as the global module index is live. 55 llvm::OwningPtr<llvm::MemoryBuffer> Buffer; 56 57 /// \brief The hash table. 58 /// 59 /// This pointer actually points to a IdentifierIndexTable object, 60 /// but that type is only accessible within the implementation of 61 /// GlobalModuleIndex. 62 void *IdentifierIndex; 63 64 /// \brief Information about a given module file. 65 struct ModuleInfo { 66 ModuleInfo() : File() { } 67 68 /// \brief The module file entry. 69 const FileEntry *File; 70 71 /// \brief The module files on which this module directly depends. 72 llvm::SmallVector<const FileEntry *, 4> Dependencies; 73 }; 74 75 /// \brief A mapping from module IDs to information about each module. 76 /// 77 /// This vector may have gaps, if module files have been removed or have 78 /// been updated since the index was built. A gap is indicated by an empty 79 /// \c File pointer. 80 llvm::SmallVector<ModuleInfo, 16> Modules; 81 82 /// \brief Lazily-populated mapping from module file entries to their 83 /// corresponding index into the \c Modules vector. 84 llvm::DenseMap<const FileEntry *, unsigned> ModulesByFile; 85 86 /// \brief The number of identifier lookups we performed. 87 unsigned NumIdentifierLookups; 88 89 /// \brief The number of identifier lookup hits, where we recognize the 90 /// identifier. 91 unsigned NumIdentifierLookupHits; 92 93 /// \brief Internal constructor. Use \c readIndex() to read an index. 94 explicit GlobalModuleIndex(FileManager &FileMgr, llvm::MemoryBuffer *Buffer, 95 llvm::BitstreamCursor Cursor); 96 97 GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION; 98 GlobalModuleIndex &operator=(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION; 99 100 public: 101 ~GlobalModuleIndex(); 102 103 /// \brief An error code returned when trying to read an index. 104 enum ErrorCode { 105 /// \brief No error occurred. 106 EC_None, 107 /// \brief No index was found. 108 EC_NotFound, 109 /// \brief Some other process is currently building the index; it is not 110 /// available yet. 111 EC_Building, 112 /// \brief There was an unspecified I/O error reading or writing the index. 113 EC_IOError 114 }; 115 116 /// \brief Read a global index file for the given directory. 117 /// 118 /// \param FileMgr The file manager to use for reading files. 119 /// 120 /// \param Path The path to the specific module cache where the module files 121 /// for the intended configuration reside. 122 /// 123 /// \returns A pair containing the global module index (if it exists) and 124 /// the error code. 125 static std::pair<GlobalModuleIndex *, ErrorCode> 126 readIndex(FileManager &FileMgr, StringRef Path); 127 128 /// \brief Retrieve the set of modules that have up-to-date indexes. 129 /// 130 /// \param ModuleFiles Will be populated with the set of module files that 131 /// have been indexed. 132 void getKnownModules(SmallVectorImpl<const FileEntry *> &ModuleFiles); 133 134 /// \brief Retrieve the set of module files on which the given module file 135 /// directly depends. 136 void getModuleDependencies(const FileEntry *ModuleFile, 137 SmallVectorImpl<const FileEntry *> &Dependencies); 138 139 /// \brief A set of module files in which we found a result. 140 typedef llvm::SmallPtrSet<const FileEntry *, 4> HitSet; 141 142 /// \brief Look for all of the module files with information about the given 143 /// identifier, e.g., a global function, variable, or type with that name. 144 /// 145 /// \param Name The identifier to look for. 146 /// 147 /// \param Hits Will be populated with the set of module files that have 148 /// information about this name. 149 /// 150 /// \returns true if the identifier is known to the index, false otherwise. 151 bool lookupIdentifier(StringRef Name, HitSet &Hits); 152 153 /// \brief Print statistics to standard error. 154 void printStats(); 155 156 /// \brief Write a global index into the given 157 /// 158 /// \param FileMgr The file manager to use to load module files. 159 /// 160 /// \param Path The path to the directory containing module files, into 161 /// which the global index will be written. 162 static ErrorCode writeIndex(FileManager &FileMgr, StringRef Path); 163 }; 164 165 } 166 167 #endif 168