GlobalModuleIndex.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- GlobalModuleIndex.h - Global Module Index --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the GlobalModuleIndex class, which manages a global index
  15. // containing all of the identifiers known to the various modules within a given
  16. // subdirectory of the module cache. It is used to improve the performance of
  17. // queries such as "do any modules know about this identifier?"
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
  21. #define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
  22. #include "llvm/ADT/DenseMap.h"
  23. #include "llvm/ADT/SmallPtrSet.h"
  24. #include "llvm/ADT/SmallVector.h"
  25. #include "llvm/ADT/StringMap.h"
  26. #include "llvm/ADT/StringRef.h"
  27. #include "llvm/Support/Error.h"
  28. #include <memory>
  29. #include <utility>
  30. namespace llvm {
  31. class BitstreamCursor;
  32. class MemoryBuffer;
  33. }
  34. namespace clang {
  35. class FileManager;
  36. class IdentifierIterator;
  37. class PCHContainerOperations;
  38. class PCHContainerReader;
  39. namespace serialization {
  40. class ModuleFile;
  41. }
  42. /// A global index for a set of module files, providing information about
  43. /// the identifiers within those module files.
  44. ///
  45. /// The global index is an aid for name lookup into modules, offering a central
  46. /// place where one can look for identifiers determine which
  47. /// module files contain any information about that identifier. This
  48. /// allows the client to restrict the search to only those module files known
  49. /// to have a information about that identifier, improving performance. Moreover,
  50. /// the global module index may know about module files that have not been
  51. /// imported, and can be queried to determine which modules the current
  52. /// translation could or should load to fix a problem.
  53. class GlobalModuleIndex {
  54. using ModuleFile = serialization::ModuleFile;
  55. /// Buffer containing the index file, which is lazily accessed so long
  56. /// as the global module index is live.
  57. std::unique_ptr<llvm::MemoryBuffer> Buffer;
  58. /// The hash table.
  59. ///
  60. /// This pointer actually points to a IdentifierIndexTable object,
  61. /// but that type is only accessible within the implementation of
  62. /// GlobalModuleIndex.
  63. void *IdentifierIndex;
  64. /// Information about a given module file.
  65. struct ModuleInfo {
  66. ModuleInfo() : File(), Size(), ModTime() { }
  67. /// The module file, once it has been resolved.
  68. ModuleFile *File;
  69. /// The module file name.
  70. std::string FileName;
  71. /// Size of the module file at the time the global index was built.
  72. off_t Size;
  73. /// Modification time of the module file at the time the global
  74. /// index was built.
  75. time_t ModTime;
  76. /// The module IDs on which this module directly depends.
  77. /// FIXME: We don't really need a vector here.
  78. llvm::SmallVector<unsigned, 4> Dependencies;
  79. };
  80. /// A mapping from module IDs to information about each module.
  81. ///
  82. /// This vector may have gaps, if module files have been removed or have
  83. /// been updated since the index was built. A gap is indicated by an empty
  84. /// file name.
  85. llvm::SmallVector<ModuleInfo, 16> Modules;
  86. /// Lazily-populated mapping from module files to their
  87. /// corresponding index into the \c Modules vector.
  88. llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
  89. /// The set of modules that have not yet been resolved.
  90. ///
  91. /// The string is just the name of the module itself, which maps to the
  92. /// module ID.
  93. llvm::StringMap<unsigned> UnresolvedModules;
  94. /// The number of identifier lookups we performed.
  95. unsigned NumIdentifierLookups;
  96. /// The number of identifier lookup hits, where we recognize the
  97. /// identifier.
  98. unsigned NumIdentifierLookupHits;
  99. /// Internal constructor. Use \c readIndex() to read an index.
  100. explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
  101. llvm::BitstreamCursor Cursor);
  102. GlobalModuleIndex(const GlobalModuleIndex &) = delete;
  103. GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete;
  104. public:
  105. ~GlobalModuleIndex();
  106. /// Read a global index file for the given directory.
  107. ///
  108. /// \param Path The path to the specific module cache where the module files
  109. /// for the intended configuration reside.
  110. ///
  111. /// \returns A pair containing the global module index (if it exists) and
  112. /// the error.
  113. static std::pair<GlobalModuleIndex *, llvm::Error>
  114. readIndex(llvm::StringRef Path);
  115. /// Returns an iterator for identifiers stored in the index table.
  116. ///
  117. /// The caller accepts ownership of the returned object.
  118. IdentifierIterator *createIdentifierIterator() const;
  119. /// Retrieve the set of modules that have up-to-date indexes.
  120. ///
  121. /// \param ModuleFiles Will be populated with the set of module files that
  122. /// have been indexed.
  123. void getKnownModules(llvm::SmallVectorImpl<ModuleFile *> &ModuleFiles);
  124. /// Retrieve the set of module files on which the given module file
  125. /// directly depends.
  126. void getModuleDependencies(ModuleFile *File,
  127. llvm::SmallVectorImpl<ModuleFile *> &Dependencies);
  128. /// A set of module files in which we found a result.
  129. typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
  130. /// Look for all of the module files with information about the given
  131. /// identifier, e.g., a global function, variable, or type with that name.
  132. ///
  133. /// \param Name The identifier to look for.
  134. ///
  135. /// \param Hits Will be populated with the set of module files that have
  136. /// information about this name.
  137. ///
  138. /// \returns true if the identifier is known to the index, false otherwise.
  139. bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits);
  140. /// Note that the given module file has been loaded.
  141. ///
  142. /// \returns false if the global module index has information about this
  143. /// module file, and true otherwise.
  144. bool loadedModuleFile(ModuleFile *File);
  145. /// Print statistics to standard error.
  146. void printStats();
  147. /// Print debugging view to standard error.
  148. void dump();
  149. /// Write a global index into the given
  150. ///
  151. /// \param FileMgr The file manager to use to load module files.
  152. /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
  153. /// creating modules.
  154. /// \param Path The path to the directory containing module files, into
  155. /// which the global index will be written.
  156. static llvm::Error writeIndex(FileManager &FileMgr,
  157. const PCHContainerReader &PCHContainerRdr,
  158. llvm::StringRef Path);
  159. };
  160. }
  161. #endif
  162. #ifdef __GNUC__
  163. #pragma GCC diagnostic pop
  164. #endif