Home | History | Annotate | Download | only in Serialization
      1 //===--- ModuleManager.cpp - Module Manager ---------------------*- 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 ModuleManager class, which manages a set of loaded
     11 //  modules for the ASTReader.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
     16 #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
     17 
     18 #include "clang/Basic/FileManager.h"
     19 #include "clang/Serialization/Module.h"
     20 #include "llvm/ADT/DenseMap.h"
     21 #include "llvm/ADT/SmallPtrSet.h"
     22 #include "llvm/ADT/iterator.h"
     23 
     24 namespace clang {
     25 
     26 class GlobalModuleIndex;
     27 class MemoryBufferCache;
     28 class ModuleMap;
     29 class PCHContainerReader;
     30 class HeaderSearch;
     31 
     32 namespace serialization {
     33 
     34 /// \brief Manages the set of modules loaded by an AST reader.
     35 class ModuleManager {
     36   /// \brief The chain of AST files, in the order in which we started to load
     37   /// them (this order isn't really useful for anything).
     38   SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;
     39 
     40   /// \brief The chain of non-module PCH files. The first entry is the one named
     41   /// by the user, the last one is the one that doesn't depend on anything
     42   /// further.
     43   SmallVector<ModuleFile *, 2> PCHChain;
     44 
     45   // \brief The roots of the dependency DAG of AST files. This is used
     46   // to implement short-circuiting logic when running DFS over the dependencies.
     47   SmallVector<ModuleFile *, 2> Roots;
     48 
     49   /// \brief All loaded modules, indexed by name.
     50   llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
     51 
     52   /// \brief FileManager that handles translating between filenames and
     53   /// FileEntry *.
     54   FileManager &FileMgr;
     55 
     56   /// Cache of PCM files.
     57   IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
     58 
     59   /// \brief Knows how to unwrap module containers.
     60   const PCHContainerReader &PCHContainerRdr;
     61 
     62   /// \brief Preprocessor's HeaderSearchInfo containing the module map.
     63   const HeaderSearch &HeaderSearchInfo;
     64 
     65   /// \brief A lookup of in-memory (virtual file) buffers
     66   llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
     67       InMemoryBuffers;
     68 
     69   /// \brief The visitation order.
     70   SmallVector<ModuleFile *, 4> VisitOrder;
     71 
     72   /// \brief The list of module files that both we and the global module index
     73   /// know about.
     74   ///
     75   /// Either the global index or the module manager may have modules that the
     76   /// other does not know about, because the global index can be out-of-date
     77   /// (in which case the module manager could have modules it does not) and
     78   /// this particular translation unit might not have loaded all of the modules
     79   /// known to the global index.
     80   SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
     81 
     82   /// \brief The global module index, if one is attached.
     83   ///
     84   /// The global module index will actually be owned by the ASTReader; this is
     85   /// just an non-owning pointer.
     86   GlobalModuleIndex *GlobalIndex;
     87 
     88   /// \brief State used by the "visit" operation to avoid malloc traffic in
     89   /// calls to visit().
     90   struct VisitState {
     91     explicit VisitState(unsigned N)
     92       : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
     93     {
     94       Stack.reserve(N);
     95     }
     96 
     97     ~VisitState() {
     98       delete NextState;
     99     }
    100 
    101     /// \brief The stack used when marking the imports of a particular module
    102     /// as not-to-be-visited.
    103     SmallVector<ModuleFile *, 4> Stack;
    104 
    105     /// \brief The visit number of each module file, which indicates when
    106     /// this module file was last visited.
    107     SmallVector<unsigned, 4> VisitNumber;
    108 
    109     /// \brief The next visit number to use to mark visited module files.
    110     unsigned NextVisitNumber;
    111 
    112     /// \brief The next visit state.
    113     VisitState *NextState;
    114   };
    115 
    116   /// \brief The first visit() state in the chain.
    117   VisitState *FirstVisitState;
    118 
    119   VisitState *allocateVisitState();
    120   void returnVisitState(VisitState *State);
    121 
    122 public:
    123   typedef llvm::pointee_iterator<
    124       SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>
    125       ModuleIterator;
    126   typedef llvm::pointee_iterator<
    127       SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>
    128       ModuleConstIterator;
    129   typedef llvm::pointee_iterator<
    130       SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>
    131       ModuleReverseIterator;
    132   typedef std::pair<uint32_t, StringRef> ModuleOffset;
    133 
    134   explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
    135                          const PCHContainerReader &PCHContainerRdr,
    136                          const HeaderSearch &HeaderSearchInfo);
    137   ~ModuleManager();
    138 
    139   /// \brief Forward iterator to traverse all loaded modules.
    140   ModuleIterator begin() { return Chain.begin(); }
    141   /// \brief Forward iterator end-point to traverse all loaded modules
    142   ModuleIterator end() { return Chain.end(); }
    143 
    144   /// \brief Const forward iterator to traverse all loaded modules.
    145   ModuleConstIterator begin() const { return Chain.begin(); }
    146   /// \brief Const forward iterator end-point to traverse all loaded modules
    147   ModuleConstIterator end() const { return Chain.end(); }
    148 
    149   /// \brief Reverse iterator to traverse all loaded modules.
    150   ModuleReverseIterator rbegin() { return Chain.rbegin(); }
    151   /// \brief Reverse iterator end-point to traverse all loaded modules.
    152   ModuleReverseIterator rend() { return Chain.rend(); }
    153 
    154   /// \brief A range covering the PCH and preamble module files loaded.
    155   llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator>
    156   pch_modules() const {
    157     return llvm::make_range(PCHChain.begin(), PCHChain.end());
    158   }
    159 
    160   /// \brief Returns the primary module associated with the manager, that is,
    161   /// the first module loaded
    162   ModuleFile &getPrimaryModule() { return *Chain[0]; }
    163 
    164   /// \brief Returns the primary module associated with the manager, that is,
    165   /// the first module loaded.
    166   ModuleFile &getPrimaryModule() const { return *Chain[0]; }
    167 
    168   /// \brief Returns the module associated with the given index
    169   ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
    170 
    171   /// \brief Returns the module associated with the given file name.
    172   ModuleFile *lookupByFileName(StringRef FileName) const;
    173 
    174   /// \brief Returns the module associated with the given module name.
    175   ModuleFile *lookupByModuleName(StringRef ModName) const;
    176 
    177   /// \brief Returns the module associated with the given module file.
    178   ModuleFile *lookup(const FileEntry *File) const;
    179 
    180   /// \brief Returns the in-memory (virtual file) buffer with the given name
    181   std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
    182 
    183   /// \brief Number of modules loaded
    184   unsigned size() const { return Chain.size(); }
    185 
    186   /// \brief The result of attempting to add a new module.
    187   enum AddModuleResult {
    188     /// \brief The module file had already been loaded.
    189     AlreadyLoaded,
    190     /// \brief The module file was just loaded in response to this call.
    191     NewlyLoaded,
    192     /// \brief The module file is missing.
    193     Missing,
    194     /// \brief The module file is out-of-date.
    195     OutOfDate
    196   };
    197 
    198   typedef ASTFileSignature(*ASTFileSignatureReader)(StringRef);
    199 
    200   /// \brief Attempts to create a new module and add it to the list of known
    201   /// modules.
    202   ///
    203   /// \param FileName The file name of the module to be loaded.
    204   ///
    205   /// \param Type The kind of module being loaded.
    206   ///
    207   /// \param ImportLoc The location at which the module is imported.
    208   ///
    209   /// \param ImportedBy The module that is importing this module, or NULL if
    210   /// this module is imported directly by the user.
    211   ///
    212   /// \param Generation The generation in which this module was loaded.
    213   ///
    214   /// \param ExpectedSize The expected size of the module file, used for
    215   /// validation. This will be zero if unknown.
    216   ///
    217   /// \param ExpectedModTime The expected modification time of the module
    218   /// file, used for validation. This will be zero if unknown.
    219   ///
    220   /// \param ExpectedSignature The expected signature of the module file, used
    221   /// for validation. This will be zero if unknown.
    222   ///
    223   /// \param ReadSignature Reads the signature from an AST file without actually
    224   /// loading it.
    225   ///
    226   /// \param Module A pointer to the module file if the module was successfully
    227   /// loaded.
    228   ///
    229   /// \param ErrorStr Will be set to a non-empty string if any errors occurred
    230   /// while trying to load the module.
    231   ///
    232   /// \return A pointer to the module that corresponds to this file name,
    233   /// and a value indicating whether the module was loaded.
    234   AddModuleResult addModule(StringRef FileName, ModuleKind Type,
    235                             SourceLocation ImportLoc,
    236                             ModuleFile *ImportedBy, unsigned Generation,
    237                             off_t ExpectedSize, time_t ExpectedModTime,
    238                             ASTFileSignature ExpectedSignature,
    239                             ASTFileSignatureReader ReadSignature,
    240                             ModuleFile *&Module,
    241                             std::string &ErrorStr);
    242 
    243   /// \brief Remove the modules starting from First (to the end).
    244   void removeModules(ModuleIterator First,
    245                      llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
    246                      ModuleMap *modMap);
    247 
    248   /// \brief Add an in-memory buffer the list of known buffers
    249   void addInMemoryBuffer(StringRef FileName,
    250                          std::unique_ptr<llvm::MemoryBuffer> Buffer);
    251 
    252   /// \brief Set the global module index.
    253   void setGlobalIndex(GlobalModuleIndex *Index);
    254 
    255   /// \brief Notification from the AST reader that the given module file
    256   /// has been "accepted", and will not (can not) be unloaded.
    257   void moduleFileAccepted(ModuleFile *MF);
    258 
    259   /// \brief Visit each of the modules.
    260   ///
    261   /// This routine visits each of the modules, starting with the
    262   /// "root" modules that no other loaded modules depend on, and
    263   /// proceeding to the leaf modules, visiting each module only once
    264   /// during the traversal.
    265   ///
    266   /// This traversal is intended to support various "lookup"
    267   /// operations that can find data in any of the loaded modules.
    268   ///
    269   /// \param Visitor A visitor function that will be invoked with each
    270   /// module. The return value must be convertible to bool; when false, the
    271   /// visitation continues to modules that the current module depends on. When
    272   /// true, the visitation skips any modules that the current module depends on.
    273   ///
    274   /// \param ModuleFilesHit If non-NULL, contains the set of module files
    275   /// that we know we need to visit because the global module index told us to.
    276   /// Any module that is known to both the global module index and the module
    277   /// manager that is *not* in this set can be skipped.
    278   void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
    279              llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
    280 
    281   /// \brief Attempt to resolve the given module file name to a file entry.
    282   ///
    283   /// \param FileName The name of the module file.
    284   ///
    285   /// \param ExpectedSize The size that the module file is expected to have.
    286   /// If the actual size differs, the resolver should return \c true.
    287   ///
    288   /// \param ExpectedModTime The modification time that the module file is
    289   /// expected to have. If the actual modification time differs, the resolver
    290   /// should return \c true.
    291   ///
    292   /// \param File Will be set to the file if there is one, or null
    293   /// otherwise.
    294   ///
    295   /// \returns True if a file exists but does not meet the size/
    296   /// modification time criteria, false if the file is either available and
    297   /// suitable, or is missing.
    298   bool lookupModuleFile(StringRef FileName,
    299                         off_t ExpectedSize,
    300                         time_t ExpectedModTime,
    301                         const FileEntry *&File);
    302 
    303   /// \brief View the graphviz representation of the module graph.
    304   void viewGraph();
    305 
    306   MemoryBufferCache &getPCMCache() const { return *PCMCache; }
    307 };
    308 
    309 } } // end namespace clang::serialization
    310 
    311 #endif
    312