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

Ted Kremenek kremenek at apple.com
Sat Feb 23 19:15:25 PST 2008


Author: kremenek
Date: Sat Feb 23 21:15:25 2008
New Revision: 47535

URL: http://llvm.org/viewvc/llvm-project?rev=47535&view=rev
Log:
In FileManager: use full paths to unique files and directories on Windows,
since inodes are bogus abstraction on that platform.

Patch by Argiris Kirtzidis!

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

Modified: cfe/trunk/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Basic/FileManager.cpp?rev=47535&r1=47534&r2=47535&view=diff

==============================================================================
--- cfe/trunk/Basic/FileManager.cpp (original)
+++ cfe/trunk/Basic/FileManager.cpp Sat Feb 23 21:15:25 2008
@@ -22,6 +22,7 @@
 #include "llvm/Bitcode/Serialize.h"
 #include "llvm/Bitcode/Deserialize.h"
 #include "llvm/Support/Streams.h"
+#include "llvm/Config/config.h"
 using namespace clang;
 
 // FIXME: Enhance libsystem to support inode and other fields.
@@ -35,6 +36,107 @@
 /// represent a dir name that doesn't exist on the disk.
 #define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
 
+#ifdef LLVM_ON_WIN32
+
+#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/' || (x) == '\\')
+
+namespace {
+  static std::string GetFullPath(const char *relPath)
+  {
+    char *absPathStrPtr = _fullpath(NULL, relPath, 0);
+    assert(absPathStrPtr && "_fullpath() returned NULL!");
+
+    std::string absPath(absPathStrPtr);
+
+    free(absPathStrPtr);
+    return absPath;
+  }
+}
+
+class FileManager::UniqueDirContainer {
+  /// UniqueDirs - Cache from full path to existing directories/files.
+  ///
+  llvm::StringMap<DirectoryEntry> UniqueDirs;  
+
+public:
+  DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
+    std::string FullPath(GetFullPath(Name));
+    return UniqueDirs.GetOrCreateValue(
+                              FullPath.c_str(),
+                              FullPath.c_str() + FullPath.size()
+                                                                ).getValue();
+  }
+  
+  size_t size() { return UniqueDirs.size(); }
+};
+
+class FileManager::UniqueFileContainer {
+  /// UniqueFiles - Cache from full path to existing directories/files.
+  ///
+  llvm::StringMap<FileEntry> UniqueFiles;
+
+public:
+  FileEntry &getFile(const char *Name, struct stat &StatBuf) {
+    std::string FullPath(GetFullPath(Name));
+    return UniqueFiles.GetOrCreateValue(
+                               FullPath.c_str(),
+                               FullPath.c_str() + FullPath.size()
+                                                                 ).getValue();
+  }
+
+  size_t size() { return UniqueFiles.size(); }
+};
+
+#else
+
+#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/')
+
+class FileManager::UniqueDirContainer {
+  /// UniqueDirs - Cache from ID's to existing directories/files.
+  ///
+  std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;  
+
+public:
+  DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
+    return UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
+  }
+
+  size_t size() { return UniqueDirs.size(); }
+};
+
+class FileManager::UniqueFileContainer {
+  /// UniqueFiles - Cache from ID's to existing directories/files.
+  ///
+  std::set<FileEntry> UniqueFiles;
+
+public:
+  FileEntry &getFile(const char *Name, struct stat &StatBuf) {
+    return
+      const_cast<FileEntry&>(
+                    *UniqueFiles.insert(FileEntry(StatBuf.st_dev,
+                                                  StatBuf.st_ino)).first);
+  }
+
+  size_t size() { return UniqueFiles.size(); }
+};
+
+#endif
+
+
+FileManager::FileManager() : UniqueDirs(*new UniqueDirContainer),
+                             UniqueFiles(*new UniqueFileContainer),
+                             DirEntries(64), FileEntries(64), NextFileUID(0)
+{
+  NumDirLookups = NumFileLookups = 0;
+  NumDirCacheMisses = NumFileCacheMisses = 0;
+}
+
+FileManager::~FileManager() {
+  delete &UniqueDirs;
+  delete &UniqueFiles;
+}
+
+
 /// getDirectory - Lookup, cache, and verify the specified directory.  This
 /// returns null if the directory doesn't exist.
 /// 
@@ -63,11 +165,10 @@
   if (stat(InterndDirName, &StatBuf) ||   // Error stat'ing.
       !S_ISDIR(StatBuf.st_mode))          // Not a directory?
     return 0;
-  
+
   // It exists.  See if we have already opened a directory with the same inode.
   // This occurs when one dir is symlinked to another, for example.    
-  DirectoryEntry &UDE = 
-    UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
+  DirectoryEntry &UDE = UniqueDirs.getDirectory(InterndDirName, StatBuf);
   
   NamedDirEnt.setValue(&UDE);
   if (UDE.getName()) // Already have an entry with this inode, return it.
@@ -108,7 +209,7 @@
   // strip off everything after it.
   // FIXME: this logic should be in sys::Path.
   const char *SlashPos = NameEnd-1;
-  while (SlashPos >= NameStart && SlashPos[0] != '/')
+  while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
     --SlashPos;
   
   const DirectoryEntry *DirInfo;
@@ -144,10 +245,7 @@
   
   // 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.
-  FileEntry &UFE = 
-   const_cast<FileEntry&>(*UniqueFiles.insert(FileEntry(StatBuf.st_dev,
-                                                        StatBuf.st_ino)).first);
-
+  FileEntry &UFE = UniqueFiles.getFile(InterndFileName, StatBuf);
   
   NamedFileEnt.setValue(&UFE);
   if (UFE.getName())  // Already have an entry with this inode, return it.

Modified: cfe/trunk/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=47535&r1=47534&r2=47535&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/FileManager.h (original)
+++ cfe/trunk/include/clang/Basic/FileManager.h Sat Feb 23 21:15:25 2008
@@ -48,6 +48,8 @@
   friend class FileManager;
 public:
   FileEntry(dev_t device, ino_t inode) : Name(0), Device(device), Inode(inode){}
+  // Add a default constructor for use with llvm::StringMap
+  FileEntry() : Name(0), Device(0), Inode(0) {}
   
   const char *getName() const { return Name; }
   off_t getSize() const { return Size; }
@@ -72,11 +74,15 @@
 /// names (e.g. symlinked) will be treated as a single file.
 ///
 class FileManager {
-  /// UniqueDirs/UniqueFiles - Cache from ID's to existing directories/files.
+
+  class UniqueDirContainer;
+  class UniqueFileContainer;
+
+  /// UniqueDirs/UniqueFiles - Cache for existing directories/files.
   ///
-  std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;  
-  std::set<FileEntry> UniqueFiles;
-  
+  UniqueDirContainer &UniqueDirs;
+  UniqueFileContainer &UniqueFiles;
+
   /// DirEntries/FileEntries - This is a cache of directory/file entries we have
   /// looked up.  The actual Entry is owned by UniqueFiles/UniqueDirs above.
   ///
@@ -91,10 +97,8 @@
   unsigned NumDirLookups, NumFileLookups;
   unsigned NumDirCacheMisses, NumFileCacheMisses;
 public:
-  FileManager() : DirEntries(64), FileEntries(64), NextFileUID(0) {
-    NumDirLookups = NumFileLookups = 0;
-    NumDirCacheMisses = NumFileCacheMisses = 0;
-  }
+  FileManager();
+  ~FileManager();
 
   /// getDirectory - Lookup, cache, and verify the specified directory.  This
   /// returns null if the directory doesn't exist.





More information about the cfe-commits mailing list