[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