GlobalModuleIndex.h revision 9ef9b8540a608a93efaaae1d26d94e8087c30b55
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 26namespace llvm { 27class BitstreamCursor; 28class MemoryBuffer; 29} 30 31namespace clang { 32 33class DirectoryEntry; 34class FileEntry; 35class FileManager; 36 37using llvm::SmallVector; 38using llvm::SmallVectorImpl; 39using 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. 52class 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 100public: 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