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,23 @@
 /// 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
+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;
+  }
+}
+#endif
+
+
 /// getDirectory - Lookup, cache, and verify the specified directory.  This
 /// returns null if the directory doesn't exist.
 /// 
@@ -63,11 +80,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)];
+    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 +132,12 @@
   // 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
+    && SlashPos[0] != '/'
+#ifdef LLVM_ON_WIN32
+    && SlashPos[0] != '\\'
+#endif
+      )
     --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

Reply via email to