]> granicus.if.org Git - clang/blob - include/clang/Basic/FileManager.h
remove old compatibility APIs, use StringRef versions instead.
[clang] / include / clang / Basic / FileManager.h
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 //  This file defines the FileManager interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_FILEMANAGER_H
15 #define LLVM_CLANG_FILEMANAGER_H
16
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/OwningPtr.h"
21 #include "llvm/Support/Allocator.h"
22 #include "llvm/Config/config.h" // for mode_t
23 // FIXME: Enhance libsystem to support inode and other fields in stat.
24 #include <sys/types.h>
25 #include <sys/stat.h>
26
27 namespace llvm {
28 class MemoryBuffer;
29 namespace sys {
30 class Path;
31 }
32 }
33
34 namespace clang {
35 class FileManager;
36 class FileSystemOptions;
37
38 /// DirectoryEntry - Cached information about one directory on the disk.
39 ///
40 class DirectoryEntry {
41   const char *Name;   // Name of the directory.
42   friend class FileManager;
43 public:
44   DirectoryEntry() : Name(0) {}
45   const char *getName() const { return Name; }
46 };
47
48 /// FileEntry - Cached information about one file on the disk.
49 ///
50 class FileEntry {
51   const char *Name;           // Name of the file.
52   off_t Size;                 // File size in bytes.
53   time_t ModTime;             // Modification time of file.
54   const DirectoryEntry *Dir;  // Directory file lives in.
55   unsigned UID;               // A unique (small) ID for the file.
56   dev_t Device;               // ID for the device containing the file.
57   ino_t Inode;                // Inode number for the file.
58   mode_t FileMode;            // The file mode as returned by 'stat'.
59   friend class FileManager;
60 public:
61   FileEntry(dev_t device, ino_t inode, mode_t m)
62     : Name(0), Device(device), Inode(inode), FileMode(m) {}
63   // Add a default constructor for use with llvm::StringMap
64   FileEntry() : Name(0), Device(0), Inode(0), FileMode(0) {}
65
66   const char *getName() const { return Name; }
67   off_t getSize() const { return Size; }
68   unsigned getUID() const { return UID; }
69   ino_t getInode() const { return Inode; }
70   dev_t getDevice() const { return Device; }
71   time_t getModificationTime() const { return ModTime; }
72   mode_t getFileMode() const { return FileMode; }
73
74   /// getDir - Return the directory the file lives in.
75   ///
76   const DirectoryEntry *getDir() const { return Dir; }
77
78   bool operator<(const FileEntry& RHS) const {
79     return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
80   }
81 };
82
83 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
84 /// system calls, which is used by precompiled and pretokenized headers to
85 /// improve performance.
86 class StatSysCallCache {
87 protected:
88   llvm::OwningPtr<StatSysCallCache> NextStatCache;
89   
90 public:
91   virtual ~StatSysCallCache() {}
92   virtual int stat(const char *path, struct stat *buf) {
93     if (getNextStatCache())
94       return getNextStatCache()->stat(path, buf);
95     
96     return ::stat(path, buf);
97   }
98   
99   /// \brief Sets the next stat call cache in the chain of stat caches.
100   /// Takes ownership of the given stat cache.
101   void setNextStatCache(StatSysCallCache *Cache) {
102     NextStatCache.reset(Cache);
103   }
104   
105   /// \brief Retrieve the next stat call cache in the chain.
106   StatSysCallCache *getNextStatCache() { return NextStatCache.get(); }
107
108   /// \brief Retrieve the next stat call cache in the chain, transferring
109   /// ownership of this cache (and, transitively, all of the remaining caches)
110   /// to the caller.
111   StatSysCallCache *takeNextStatCache() { return NextStatCache.take(); }
112 };
113
114 /// \brief A stat "cache" that can be used by FileManager to keep
115 /// track of the results of stat() calls that occur throughout the
116 /// execution of the front end.
117 class MemorizeStatCalls : public StatSysCallCache {
118 public:
119   /// \brief The result of a stat() call.
120   ///
121   /// The first member is the result of calling stat(). If stat()
122   /// found something, the second member is a copy of the stat
123   /// structure.
124   typedef std::pair<int, struct stat> StatResult;
125
126   /// \brief The set of stat() calls that have been
127   llvm::StringMap<StatResult, llvm::BumpPtrAllocator> StatCalls;
128
129   typedef llvm::StringMap<StatResult, llvm::BumpPtrAllocator>::const_iterator
130     iterator;
131
132   iterator begin() const { return StatCalls.begin(); }
133   iterator end() const { return StatCalls.end(); }
134
135   virtual int stat(const char *path, struct stat *buf);
136 };
137
138 /// FileManager - Implements support for file system lookup, file system
139 /// caching, and directory search management.  This also handles more advanced
140 /// properties, such as uniquing files based on "inode", so that a file with two
141 /// names (e.g. symlinked) will be treated as a single file.
142 ///
143 class FileManager {
144
145   class UniqueDirContainer;
146   class UniqueFileContainer;
147
148   /// UniqueDirs/UniqueFiles - Cache for existing directories/files.
149   ///
150   UniqueDirContainer &UniqueDirs;
151   UniqueFileContainer &UniqueFiles;
152
153   /// DirEntries/FileEntries - This is a cache of directory/file entries we have
154   /// looked up.  The actual Entry is owned by UniqueFiles/UniqueDirs above.
155   ///
156   llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> DirEntries;
157   llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> FileEntries;
158
159   /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
160   ///
161   unsigned NextFileUID;
162
163   /// \brief The virtual files that we have allocated.
164   llvm::SmallVector<FileEntry *, 4> VirtualFileEntries;
165
166   // Statistics.
167   unsigned NumDirLookups, NumFileLookups;
168   unsigned NumDirCacheMisses, NumFileCacheMisses;
169
170   // Caching.
171   llvm::OwningPtr<StatSysCallCache> StatCache;
172
173   int stat_cached(const char* path, struct stat* buf,
174                   const FileSystemOptions &FileSystemOpts);
175
176 public:
177   FileManager();
178   ~FileManager();
179
180   /// \brief Installs the provided StatSysCallCache object within
181   /// the FileManager. 
182   ///
183   /// Ownership of this object is transferred to the FileManager.
184   ///
185   /// \param statCache the new stat cache to install. Ownership of this
186   /// object is transferred to the FileManager.
187   ///
188   /// \param AtBeginning whether this new stat cache must be installed at the
189   /// beginning of the chain of stat caches. Otherwise, it will be added to
190   /// the end of the chain.
191   void addStatCache(StatSysCallCache *statCache, bool AtBeginning = false);
192
193   /// \brief Removes the provided StatSysCallCache object from the file manager.
194   void removeStatCache(StatSysCallCache *statCache);
195   
196   /// getDirectory - Lookup, cache, and verify the specified directory.  This
197   /// returns null if the directory doesn't exist.
198   ///
199   const DirectoryEntry *getDirectory(llvm::StringRef Filename,
200                                      const FileSystemOptions &FileSystemOpts);
201
202   /// getFile - Lookup, cache, and verify the specified file.  This returns null
203   /// if the file doesn't exist.
204   ///
205   const FileEntry *getFile(llvm::StringRef Filename,
206                            const FileSystemOptions &FileSystemOpts);
207
208   /// \brief Retrieve a file entry for a "virtual" file that acts as
209   /// if there were a file with the given name on disk. The file
210   /// itself is not accessed.
211   const FileEntry *getVirtualFile(llvm::StringRef Filename, off_t Size,
212                                   time_t ModificationTime,
213                                   const FileSystemOptions &FileSystemOpts);
214
215   /// \brief Open the specified file as a MemoryBuffer, returning a new
216   /// MemoryBuffer if successful, otherwise returning null.
217   llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
218                                        const FileSystemOptions &FileSystemOpts,
219                                        std::string *ErrorStr = 0,
220                                        struct stat *FileInfo = 0) {
221     return getBufferForFile(Entry->getName(), FileSystemOpts,
222                             ErrorStr, Entry->getSize(), FileInfo);
223   }
224   llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename,
225                                        const FileSystemOptions &FileSystemOpts,
226                                        std::string *ErrorStr = 0,
227                                        int64_t FileSize = -1,
228                                        struct stat *FileInfo = 0) {
229     return getBufferForFile(Filename.begin(), Filename.end(), FileSystemOpts,
230                             ErrorStr, FileSize, FileInfo);
231   }
232   llvm::MemoryBuffer *getBufferForFile(const char *FilenameStart,
233                                        const char *FilenameEnd,
234                                        const FileSystemOptions &FileSystemOpts,
235                                        std::string *ErrorStr = 0,
236                                        int64_t FileSize = -1,
237                                        struct stat *FileInfo = 0);
238
239   /// \brief If path is not absolute and FileSystemOptions set the working
240   /// directory, the path is modified to be relative to the given
241   /// working directory.
242   static void FixupRelativePath(llvm::sys::Path &path,
243                                 const FileSystemOptions &FSOpts);
244
245   void PrintStats() const;
246 };
247
248 }  // end namespace clang
249
250 #endif