LCOV - code coverage report
Current view: top level - clang/Basic - FileManager.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 1 1 100.0 %
Date: 2016-01-31 12:01:00 Functions: 1 1 100.0 %

          Line data    Source code
       1             : //===--- FileManager.h - File System Probing and Caching --------*- 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             : /// \file
      11             : /// \brief Defines the clang::FileManager interface and associated types.
      12             : ///
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_CLANG_BASIC_FILEMANAGER_H
      16             : #define LLVM_CLANG_BASIC_FILEMANAGER_H
      17             : 
      18             : #include "clang/Basic/FileSystemOptions.h"
      19             : #include "clang/Basic/LLVM.h"
      20             : #include "clang/Basic/VirtualFileSystem.h"
      21             : #include "llvm/ADT/DenseMap.h"
      22             : #include "llvm/ADT/IntrusiveRefCntPtr.h"
      23             : #include "llvm/ADT/SmallVector.h"
      24             : #include "llvm/ADT/StringMap.h"
      25             : #include "llvm/ADT/StringRef.h"
      26             : #include "llvm/Support/Allocator.h"
      27             : #include <memory>
      28             : #include <map>
      29             : 
      30             : namespace llvm {
      31             : class MemoryBuffer;
      32             : }
      33             : 
      34             : namespace clang {
      35             : class FileManager;
      36             : class FileSystemStatCache;
      37             : 
      38             : /// \brief Cached information about one directory (either on disk or in
      39             : /// the virtual file system).
      40             : class DirectoryEntry {
      41             :   const char *Name;   // Name of the directory.
      42             :   friend class FileManager;
      43             : public:
      44             :   DirectoryEntry() : Name(nullptr) {}
      45             :   const char *getName() const { return Name; }
      46             : };
      47             : 
      48             : /// \brief Cached information about one file (either on disk
      49             : /// or in the virtual file system).
      50             : ///
      51             : /// If the 'File' member is valid, then this FileEntry has an open file
      52             : /// descriptor for the file.
      53             : class FileEntry {
      54             :   const char *Name;           // Name of the file.
      55             :   off_t Size;                 // File size in bytes.
      56             :   time_t ModTime;             // Modification time of file.
      57             :   const DirectoryEntry *Dir;  // Directory file lives in.
      58             :   unsigned UID;               // A unique (small) ID for the file.
      59             :   llvm::sys::fs::UniqueID UniqueID;
      60             :   bool IsNamedPipe;
      61             :   bool InPCH;
      62             :   bool IsValid;               // Is this \c FileEntry initialized and valid?
      63             : 
      64             :   /// \brief The open file, if it is owned by the \p FileEntry.
      65             :   mutable std::unique_ptr<vfs::File> File;
      66             :   friend class FileManager;
      67             : 
      68             :   void operator=(const FileEntry &) = delete;
      69             : 
      70             : public:
      71             :   FileEntry()
      72             :       : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
      73             :   {}
      74             : 
      75             :   // FIXME: this is here to allow putting FileEntry in std::map.  Once we have
      76             :   // emplace, we shouldn't need a copy constructor anymore.
      77             :   /// Intentionally does not copy fields that are not set in an uninitialized
      78             :   /// \c FileEntry.
      79             :   FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
      80             :       IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
      81             :     assert(!isValid() && "Cannot copy an initialized FileEntry");
      82             :   }
      83             : 
      84          11 :   const char *getName() const { return Name; }
      85             :   bool isValid() const { return IsValid; }
      86             :   off_t getSize() const { return Size; }
      87             :   unsigned getUID() const { return UID; }
      88             :   const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
      89             :   bool isInPCH() const { return InPCH; }
      90             :   time_t getModificationTime() const { return ModTime; }
      91             : 
      92             :   /// \brief Return the directory the file lives in.
      93             :   const DirectoryEntry *getDir() const { return Dir; }
      94             : 
      95             :   bool operator<(const FileEntry &RHS) const { return UniqueID < RHS.UniqueID; }
      96             : 
      97             :   /// \brief Check whether the file is a named pipe (and thus can't be opened by
      98             :   /// the native FileManager methods).
      99             :   bool isNamedPipe() const { return IsNamedPipe; }
     100             : 
     101             :   void closeFile() const {
     102             :     File.reset(); // rely on destructor to close File
     103             :   }
     104             : };
     105             : 
     106             : struct FileData;
     107             : 
     108             : /// \brief Implements support for file system lookup, file system caching,
     109             : /// and directory search management.
     110             : ///
     111             : /// This also handles more advanced properties, such as uniquing files based
     112             : /// on "inode", so that a file with two names (e.g. symlinked) will be treated
     113             : /// as a single file.
     114             : ///
     115             : class FileManager : public RefCountedBase<FileManager> {
     116             :   IntrusiveRefCntPtr<vfs::FileSystem> FS;
     117             :   FileSystemOptions FileSystemOpts;
     118             : 
     119             :   /// \brief Cache for existing real directories.
     120             :   std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
     121             : 
     122             :   /// \brief Cache for existing real files.
     123             :   std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
     124             : 
     125             :   /// \brief The virtual directories that we have allocated.
     126             :   ///
     127             :   /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
     128             :   /// directories (foo/ and foo/bar/) here.
     129             :   SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries;
     130             :   /// \brief The virtual files that we have allocated.
     131             :   SmallVector<FileEntry*, 4> VirtualFileEntries;
     132             : 
     133             :   /// \brief A cache that maps paths to directory entries (either real or
     134             :   /// virtual) we have looked up
     135             :   ///
     136             :   /// The actual Entries for real directories/files are
     137             :   /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
     138             :   /// for virtual directories/files are owned by
     139             :   /// VirtualDirectoryEntries/VirtualFileEntries above.
     140             :   ///
     141             :   llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
     142             : 
     143             :   /// \brief A cache that maps paths to file entries (either real or
     144             :   /// virtual) we have looked up.
     145             :   ///
     146             :   /// \see SeenDirEntries
     147             :   llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
     148             : 
     149             :   /// \brief The canonical names of directories.
     150             :   llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
     151             : 
     152             :   /// \brief Storage for canonical names that we have computed.
     153             :   llvm::BumpPtrAllocator CanonicalNameStorage;
     154             : 
     155             :   /// \brief Each FileEntry we create is assigned a unique ID #.
     156             :   ///
     157             :   unsigned NextFileUID;
     158             : 
     159             :   // Statistics.
     160             :   unsigned NumDirLookups, NumFileLookups;
     161             :   unsigned NumDirCacheMisses, NumFileCacheMisses;
     162             : 
     163             :   // Caching.
     164             :   std::unique_ptr<FileSystemStatCache> StatCache;
     165             : 
     166             :   bool getStatValue(const char *Path, FileData &Data, bool isFile,
     167             :                     std::unique_ptr<vfs::File> *F);
     168             : 
     169             :   /// Add all ancestors of the given path (pointing to either a file
     170             :   /// or a directory) as virtual directories.
     171             :   void addAncestorsAsVirtualDirs(StringRef Path);
     172             : 
     173             : public:
     174             :   FileManager(const FileSystemOptions &FileSystemOpts,
     175             :               IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
     176             :   ~FileManager();
     177             : 
     178             :   /// \brief Installs the provided FileSystemStatCache object within
     179             :   /// the FileManager.
     180             :   ///
     181             :   /// Ownership of this object is transferred to the FileManager.
     182             :   ///
     183             :   /// \param statCache the new stat cache to install. Ownership of this
     184             :   /// object is transferred to the FileManager.
     185             :   ///
     186             :   /// \param AtBeginning whether this new stat cache must be installed at the
     187             :   /// beginning of the chain of stat caches. Otherwise, it will be added to
     188             :   /// the end of the chain.
     189             :   void addStatCache(std::unique_ptr<FileSystemStatCache> statCache,
     190             :                     bool AtBeginning = false);
     191             : 
     192             :   /// \brief Removes the specified FileSystemStatCache object from the manager.
     193             :   void removeStatCache(FileSystemStatCache *statCache);
     194             : 
     195             :   /// \brief Removes all FileSystemStatCache objects from the manager.
     196             :   void clearStatCaches();
     197             : 
     198             :   /// \brief Lookup, cache, and verify the specified directory (real or
     199             :   /// virtual).
     200             :   ///
     201             :   /// This returns NULL if the directory doesn't exist.
     202             :   ///
     203             :   /// \param CacheFailure If true and the file does not exist, we'll cache
     204             :   /// the failure to find this file.
     205             :   const DirectoryEntry *getDirectory(StringRef DirName,
     206             :                                      bool CacheFailure = true);
     207             : 
     208             :   /// \brief Lookup, cache, and verify the specified file (real or
     209             :   /// virtual).
     210             :   ///
     211             :   /// This returns NULL if the file doesn't exist.
     212             :   ///
     213             :   /// \param OpenFile if true and the file exists, it will be opened.
     214             :   ///
     215             :   /// \param CacheFailure If true and the file does not exist, we'll cache
     216             :   /// the failure to find this file.
     217             :   const FileEntry *getFile(StringRef Filename, bool OpenFile = false,
     218             :                            bool CacheFailure = true);
     219             : 
     220             :   /// \brief Returns the current file system options
     221             :   const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; }
     222             : 
     223             :   IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
     224             :     return FS;
     225             :   }
     226             : 
     227             :   /// \brief Retrieve a file entry for a "virtual" file that acts as
     228             :   /// if there were a file with the given name on disk.
     229             :   ///
     230             :   /// The file itself is not accessed.
     231             :   const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
     232             :                                   time_t ModificationTime);
     233             : 
     234             :   /// \brief Open the specified file as a MemoryBuffer, returning a new
     235             :   /// MemoryBuffer if successful, otherwise returning null.
     236             :   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
     237             :   getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
     238             :                    bool ShouldCloseOpenFile = true);
     239             :   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
     240             :   getBufferForFile(StringRef Filename);
     241             : 
     242             :   /// \brief Get the 'stat' information for the given \p Path.
     243             :   ///
     244             :   /// If the path is relative, it will be resolved against the WorkingDir of the
     245             :   /// FileManager's FileSystemOptions.
     246             :   ///
     247             :   /// \returns false on success, true on error.
     248             :   bool getNoncachedStatValue(StringRef Path,
     249             :                              vfs::Status &Result);
     250             : 
     251             :   /// \brief Remove the real file \p Entry from the cache.
     252             :   void invalidateCache(const FileEntry *Entry);
     253             : 
     254             :   /// \brief If path is not absolute and FileSystemOptions set the working
     255             :   /// directory, the path is modified to be relative to the given
     256             :   /// working directory.
     257             :   void FixupRelativePath(SmallVectorImpl<char> &path) const;
     258             : 
     259             :   /// \brief Produce an array mapping from the unique IDs assigned to each
     260             :   /// file to the corresponding FileEntry pointer.
     261             :   void GetUniqueIDMapping(
     262             :                     SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
     263             : 
     264             :   /// \brief Modifies the size and modification time of a previously created
     265             :   /// FileEntry. Use with caution.
     266             :   static void modifyFileEntry(FileEntry *File, off_t Size,
     267             :                               time_t ModificationTime);
     268             : 
     269             :   /// \brief Remove any './' components from a path.
     270             :   static bool removeDotPaths(SmallVectorImpl<char> &Path);
     271             : 
     272             :   /// \brief Retrieve the canonical name for a given directory.
     273             :   ///
     274             :   /// This is a very expensive operation, despite its results being cached,
     275             :   /// and should only be used when the physical layout of the file system is
     276             :   /// required, which is (almost) never.
     277             :   StringRef getCanonicalName(const DirectoryEntry *Dir);
     278             : 
     279             :   void PrintStats() const;
     280             : };
     281             : 
     282             : }  // end namespace clang
     283             : 
     284             : #endif

Generated by: LCOV version 1.11