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