Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:06

0001 //===--- GlobalModuleIndex.h - Global Module Index --------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the GlobalModuleIndex class, which manages a global index
0010 // containing all of the identifiers known to the various modules within a given
0011 // subdirectory of the module cache. It is used to improve the performance of
0012 // queries such as "do any modules know about this identifier?"
0013 //
0014 //===----------------------------------------------------------------------===//
0015 #ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
0016 #define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
0017 
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/SmallPtrSet.h"
0020 #include "llvm/ADT/SmallVector.h"
0021 #include "llvm/ADT/StringMap.h"
0022 #include "llvm/ADT/StringRef.h"
0023 #include "llvm/Support/Error.h"
0024 #include <memory>
0025 #include <utility>
0026 
0027 namespace llvm {
0028 class BitstreamCursor;
0029 class MemoryBuffer;
0030 }
0031 
0032 namespace clang {
0033 
0034 class FileManager;
0035 class IdentifierIterator;
0036 class PCHContainerOperations;
0037 class PCHContainerReader;
0038 
0039 namespace serialization {
0040   class ModuleFile;
0041 }
0042 
0043 /// A global index for a set of module files, providing information about
0044 /// the identifiers within those module files.
0045 ///
0046 /// The global index is an aid for name lookup into modules, offering a central
0047 /// place where one can look for identifiers determine which
0048 /// module files contain any information about that identifier. This
0049 /// allows the client to restrict the search to only those module files known
0050 /// to have a information about that identifier, improving performance. Moreover,
0051 /// the global module index may know about module files that have not been
0052 /// imported, and can be queried to determine which modules the current
0053 /// translation could or should load to fix a problem.
0054 class GlobalModuleIndex {
0055   using ModuleFile = serialization::ModuleFile;
0056 
0057   /// Buffer containing the index file, which is lazily accessed so long
0058   /// as the global module index is live.
0059   std::unique_ptr<llvm::MemoryBuffer> Buffer;
0060 
0061   /// The hash table.
0062   ///
0063   /// This pointer actually points to a IdentifierIndexTable object,
0064   /// but that type is only accessible within the implementation of
0065   /// GlobalModuleIndex.
0066   void *IdentifierIndex;
0067 
0068   /// Information about a given module file.
0069   struct ModuleInfo {
0070     ModuleInfo() = default;
0071 
0072     /// The module file, once it has been resolved.
0073     ModuleFile *File = nullptr;
0074 
0075     /// The module file name.
0076     std::string FileName;
0077 
0078     /// Size of the module file at the time the global index was built.
0079     off_t Size = 0;
0080 
0081     /// Modification time of the module file at the time the global
0082     /// index was built.
0083     time_t ModTime = 0;
0084 
0085     /// The module IDs on which this module directly depends.
0086     /// FIXME: We don't really need a vector here.
0087     llvm::SmallVector<unsigned, 4> Dependencies;
0088   };
0089 
0090   /// A mapping from module IDs to information about each module.
0091   ///
0092   /// This vector may have gaps, if module files have been removed or have
0093   /// been updated since the index was built. A gap is indicated by an empty
0094   /// file name.
0095   llvm::SmallVector<ModuleInfo, 16> Modules;
0096 
0097   /// Lazily-populated mapping from module files to their
0098   /// corresponding index into the \c Modules vector.
0099   llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
0100 
0101   /// The set of modules that have not yet been resolved.
0102   ///
0103   /// The string is just the name of the module itself, which maps to the
0104   /// module ID.
0105   llvm::StringMap<unsigned> UnresolvedModules;
0106 
0107   /// The number of identifier lookups we performed.
0108   unsigned NumIdentifierLookups;
0109 
0110   /// The number of identifier lookup hits, where we recognize the
0111   /// identifier.
0112   unsigned NumIdentifierLookupHits;
0113 
0114   /// Internal constructor. Use \c readIndex() to read an index.
0115   explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
0116                              llvm::BitstreamCursor Cursor);
0117 
0118   GlobalModuleIndex(const GlobalModuleIndex &) = delete;
0119   GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete;
0120 
0121 public:
0122   ~GlobalModuleIndex();
0123 
0124   /// Read a global index file for the given directory.
0125   ///
0126   /// \param Path The path to the specific module cache where the module files
0127   /// for the intended configuration reside.
0128   ///
0129   /// \returns A pair containing the global module index (if it exists) and
0130   /// the error.
0131   static std::pair<GlobalModuleIndex *, llvm::Error>
0132   readIndex(llvm::StringRef Path);
0133 
0134   /// Returns an iterator for identifiers stored in the index table.
0135   ///
0136   /// The caller accepts ownership of the returned object.
0137   IdentifierIterator *createIdentifierIterator() const;
0138 
0139   /// Retrieve the set of module files on which the given module file
0140   /// directly depends.
0141   void getModuleDependencies(ModuleFile *File,
0142                              llvm::SmallVectorImpl<ModuleFile *> &Dependencies);
0143 
0144   /// A set of module files in which we found a result.
0145   typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
0146 
0147   /// Look for all of the module files with information about the given
0148   /// identifier, e.g., a global function, variable, or type with that name.
0149   ///
0150   /// \param Name The identifier to look for.
0151   ///
0152   /// \param Hits Will be populated with the set of module files that have
0153   /// information about this name.
0154   ///
0155   /// \returns true if the identifier is known to the index, false otherwise.
0156   bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits);
0157 
0158   /// Note that the given module file has been loaded.
0159   ///
0160   /// \returns false if the global module index has information about this
0161   /// module file, and true otherwise.
0162   bool loadedModuleFile(ModuleFile *File);
0163 
0164   /// Print statistics to standard error.
0165   void printStats();
0166 
0167   /// Print debugging view to standard error.
0168   void dump();
0169 
0170   /// Write a global index into the given
0171   ///
0172   /// \param FileMgr The file manager to use to load module files.
0173   /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
0174   /// creating modules.
0175   /// \param Path The path to the directory containing module files, into
0176   /// which the global index will be written.
0177   static llvm::Error writeIndex(FileManager &FileMgr,
0178                                 const PCHContainerReader &PCHContainerRdr,
0179                                 llvm::StringRef Path);
0180 };
0181 }
0182 
0183 #endif