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