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