[cfe-commits] r120056 - in /cfe/trunk: include/clang/Basic/FileManager.h lib/Basic/FileManager.cpp

Chris Lattner sabre at nondot.org
Tue Nov 23 12:50:22 PST 2010


Author: lattner
Date: Tue Nov 23 14:50:22 2010
New Revision: 120056

URL: http://llvm.org/viewvc/llvm-project?rev=120056&view=rev
Log:
pull "is directory" handling into FileManager::getStatValue
which simplifies clients and is important for future directions.
Add a FD member to FileEntry which isn't used but will be shortly.

Modified:
    cfe/trunk/include/clang/Basic/FileManager.h
    cfe/trunk/lib/Basic/FileManager.cpp

Modified: cfe/trunk/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=120056&r1=120055&r2=120056&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/FileManager.h (original)
+++ cfe/trunk/include/clang/Basic/FileManager.h Tue Nov 23 14:50:22 2010
@@ -45,7 +45,9 @@
   const char *getName() const { return Name; }
 };
 
-/// FileEntry - Cached information about one file on the disk.
+/// FileEntry - Cached information about one file on the disk.  If the 'FD'
+/// member is valid, then this FileEntry has an open file descriptor for the
+/// file.
 ///
 class FileEntry {
   const char *Name;           // Name of the file.
@@ -56,12 +58,25 @@
   dev_t Device;               // ID for the device containing the file.
   ino_t Inode;                // Inode number for the file.
   mode_t FileMode;            // The file mode as returned by 'stat'.
+  
+  /// FD - The file descriptor for the file entry if it is opened and owned
+  /// by the FileEntry.  If not, this is set to -1.
+  int FD;
   friend class FileManager;
+  
+  void operator=(const FileEntry&); // DO NOT IMPLEMENT.
 public:
   FileEntry(dev_t device, ino_t inode, mode_t m)
-    : Name(0), Device(device), Inode(inode), FileMode(m) {}
+    : Name(0), Device(device), Inode(inode), FileMode(m), FD(-1) {}
   // Add a default constructor for use with llvm::StringMap
-  FileEntry() : Name(0), Device(0), Inode(0), FileMode(0) {}
+  FileEntry() : Name(0), Device(0), Inode(0), FileMode(0), FD(-1) {}
+
+  FileEntry(const FileEntry &FE) {
+    memcpy(this, &FE, sizeof(FE));
+    assert(FD == -1 && "Cannot copy an file-owning FileEntry");
+  }
+
+  ~FileEntry();
 
   const char *getName() const { return Name; }
   off_t getSize() const { return Size; }
@@ -75,7 +90,7 @@
   ///
   const DirectoryEntry *getDir() const { return Dir; }
 
-  bool operator<(const FileEntry& RHS) const {
+  bool operator<(const FileEntry &RHS) const {
     return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
   }
 };
@@ -116,7 +131,7 @@
   // Caching.
   llvm::OwningPtr<FileSystemStatCache> StatCache;
 
-  bool getStatValue(const char *Path, struct stat &StatBuf);
+  bool getStatValue(const char *Path, struct stat &StatBuf, bool isForDir);
 public:
   FileManager(const FileSystemOptions &FileSystemOpts);
   ~FileManager();

Modified: cfe/trunk/lib/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=120056&r1=120055&r2=120056&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/FileManager.cpp (original)
+++ cfe/trunk/lib/Basic/FileManager.cpp Tue Nov 23 14:50:22 2010
@@ -41,6 +41,17 @@
 /// represent a dir name that doesn't exist on the disk.
 #define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
 
+/// NON_EXISTENT_FILE - A special value distinct from null that is used to
+/// represent a filename that doesn't exist on the disk.
+#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
+
+
+FileEntry::~FileEntry() {
+  // If this FileEntry owns an open file descriptor that never got used, close
+  // it.
+  if (FD != -1) ::close(FD);
+}
+
 //===----------------------------------------------------------------------===//
 // Windows.
 //===----------------------------------------------------------------------===//
@@ -102,7 +113,6 @@
 
 class FileManager::UniqueDirContainer {
   /// UniqueDirs - Cache from ID's to existing directories/files.
-  ///
   std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
 
 public:
@@ -115,7 +125,6 @@
 
 class FileManager::UniqueFileContainer {
   /// UniqueFiles - Cache from ID's to existing directories/files.
-  ///
   std::set<FileEntry> UniqueFiles;
 
 public:
@@ -182,10 +191,9 @@
   FileSystemStatCache *PrevCache = StatCache.get();
   while (PrevCache && PrevCache->getNextStatCache() != statCache)
     PrevCache = PrevCache->getNextStatCache();
-  if (PrevCache)
-    PrevCache->setNextStatCache(statCache->getNextStatCache());
-  else
-    assert(false && "Stat cache not found for removal");
+  
+  assert(PrevCache && "Stat cache not found for removal");
+  PrevCache->setNextStatCache(statCache->getNextStatCache());
 }
 
 /// \brief Retrieve the directory that the given file name resides in.
@@ -240,8 +248,7 @@
 
   // Check to see if the directory exists.
   struct stat StatBuf;
-  if (getStatValue(InterndDirName, StatBuf) ||    // Error stat'ing.
-      !S_ISDIR(StatBuf.st_mode))                  // Not a directory?
+  if (getStatValue(InterndDirName, StatBuf, true))
     return 0;
 
   // It exists.  See if we have already opened a directory with the same inode.
@@ -258,10 +265,6 @@
   return &UDE;
 }
 
-/// NON_EXISTENT_FILE - A special value distinct from null that is used to
-/// represent a filename that doesn't exist on the disk.
-#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
-
 /// getFile - Lookup, cache, and verify the specified file.  This returns null
 /// if the file doesn't exist.
 ///
@@ -302,12 +305,8 @@
 
   // Nope, there isn't.  Check to see if the file exists.
   struct stat StatBuf;
-  if (getStatValue(InterndFileName, StatBuf) ||    // Error stat'ing.
-      S_ISDIR(StatBuf.st_mode)) {                  // A directory?
-    // If this file doesn't exist, we leave NON_EXISTENT_FILE in FileEntries for
-    // this path so subsequent queries get the negative result.
+  if (getStatValue(InterndFileName, StatBuf, false))
     return 0;
-  }
 
   // It exists.  See if we have already opened a file with the same inode.
   // This occurs when one dir is symlinked to another, for example.
@@ -355,7 +354,11 @@
   VirtualFileEntries.push_back(UFE);
   NamedFileEnt.setValue(UFE);
 
-  UFE->Name    = NamedFileEnt.getKeyData();
+  // Get the null-terminated file name as stored as the key of the
+  // FileEntries map.
+  const char *InterndFileName = NamedFileEnt.getKeyData();
+   
+  UFE->Name    = InterndFileName;
   UFE->Size    = Size;
   UFE->ModTime = ModificationTime;
   UFE->Dir     = DirInfo;
@@ -363,15 +366,13 @@
   
   // If this virtual file resolves to a file, also map that file to the 
   // newly-created file entry.
-  const char *InterndFileName = NamedFileEnt.getKeyData();
   struct stat StatBuf;
-  if (!getStatValue(InterndFileName, StatBuf) &&
-      !S_ISDIR(StatBuf.st_mode)) {
-    llvm::sys::Path FilePath(InterndFileName);
-    FilePath.makeAbsolute();
-    FileEntries[FilePath.str()] = UFE;
-  }
-  
+  if (getStatValue(InterndFileName, StatBuf, false))
+    return UFE;
+    
+  llvm::sys::Path FilePath(UFE->Name);
+  FilePath.makeAbsolute();
+  FileEntries[FilePath.str()] = UFE;
   return UFE;
 }
 
@@ -409,16 +410,22 @@
 /// getStatValue - Get the 'stat' information for the specified path, using the
 /// cache to accellerate it if possible.  This returns true if the path does not
 /// exist or false if it exists.
-bool FileManager::getStatValue(const char *Path, struct stat &StatBuf) {
+///
+/// The isForDir member indicates whether this is a directory lookup or not.
+/// This will return failure if the lookup isn't the expected kind.
+bool FileManager::getStatValue(const char *Path, struct stat &StatBuf,
+                               bool isForDir) {
   // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
   // absolute!
   if (FileSystemOpts.WorkingDir.empty())
-    return FileSystemStatCache::get(Path, StatBuf, StatCache.get());
+    return FileSystemStatCache::get(Path, StatBuf, StatCache.get()) ||
+           S_ISDIR(StatBuf.st_mode) != isForDir;
   
   llvm::sys::Path FilePath(Path);
   FixupRelativePath(FilePath, FileSystemOpts);
 
-  return FileSystemStatCache::get(FilePath.c_str(), StatBuf, StatCache.get());
+  return FileSystemStatCache::get(FilePath.c_str(), StatBuf, StatCache.get()) ||
+         S_ISDIR(StatBuf.st_mode) != isForDir;
 }
 
 





More information about the cfe-commits mailing list