FileManager.h revision f9f7766846a205bc900b578f944567e679b221aa
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the FileManager interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_FILEMANAGER_H 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_FILEMANAGER_H 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1739b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner#include "clang/Basic/FileSystemOptions.h" 18057e567f1b375190779e5341f42861896cdee442Douglas Gregor#include "llvm/ADT/SmallVector.h" 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h" 20458fb10ef5ba2d7b375c6c64095c1458af0a5be3Benjamin Kramer#include "llvm/ADT/StringRef.h" 2196438f319bb07d9a40564b5e01333f82c0c8a61eTed Kremenek#include "llvm/ADT/OwningPtr.h" 22f3eb9219cf4b4e80c377d37aed72d5d6d840b7bcTed Kremenek#include "llvm/Support/Allocator.h" 23ea684e699ea84e61711e279f5fa7a1b9f3d46bc2Cedric Venet#include "llvm/Config/config.h" // for mode_t 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// FIXME: Enhance libsystem to support inode and other fields in stat. 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <sys/types.h> 2610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner 2710e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerstruct stat; 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 29389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidisnamespace llvm { 30389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidisclass MemoryBuffer; 3110e286aa8d39fb51a21412850265d9dae74613eeChris Lattnernamespace sys { class Path; } 32389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis} 33389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager; 3610e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerclass FileSystemStatCache; 3710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DirectoryEntry - Cached information about one directory on the disk. 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass DirectoryEntry { 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *Name; // Name of the directory. 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer friend class FileManager; 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DirectoryEntry() : Name(0) {} 451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const char *getName() const { return Name; } 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 48f9f7766846a205bc900b578f944567e679b221aaChris Lattner/// FileEntry - Cached information about one file on the disk. If the 'FD' 49f9f7766846a205bc900b578f944567e679b221aaChris Lattner/// member is valid, then this FileEntry has an open file descriptor for the 50f9f7766846a205bc900b578f944567e679b221aaChris Lattner/// file. 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry { 53f17765d202d1ec34ada7ff3f18d18731588143c2Chris Lattner const char *Name; // Name of the file. 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer off_t Size; // File size in bytes. 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer time_t ModTime; // Modification time of file. 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const DirectoryEntry *Dir; // Directory file lives in. 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned UID; // A unique (small) ID for the file. 58bca6d125c77c93c7fa41798c15348175a6bb1267Ted Kremenek dev_t Device; // ID for the device containing the file. 59bca6d125c77c93c7fa41798c15348175a6bb1267Ted Kremenek ino_t Inode; // Inode number for the file. 6096438f319bb07d9a40564b5e01333f82c0c8a61eTed Kremenek mode_t FileMode; // The file mode as returned by 'stat'. 61f9f7766846a205bc900b578f944567e679b221aaChris Lattner 62f9f7766846a205bc900b578f944567e679b221aaChris Lattner /// FD - The file descriptor for the file entry if it is opened and owned 63f9f7766846a205bc900b578f944567e679b221aaChris Lattner /// by the FileEntry. If not, this is set to -1. 64f9f7766846a205bc900b578f944567e679b221aaChris Lattner int FD; 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer friend class FileManager; 66f9f7766846a205bc900b578f944567e679b221aaChris Lattner 67f9f7766846a205bc900b578f944567e679b221aaChris Lattner void operator=(const FileEntry&); // DO NOT IMPLEMENT. 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 6996438f319bb07d9a40564b5e01333f82c0c8a61eTed Kremenek FileEntry(dev_t device, ino_t inode, mode_t m) 70f9f7766846a205bc900b578f944567e679b221aaChris Lattner : Name(0), Device(device), Inode(inode), FileMode(m), FD(-1) {} 716bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek // Add a default constructor for use with llvm::StringMap 72f9f7766846a205bc900b578f944567e679b221aaChris Lattner FileEntry() : Name(0), Device(0), Inode(0), FileMode(0), FD(-1) {} 73f9f7766846a205bc900b578f944567e679b221aaChris Lattner 74f9f7766846a205bc900b578f944567e679b221aaChris Lattner FileEntry(const FileEntry &FE) { 75f9f7766846a205bc900b578f944567e679b221aaChris Lattner memcpy(this, &FE, sizeof(FE)); 76f9f7766846a205bc900b578f944567e679b221aaChris Lattner assert(FD == -1 && "Cannot copy an file-owning FileEntry"); 77f9f7766846a205bc900b578f944567e679b221aaChris Lattner } 78f9f7766846a205bc900b578f944567e679b221aaChris Lattner 79f9f7766846a205bc900b578f944567e679b221aaChris Lattner ~FileEntry(); 801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *getName() const { return Name; } 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer off_t getSize() const { return Size; } 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned getUID() const { return UID; } 84bca6d125c77c93c7fa41798c15348175a6bb1267Ted Kremenek ino_t getInode() const { return Inode; } 857f1752797d4a4344b539ad9452471871c0eec64bTed Kremenek dev_t getDevice() const { return Device; } 865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer time_t getModificationTime() const { return ModTime; } 8796438f319bb07d9a40564b5e01333f82c0c8a61eTed Kremenek mode_t getFileMode() const { return FileMode; } 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getDir - Return the directory the file lives in. 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const DirectoryEntry *getDir() const { return Dir; } 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 93f9f7766846a205bc900b578f944567e679b221aaChris Lattner bool operator<(const FileEntry &RHS) const { 94bca6d125c77c93c7fa41798c15348175a6bb1267Ted Kremenek return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode); 95bca6d125c77c93c7fa41798c15348175a6bb1267Ted Kremenek } 965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileManager - Implements support for file system lookup, file system 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// caching, and directory search management. This also handles more advanced 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// properties, such as uniquing files based on "inode", so that a file with two 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// names (e.g. symlinked) will be treated as a single file. 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager { 10439b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner FileSystemOptions FileSystemOpts; 1057ad97ffa631af6ad678c79b38341ac995f347ce9Chris Lattner 1066bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek class UniqueDirContainer; 1076bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek class UniqueFileContainer; 1086bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek 1096bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek /// UniqueDirs/UniqueFiles - Cache for existing directories/files. 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1116bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek UniqueDirContainer &UniqueDirs; 1126bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek UniqueFileContainer &UniqueFiles; 1136bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// DirEntries/FileEntries - This is a cache of directory/file entries we have 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above. 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 117f3eb9219cf4b4e80c377d37aed72d5d6d840b7bcTed Kremenek llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> DirEntries; 118f3eb9219cf4b4e80c377d37aed72d5d6d840b7bcTed Kremenek llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> FileEntries; 1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// NextFileUID - Each FileEntry we create is assigned a unique ID #. 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NextFileUID; 1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 124057e567f1b375190779e5341f42861896cdee442Douglas Gregor /// \brief The virtual files that we have allocated. 12510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner llvm::SmallVector<FileEntry*, 4> VirtualFileEntries; 126057e567f1b375190779e5341f42861896cdee442Douglas Gregor 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Statistics. 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumDirLookups, NumFileLookups; 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumDirCacheMisses, NumFileCacheMisses; 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 131fc7052d4a241ee6fc70afea7c1c9560147f0a49cTed Kremenek // Caching. 13210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner llvm::OwningPtr<FileSystemStatCache> StatCache; 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 134f9f7766846a205bc900b578f944567e679b221aaChris Lattner bool getStatValue(const char *Path, struct stat &StatBuf, bool isForDir); 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 1367ad97ffa631af6ad678c79b38341ac995f347ce9Chris Lattner FileManager(const FileSystemOptions &FileSystemOpts); 1376bb816a3b895e9c983d89b22d510dca58a0eb75eTed Kremenek ~FileManager(); 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 13910e286aa8d39fb51a21412850265d9dae74613eeChris Lattner /// \brief Installs the provided FileSystemStatCache object within 14052e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// the FileManager. 14152e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// 14252e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// Ownership of this object is transferred to the FileManager. 14352e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// 14452e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// \param statCache the new stat cache to install. Ownership of this 14552e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// object is transferred to the FileManager. 14652e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// 14752e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// \param AtBeginning whether this new stat cache must be installed at the 14852e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// beginning of the chain of stat caches. Otherwise, it will be added to 14952e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor /// the end of the chain. 15010e286aa8d39fb51a21412850265d9dae74613eeChris Lattner void addStatCache(FileSystemStatCache *statCache, bool AtBeginning = false); 15152e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor 15210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner /// \brief Removes the specified FileSystemStatCache object from the manager. 15310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner void removeStatCache(FileSystemStatCache *statCache); 15452e7108f51a4a9f4d6e84f33fb594d06e1d79560Douglas Gregor 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getDirectory - Lookup, cache, and verify the specified directory. This 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// returns null if the directory doesn't exist. 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// 15839b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const DirectoryEntry *getDirectory(llvm::StringRef Filename); 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFile - Lookup, cache, and verify the specified file. This returns null 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// if the file doesn't exist. 1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// 16339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const FileEntry *getFile(llvm::StringRef Filename); 1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 165057e567f1b375190779e5341f42861896cdee442Douglas Gregor /// \brief Retrieve a file entry for a "virtual" file that acts as 166057e567f1b375190779e5341f42861896cdee442Douglas Gregor /// if there were a file with the given name on disk. The file 167057e567f1b375190779e5341f42861896cdee442Douglas Gregor /// itself is not accessed. 168ec1b1cc006cef19e0a95d0ea6fbfd37d0d615066Benjamin Kramer const FileEntry *getVirtualFile(llvm::StringRef Filename, off_t Size, 16939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner time_t ModificationTime); 170389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 171389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /// \brief Open the specified file as a MemoryBuffer, returning a new 172389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /// MemoryBuffer if successful, otherwise returning null. 173389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry, 17475dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner std::string *ErrorStr = 0); 175389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename, 17675dfb65c38d51772df9a00ce2d2feeefd55667adChris Lattner std::string *ErrorStr = 0); 177389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis 178389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /// \brief If path is not absolute and FileSystemOptions set the working 179389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /// directory, the path is modified to be relative to the given 180389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis /// working directory. 181389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis static void FixupRelativePath(llvm::sys::Path &path, 182389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileSystemOptions &FSOpts); 18367452f51aec1ad8a3e4c6622c0c57c5d8dc1b6a3Chris Lattner 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end namespace clang 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 190