Hi,
The patch that I sent is problematic for non-windows systems, sorry
about that; new one attached (with better handling of directory
separator chars too).
Argiris Kirtzidis wrote:
Hi,
The attached patch allows clang to handle files/directories properly
on windows systems.
Index: Basic/FileManager.cpp
===================================================================
--- Basic/FileManager.cpp (revision 47456)
+++ Basic/FileManager.cpp (working copy)
@@ -35,6 +35,28 @@
/// 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 {
+ // FIXME: Add a portable GetFullPath to the llvm::sys::Path class ?
+ 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;
+ }
+}
+
+#else
+#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/')
+#endif
+
+
/// getDirectory - Lookup, cache, and verify the specified directory. This
/// returns null if the directory doesn't exist.
///
@@ -63,11 +85,18 @@
if (stat(InterndDirName, &StatBuf) || // Error stat'ing.
!S_ISDIR(StatBuf.st_mode)) // Not a directory?
return 0;
-
+
+#ifdef LLVM_ON_WIN32
+ // It exists. See if we have already opened a directory with the same full
path.
+ std::string FullPath(GetFullPath(InterndDirName));
+ DirectoryEntry &UDE =
+ UniqueDirs.GetOrCreateValue(FullPath.c_str(), FullPath.c_str() +
FullPath.size()).getValue();
+#else
// 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)];
+#endif
NamedDirEnt.setValue(&UDE);
if (UDE.getName()) // Already have an entry with this inode, return it.
@@ -108,7 +137,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;
@@ -142,11 +171,18 @@
}
//llvm::cerr << ": exists\n";
+#ifdef LLVM_ON_WIN32
+ // It exists. See if we have already opened a file with the same full path.
+ std::string FullPath(GetFullPath(InterndFileName));
+ FileEntry &UFE =
+ UniqueFiles.GetOrCreateValue(FullPath.c_str(), FullPath.c_str() +
FullPath.size()).getValue();
+#else
// 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);
+#endif
NamedFileEnt.setValue(&UFE);
Index: include/clang/Basic/FileManager.h
===================================================================
--- include/clang/Basic/FileManager.h (revision 47456)
+++ include/clang/Basic/FileManager.h (working copy)
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/Bitcode/SerializationFwd.h"
+#include "llvm/Config/Config.h"
#include <map>
#include <set>
#include <string>
@@ -48,6 +49,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,10 +75,19 @@
/// names (e.g. symlinked) will be treated as a single file.
///
class FileManager {
+
+#ifdef LLVM_ON_WIN32
+ // ino_t is useless on windows, cache using full path as unique criterion
+ /// UniqueDirs/UniqueFiles - Cache from full path to existing
directories/files.
+ ///
+ llvm::StringMap<DirectoryEntry> UniqueDirs;
+ llvm::StringMap<FileEntry> UniqueFiles;
+#else
/// UniqueDirs/UniqueFiles - Cache from ID's to existing directories/files.
///
std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
std::set<FileEntry> UniqueFiles;
+#endif
/// DirEntries/FileEntries - This is a cache of directory/file entries we
have
/// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above.
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev