r187619 - Use llvm::sys::fs::UniqueID for windows and unix.

Alexey Samsonov samsonov at google.com
Fri Aug 2 02:12:19 PDT 2013


Hi Rafael,

MSan reported an error after this commit, which I hopefully fixed in
r187647.
Default PPRegion ctor didn't initialize UniqueID, which could lead to weird
comparison results.
Another possible fix would be to make default UniqueID ctor initialize the
members with zeroes, but I didn't like it,
as UniqueID is essentially a pair, and zeroes might be valid values on some
platforms. Could you check if this looks fine to you?


On Fri, Aug 2, 2013 at 1:42 AM, Rafael Espindola <rafael.espindola at gmail.com
> wrote:

> Author: rafael
> Date: Thu Aug  1 16:42:11 2013
> New Revision: 187619
>
> URL: http://llvm.org/viewvc/llvm-project?rev=187619&view=rev
> Log:
> Use llvm::sys::fs::UniqueID for windows and unix.
>
> This unifies the unix and windows versions of
> FileManager::UniqueDirContainer
> and FileManager::UniqueFileContainer by using UniqueID.
>
> We cannot just replace "struct stat" with llvm::sys::fs::file_status,
> since we
> want to be able to construct fake ones, and file_status has different
> members
> on unix and windows.
>
> What the patch does is:
>
> * Record only the information that clang is actually using.
> * Use llvm::sys::fs::status instead of stat and fstat.
> * Use llvm::sys::fs::UniqueID
> * Delete the old windows versions of UniqueDirContainer and
> UniqueFileContainer since the "unix" one now works on windows too.
>
> Modified:
>     cfe/trunk/include/clang/Basic/FileManager.h
>     cfe/trunk/include/clang/Basic/FileSystemStatCache.h
>     cfe/trunk/lib/Basic/FileManager.cpp
>     cfe/trunk/lib/Basic/FileSystemStatCache.cpp
>     cfe/trunk/lib/Frontend/CacheTokens.cpp
>     cfe/trunk/lib/Frontend/TextDiagnostic.cpp
>     cfe/trunk/lib/Lex/PTHLexer.cpp
>     cfe/trunk/tools/libclang/CIndex.cpp
>     cfe/trunk/tools/libclang/Indexing.cpp
>     cfe/trunk/unittests/Basic/FileManagerTest.cpp
>
> Modified: cfe/trunk/include/clang/Basic/FileManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/FileManager.h (original)
> +++ cfe/trunk/include/clang/Basic/FileManager.h Thu Aug  1 16:42:11 2013
> @@ -63,9 +63,9 @@ class FileEntry {
>    time_t ModTime;             // Modification time of file.
>    const DirectoryEntry *Dir;  // Directory file lives in.
>    unsigned UID;               // A unique (small) ID for the file.
> -  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'.
> +  llvm::sys::fs::UniqueID UniqueID;
> +  bool IsNamedPipe;
> +  bool InPCH;
>
>    /// FD - The file descriptor for the file entry if it is opened and
> owned
>    /// by the FileEntry.  If not, this is set to -1.
> @@ -73,10 +73,12 @@ class FileEntry {
>    friend class FileManager;
>
>  public:
> -  FileEntry(dev_t device, ino_t inode, mode_t m)
> -    : Name(0), Device(device), Inode(inode), FileMode(m), FD(-1) {}
> +  FileEntry(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe, bool
> InPCH)
> +      : Name(0), UniqueID(UniqueID), IsNamedPipe(IsNamedPipe),
> InPCH(InPCH),
> +        FD(-1) {}
>    // Add a default constructor for use with llvm::StringMap
> -  FileEntry() : Name(0), Device(0), Inode(0), FileMode(0), FD(-1) {}
> +  FileEntry()
> +      : Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false), FD(-1)
> {}
>
>    FileEntry(const FileEntry &FE) {
>      memcpy(this, &FE, sizeof(FE));
> @@ -93,23 +95,22 @@ public:
>    const char *getName() const { return Name; }
>    off_t getSize() const { return Size; }
>    unsigned getUID() const { return UID; }
> -  ino_t getInode() const { return Inode; }
> -  dev_t getDevice() const { return Device; }
> +  const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
> +  bool isInPCH() const { return InPCH; }
>    time_t getModificationTime() const { return ModTime; }
> -  mode_t getFileMode() const { return FileMode; }
>
>    /// \brief Return the directory the file lives in.
>    const DirectoryEntry *getDir() const { return Dir; }
>
> -  bool operator<(const FileEntry &RHS) const {
> -    return Device < RHS.Device || (Device == RHS.Device && Inode <
> RHS.Inode);
> -  }
> +  bool operator<(const FileEntry &RHS) const { return UniqueID <
> RHS.UniqueID; }
>
>    /// \brief Check whether the file is a named pipe (and thus can't be
> opened by
>    /// the native FileManager methods).
> -  bool isNamedPipe() const;
> +  bool isNamedPipe() const { return IsNamedPipe; }
>  };
>
> +struct FileData;
> +
>  /// \brief Implements support for file system lookup, file system caching,
>  /// and directory search management.
>  ///
> @@ -170,8 +171,8 @@ class FileManager : public RefCountedBas
>    // Caching.
>    OwningPtr<FileSystemStatCache> StatCache;
>
> -  bool getStatValue(const char *Path, struct stat &StatBuf,
> -                    bool isFile, int *FileDescriptor);
> +  bool getStatValue(const char *Path, FileData &Data, bool isFile,
> +                    int *FileDescriptor);
>
>    /// Add all ancestors of the given path (pointing to either a file
>    /// or a directory) as virtual directories.
>
> Modified: cfe/trunk/include/clang/Basic/FileSystemStatCache.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileSystemStatCache.h?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/FileSystemStatCache.h (original)
> +++ cfe/trunk/include/clang/Basic/FileSystemStatCache.h Thu Aug  1
> 16:42:11 2013
> @@ -18,11 +18,21 @@
>  #include "clang/Basic/LLVM.h"
>  #include "llvm/ADT/OwningPtr.h"
>  #include "llvm/ADT/StringMap.h"
> +#include "llvm/Support/FileSystem.h"
>  #include <sys/stat.h>
>  #include <sys/types.h>
>
>  namespace clang {
>
> +struct FileData {
> +  uint64_t Size;
> +  time_t ModTime;
> +  llvm::sys::fs::UniqueID UniqueID;
> +  bool IsDirectory;
> +  bool IsNamedPipe;
> +  bool InPCH;
> +};
> +
>  /// \brief Abstract interface for introducing a FileManager cache for
> 'stat'
>  /// system calls, which is used by precompiled and pretokenized headers to
>  /// improve performance.
> @@ -49,10 +59,9 @@ public:
>    /// success for directories (not files).  On a successful file lookup,
> the
>    /// implementation can optionally fill in FileDescriptor with a valid
>    /// descriptor and the client guarantees that it will close it.
> -  static bool get(const char *Path, struct stat &StatBuf,
> -                  bool isFile, int *FileDescriptor, FileSystemStatCache
> *Cache);
> -
> -
> +  static bool get(const char *Path, FileData &Data, bool isFile,
> +                  int *FileDescriptor, FileSystemStatCache *Cache);
> +
>    /// \brief Sets the next stat call cache in the chain of stat caches.
>    /// Takes ownership of the given stat cache.
>    void setNextStatCache(FileSystemStatCache *Cache) {
> @@ -68,18 +77,18 @@ public:
>    FileSystemStatCache *takeNextStatCache() { return NextStatCache.take();
> }
>
>  protected:
> -  virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
> -                               bool isFile, int *FileDescriptor) = 0;
> +  virtual LookupResult getStat(const char *Path, FileData &Data, bool
> isFile,
> +                               int *FileDescriptor) = 0;
>
> -  LookupResult statChained(const char *Path, struct stat &StatBuf,
> -                           bool isFile, int *FileDescriptor) {
> +  LookupResult statChained(const char *Path, FileData &Data, bool isFile,
> +                           int *FileDescriptor) {
>      if (FileSystemStatCache *Next = getNextStatCache())
> -      return Next->getStat(Path, StatBuf, isFile, FileDescriptor);
> -
> +      return Next->getStat(Path, Data, isFile, FileDescriptor);
> +
>      // If we hit the end of the list of stat caches to try, just compute
> and
>      // return it without a cache.
> -    return get(Path, StatBuf,
> -               isFile, FileDescriptor, 0) ? CacheMissing : CacheExists;
> +    return get(Path, Data, isFile, FileDescriptor, 0) ? CacheMissing
> +                                                      : CacheExists;
>    }
>  };
>
> @@ -89,16 +98,16 @@ protected:
>  class MemorizeStatCalls : public FileSystemStatCache {
>  public:
>    /// \brief The set of stat() calls that have been seen.
> -  llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls;
> -
> -  typedef llvm::StringMap<struct stat,
> llvm::BumpPtrAllocator>::const_iterator
> +  llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
> +
> +  typedef llvm::StringMap<FileData,
> llvm::BumpPtrAllocator>::const_iterator
>    iterator;
> -
> +
>    iterator begin() const { return StatCalls.begin(); }
>    iterator end() const { return StatCalls.end(); }
> -
> -  virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
> -                               bool isFile, int *FileDescriptor);
> +
> +  virtual LookupResult getStat(const char *Path, FileData &Data, bool
> isFile,
> +                               int *FileDescriptor);
>  };
>
>  } // end namespace clang
>
> Modified: cfe/trunk/lib/Basic/FileManager.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Basic/FileManager.cpp (original)
> +++ cfe/trunk/lib/Basic/FileManager.cpp Thu Aug  1 16:42:11 2013
> @@ -63,91 +63,16 @@ FileEntry::~FileEntry() {
>    if (FD != -1) ::close(FD);
>  }
>
> -bool FileEntry::isNamedPipe() const {
> -  return S_ISFIFO(FileMode);
> -}
> -
>
> -//===----------------------------------------------------------------------===//
> -// Windows.
>
> -//===----------------------------------------------------------------------===//
> -
> -#ifdef LLVM_ON_WIN32
> -
> -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:
> -  /// getDirectory - Return an existing DirectoryEntry with the given
> -  /// name if there is already one; otherwise create and return a
> -  /// default-constructed DirectoryEntry.
> -  DirectoryEntry &getDirectory(const char *Name,
> -                               const struct stat & /*StatBuf*/) {
> -    std::string FullPath(GetFullPath(Name));
> -    return UniqueDirs.GetOrCreateValue(FullPath).getValue();
> -  }
> -
> -  size_t size() const { return UniqueDirs.size(); }
> -};
> -
> -class FileManager::UniqueFileContainer {
> -  /// UniqueFiles - Cache from full path to existing directories/files.
> -  ///
> -  llvm::StringMap<FileEntry, llvm::BumpPtrAllocator> UniqueFiles;
> -
> -public:
> -  /// getFile - Return an existing FileEntry with the given name if
> -  /// there is already one; otherwise create and return a
> -  /// default-constructed FileEntry.
> -  FileEntry &getFile(const char *Name, const struct stat & /*StatBuf*/) {
> -    std::string FullPath(GetFullPath(Name));
> -
> -    // Lowercase string because Windows filesystem is case insensitive.
> -    FullPath = StringRef(FullPath).lower();
> -    return UniqueFiles.GetOrCreateValue(FullPath).getValue();
> -  }
> -
> -  size_t size() const { return UniqueFiles.size(); }
> -
> -  void erase(const FileEntry *Entry) {
> -    std::string FullPath(GetFullPath(Entry->getName()));
> -
> -    // Lowercase string because Windows filesystem is case insensitive.
> -    FullPath = StringRef(FullPath).lower();
> -    UniqueFiles.erase(FullPath);
> -  }
> -};
> -
>
> -//===----------------------------------------------------------------------===//
> -// Unix-like Systems.
>
> -//===----------------------------------------------------------------------===//
> -
> -#else
> -
>  class FileManager::UniqueDirContainer {
>    /// UniqueDirs - Cache from ID's to existing directories/files.
> -  std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
> +  std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueDirs;
>
>  public:
>    /// getDirectory - Return an existing DirectoryEntry with the given
>    /// ID's if there is already one; otherwise create and return a
>    /// default-constructed DirectoryEntry.
> -  DirectoryEntry &getDirectory(const char * /*Name*/,
> -                               const struct stat &StatBuf) {
> -    return UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
> +  DirectoryEntry &getDirectory(const llvm::sys::fs::UniqueID &UniqueID) {
> +    return UniqueDirs[UniqueID];
>    }
>
>    size_t size() const { return UniqueDirs.size(); }
> @@ -161,12 +86,10 @@ public:
>    /// getFile - Return an existing FileEntry with the given ID's if
>    /// there is already one; otherwise create and return a
>    /// default-constructed FileEntry.
> -  FileEntry &getFile(const char * /*Name*/, const struct stat &StatBuf) {
> -    return
> -      const_cast<FileEntry&>(
> -                    *UniqueFiles.insert(FileEntry(StatBuf.st_dev,
> -                                                  StatBuf.st_ino,
> -
>  StatBuf.st_mode)).first);
> +  FileEntry &getFile(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe,
> +                     bool InPCH) {
> +    return const_cast<FileEntry &>(
> +        *UniqueFiles.insert(FileEntry(UniqueID, IsNamedPipe,
> InPCH)).first);
>    }
>
>    size_t size() const { return UniqueFiles.size(); }
> @@ -174,8 +97,6 @@ public:
>    void erase(const FileEntry *Entry) { UniqueFiles.erase(*Entry); }
>  };
>
> -#endif
> -
>
>  //===----------------------------------------------------------------------===//
>  // Common logic.
>
>  //===----------------------------------------------------------------------===//
> @@ -323,8 +244,8 @@ const DirectoryEntry *FileManager::getDi
>    const char *InterndDirName = NamedDirEnt.getKeyData();
>
>    // Check to see if the directory exists.
> -  struct stat StatBuf;
> -  if (getStatValue(InterndDirName, StatBuf, false, 0/*directory
> lookup*/)) {
> +  FileData Data;
> +  if (getStatValue(InterndDirName, Data, false, 0 /*directory lookup*/)) {
>      // There's no real directory at the given path.
>      if (!CacheFailure)
>        SeenDirEntries.erase(DirName);
> @@ -335,7 +256,8 @@ const DirectoryEntry *FileManager::getDi
>    // same inode (this occurs on Unix-like systems when one dir is
>    // symlinked to another, for example) or the same path (on
>    // Windows).
> -  DirectoryEntry &UDE = UniqueRealDirs.getDirectory(InterndDirName,
> StatBuf);
> +  DirectoryEntry &UDE =
> +      UniqueRealDirs.getDirectory(Data.UniqueID);
>
>    NamedDirEnt.setValue(&UDE);
>    if (!UDE.getName()) {
> @@ -388,8 +310,8 @@ const FileEntry *FileManager::getFile(St
>
>    // Nope, there isn't.  Check to see if the file exists.
>    int FileDescriptor = -1;
> -  struct stat StatBuf;
> -  if (getStatValue(InterndFileName, StatBuf, true,
> +  FileData Data;
> +  if (getStatValue(InterndFileName, Data, true,
>                     openFile ? &FileDescriptor : 0)) {
>      // There's no real file at the given path.
>      if (!CacheFailure)
> @@ -405,7 +327,8 @@ const FileEntry *FileManager::getFile(St
>
>    // 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 = UniqueRealFiles.getFile(InterndFileName, StatBuf);
> +  FileEntry &UFE =
> +      UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe,
> Data.InPCH);
>
>    NamedFileEnt.setValue(&UFE);
>    if (UFE.getName()) { // Already have an entry with this inode, return
> it.
> @@ -420,8 +343,8 @@ const FileEntry *FileManager::getFile(St
>    // FIXME: Change the name to be a char* that points back to the
>    // 'SeenFileEntries' key.
>    UFE.Name    = InterndFileName;
> -  UFE.Size    = StatBuf.st_size;
> -  UFE.ModTime = StatBuf.st_mtime;
> +  UFE.Size = Data.Size;
> +  UFE.ModTime = Data.ModTime;
>    UFE.Dir     = DirInfo;
>    UFE.UID     = NextFileUID++;
>    UFE.FD      = FileDescriptor;
> @@ -458,12 +381,12 @@ FileManager::getVirtualFile(StringRef Fi
>           "The directory of a virtual file should already be in the
> cache.");
>
>    // Check to see if the file exists. If so, drop the virtual file
> -  struct stat StatBuf;
> +  FileData Data;
>    const char *InterndFileName = NamedFileEnt.getKeyData();
> -  if (getStatValue(InterndFileName, StatBuf, true, 0) == 0) {
> -    StatBuf.st_size = Size;
> -    StatBuf.st_mtime = ModificationTime;
> -    UFE = &UniqueRealFiles.getFile(InterndFileName, StatBuf);
> +  if (getStatValue(InterndFileName, Data, true, 0) == 0) {
> +    Data.Size = Size;
> +    Data.ModTime = ModificationTime;
> +    UFE = &UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe,
> Data.InPCH);
>
>      NamedFileEnt.setValue(UFE);
>
> @@ -572,19 +495,19 @@ getBufferForFile(StringRef Filename, std
>  /// if the path points to a virtual file or does not exist, or returns
>  /// false if it's an existent real file.  If FileDescriptor is NULL,
>  /// do directory look-up instead of file look-up.
> -bool FileManager::getStatValue(const char *Path, struct stat &StatBuf,
> -                               bool isFile, int *FileDescriptor) {
> +bool FileManager::getStatValue(const char *Path, FileData &Data, bool
> isFile,
> +                               int *FileDescriptor) {
>    // FIXME: FileSystemOpts shouldn't be passed in here, all paths should
> be
>    // absolute!
>    if (FileSystemOpts.WorkingDir.empty())
> -    return FileSystemStatCache::get(Path, StatBuf, isFile, FileDescriptor,
> +    return FileSystemStatCache::get(Path, Data, isFile, FileDescriptor,
>                                      StatCache.get());
>
>    SmallString<128> FilePath(Path);
>    FixupRelativePath(FilePath);
>
> -  return FileSystemStatCache::get(FilePath.c_str(), StatBuf,
> -                                  isFile, FileDescriptor,
> StatCache.get());
> +  return FileSystemStatCache::get(FilePath.c_str(), Data, isFile,
> +                                  FileDescriptor, StatCache.get());
>  }
>
>  bool FileManager::getNoncachedStatValue(StringRef Path,
>
> Modified: cfe/trunk/lib/Basic/FileSystemStatCache.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileSystemStatCache.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Basic/FileSystemStatCache.cpp (original)
> +++ cfe/trunk/lib/Basic/FileSystemStatCache.cpp Thu Aug  1 16:42:11 2013
> @@ -30,6 +30,16 @@ using namespace clang;
>
>  void FileSystemStatCache::anchor() { }
>
> +static void copyStatusToFileData(const llvm::sys::fs::file_status &Status,
> +                                 FileData &Data) {
> +  Data.Size = Status.getSize();
> +  Data.ModTime = Status.getLastModificationTime().toEpochTime();
> +  Data.UniqueID = Status.getUniqueID();
> +  Data.IsDirectory = is_directory(Status);
> +  Data.IsNamedPipe = Status.type() == llvm::sys::fs::file_type::fifo_file;
> +  Data.InPCH = false;
> +}
> +
>  /// FileSystemStatCache::get - Get the 'stat' information for the
> specified
>  /// path, using the cache to accelerate it if possible.  This returns
> true if
>  /// the path does not exist or false if it exists.
> @@ -39,19 +49,24 @@ void FileSystemStatCache::anchor() { }
>  /// success for directories (not files).  On a successful file lookup, the
>  /// implementation can optionally fill in FileDescriptor with a valid
>  /// descriptor and the client guarantees that it will close it.
> -bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf,
> -                              bool isFile, int *FileDescriptor,
> -                              FileSystemStatCache *Cache) {
> +bool FileSystemStatCache::get(const char *Path, FileData &Data, bool
> isFile,
> +                              int *FileDescriptor, FileSystemStatCache
> *Cache) {
>    LookupResult R;
>    bool isForDir = !isFile;
>
>    // If we have a cache, use it to resolve the stat query.
>    if (Cache)
> -    R = Cache->getStat(Path, StatBuf, isFile, FileDescriptor);
> +    R = Cache->getStat(Path, Data, isFile, FileDescriptor);
>    else if (isForDir || !FileDescriptor) {
>      // If this is a directory or a file descriptor is not needed and we
> have
>      // no cache, just go to the file system.
> -    R = ::stat(Path, &StatBuf) != 0 ? CacheMissing : CacheExists;
> +    llvm::sys::fs::file_status Status;
> +    if (llvm::sys::fs::status(Path, Status)) {
> +      R = CacheMissing;
> +    } else {
> +      R = CacheExists;
> +      copyStatusToFileData(Status, Data);
> +    }
>    } else {
>      // Otherwise, we have to go to the filesystem.  We can always just use
>      // 'stat' here, but (for files) the client is asking whether the file
> exists
> @@ -69,9 +84,11 @@ bool FileSystemStatCache::get(const char
>        // Otherwise, the open succeeded.  Do an fstat to get the
> information
>        // about the file.  We'll end up returning the open file descriptor
> to the
>        // client to do what they please with it.
> -      if (::fstat(*FileDescriptor, &StatBuf) == 0)
> +      llvm::sys::fs::file_status Status;
> +      if (!llvm::sys::fs::status(*FileDescriptor, Status)) {
>          R = CacheExists;
> -      else {
> +        copyStatusToFileData(Status, Data);
> +      } else {
>          // fstat rarely fails.  If it does, claim the initial open didn't
>          // succeed.
>          R = CacheMissing;
> @@ -86,7 +103,7 @@ bool FileSystemStatCache::get(const char
>
>    // If the path exists, make sure that its "directoryness" matches the
> clients
>    // demands.
> -  if (S_ISDIR(StatBuf.st_mode) != isForDir) {
> +  if (Data.IsDirectory != isForDir) {
>      // If not, close the file if opened.
>      if (FileDescriptor && *FileDescriptor != -1) {
>        ::close(*FileDescriptor);
> @@ -99,12 +116,11 @@ bool FileSystemStatCache::get(const char
>    return false;
>  }
>
> -
>  MemorizeStatCalls::LookupResult
> -MemorizeStatCalls::getStat(const char *Path, struct stat &StatBuf,
> -                           bool isFile, int *FileDescriptor) {
> -  LookupResult Result = statChained(Path, StatBuf, isFile,
> FileDescriptor);
> -
> +MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile,
> +                           int *FileDescriptor) {
> +  LookupResult Result = statChained(Path, Data, isFile, FileDescriptor);
> +
>    // Do not cache failed stats, it is easy to construct common
> inconsistent
>    // situations if we do, and they are not important for PCH performance
> (which
>    // currently only needs the stats to construct the initial FileManager
> @@ -113,8 +129,8 @@ MemorizeStatCalls::getStat(const char *P
>      return Result;
>
>    // Cache file 'stat' results and directories with absolutely paths.
> -  if (!S_ISDIR(StatBuf.st_mode) || llvm::sys::path::is_absolute(Path))
> -    StatCalls[Path] = StatBuf;
> -
> +  if (!Data.IsDirectory || llvm::sys::path::is_absolute(Path))
> +    StatCalls[Path] = Data;
> +
>    return Result;
>  }
>
> Modified: cfe/trunk/lib/Frontend/CacheTokens.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CacheTokens.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Frontend/CacheTokens.cpp (original)
> +++ cfe/trunk/lib/Frontend/CacheTokens.cpp Thu Aug  1 16:42:11 2013
> @@ -58,16 +58,16 @@ public:
>  class PTHEntryKeyVariant {
>    union { const FileEntry* FE; const char* Path; };
>    enum { IsFE = 0x1, IsDE = 0x2, IsNoExist = 0x0 } Kind;
> -  struct stat *StatBuf;
> +  FileData *Data;
> +
>  public:
> -  PTHEntryKeyVariant(const FileEntry *fe)
> -    : FE(fe), Kind(IsFE), StatBuf(0) {}
> +  PTHEntryKeyVariant(const FileEntry *fe) : FE(fe), Kind(IsFE), Data(0) {}
>
> -  PTHEntryKeyVariant(struct stat* statbuf, const char* path)
> -    : Path(path), Kind(IsDE), StatBuf(new struct stat(*statbuf)) {}
> +  PTHEntryKeyVariant(FileData *Data, const char *path)
> +      : Path(path), Kind(IsDE), Data(new FileData(*Data)) {}
>
> -  explicit PTHEntryKeyVariant(const char* path)
> -    : Path(path), Kind(IsNoExist), StatBuf(0) {}
> +  explicit PTHEntryKeyVariant(const char *path)
> +      : Path(path), Kind(IsNoExist), Data(0) {}
>
>    bool isFile() const { return Kind == IsFE; }
>
> @@ -79,22 +79,21 @@ public:
>
>    void EmitData(raw_ostream& Out) {
>      switch (Kind) {
> -    case IsFE:
> +    case IsFE: {
>        // Emit stat information.
> -      ::Emit32(Out, FE->getInode());
> -      ::Emit32(Out, FE->getDevice());
> -      ::Emit16(Out, FE->getFileMode());
> +      llvm::sys::fs::UniqueID UID = FE->getUniqueID();
> +      ::Emit64(Out, UID.getFile());
> +      ::Emit64(Out, UID.getDevice());
>        ::Emit64(Out, FE->getModificationTime());
>        ::Emit64(Out, FE->getSize());
> -      break;
> +    } break;
>      case IsDE:
>        // Emit stat information.
> -      ::Emit32(Out, (uint32_t) StatBuf->st_ino);
> -      ::Emit32(Out, (uint32_t) StatBuf->st_dev);
> -      ::Emit16(Out, (uint16_t) StatBuf->st_mode);
> -      ::Emit64(Out, (uint64_t) StatBuf->st_mtime);
> -      ::Emit64(Out, (uint64_t) StatBuf->st_size);
> -      delete StatBuf;
> +      ::Emit64(Out, Data->UniqueID.getFile());
> +      ::Emit64(Out, Data->UniqueID.getDevice());
> +      ::Emit64(Out, Data->ModTime);
> +      ::Emit64(Out, Data->Size);
> +      delete Data;
>        break;
>      default:
>        break;
> @@ -516,18 +515,18 @@ public:
>    StatListener(PTHMap &pm) : PM(pm) {}
>    ~StatListener() {}
>
> -  LookupResult getStat(const char *Path, struct stat &StatBuf,
> -                       bool isFile, int *FileDescriptor) {
> -    LookupResult Result = statChained(Path, StatBuf, isFile,
> FileDescriptor);
> +  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
> +                       int *FileDescriptor) {
> +    LookupResult Result = statChained(Path, Data, isFile, FileDescriptor);
>
>      if (Result == CacheMissing) // Failed 'stat'.
>        PM.insert(PTHEntryKeyVariant(Path), PTHEntry());
> -    else if (S_ISDIR(StatBuf.st_mode)) {
> +    else if (Data.IsDirectory) {
>        // Only cache directories with absolute paths.
>        if (llvm::sys::path::is_relative(Path))
>          return Result;
>
> -      PM.insert(PTHEntryKeyVariant(&StatBuf, Path), PTHEntry());
> +      PM.insert(PTHEntryKeyVariant(&Data, Path), PTHEntry());
>      }
>
>      return Result;
>
> Modified: cfe/trunk/lib/Frontend/TextDiagnostic.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnostic.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Frontend/TextDiagnostic.cpp (original)
> +++ cfe/trunk/lib/Frontend/TextDiagnostic.cpp Thu Aug  1 16:42:11 2013
> @@ -778,11 +778,8 @@ void TextDiagnostic::emitDiagnosticLoc(S
>        const FileEntry* FE = SM.getFileEntryForID(FID);
>        if (FE && FE->getName()) {
>          OS << FE->getName();
> -        if (FE->getDevice() == 0 && FE->getInode() == 0
> -            && FE->getFileMode() == 0) {
> -          // in PCH is a guess, but a good one:
> +        if (FE->isInPCH())
>            OS << " (in PCH)";
> -        }
>          OS << ": ";
>        }
>      }
>
> Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
> +++ cfe/trunk/lib/Lex/PTHLexer.cpp Thu Aug  1 16:42:11 2013
> @@ -619,18 +619,18 @@ PTHLexer *PTHManager::CreateLexer(FileID
>  namespace {
>  class PTHStatData {
>  public:
> -  const bool hasStat;
> -  const ino_t ino;
> -  const dev_t dev;
> -  const mode_t mode;
> -  const time_t mtime;
> -  const off_t size;
> +  const bool HasData;
> +  uint64_t Size;
> +  time_t ModTime;
> +  llvm::sys::fs::UniqueID UniqueID;
> +  bool IsDirectory;
> +
> +  PTHStatData(uint64_t Size, time_t ModTime, llvm::sys::fs::UniqueID
> UniqueID,
> +              bool IsDirectory)
> +      : HasData(true), Size(Size), ModTime(ModTime), UniqueID(UniqueID),
> +        IsDirectory(IsDirectory) {}
>
> -  PTHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
> -  : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
> -
> -  PTHStatData()
> -    : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
> +  PTHStatData() : HasData(false) {}
>  };
>
>  class PTHStatLookupTrait : public PTHFileLookupCommonTrait {
> @@ -653,12 +653,18 @@ public:
>                              unsigned) {
>
>      if (k.first /* File or Directory */) {
> -      if (k.first == 0x1 /* File */) d += 4 * 2; // Skip the first 2
> words.
> -      ino_t ino = (ino_t) ReadUnalignedLE32(d);
> -      dev_t dev = (dev_t) ReadUnalignedLE32(d);
> -      mode_t mode = (mode_t) ReadUnalignedLE16(d);
> -      time_t mtime = (time_t) ReadUnalignedLE64(d);
> -      return data_type(ino, dev, mode, mtime, (off_t)
> ReadUnalignedLE64(d));
> +      bool IsDirectory = true;
> +      if (k.first == 0x1 /* File */) {
> +        IsDirectory = false;
> +        d += 4 * 2; // Skip the first 2 words.
> +      }
> +
> +      uint64_t File = ReadUnalignedLE64(d);
> +      uint64_t Device = ReadUnalignedLE64(d);
> +      llvm::sys::fs::UniqueID UniqueID(File, Device);
> +      time_t ModTime = ReadUnalignedLE64(d);
> +      uint64_t Size = ReadUnalignedLE64(d);
> +      return data_type(Size, ModTime, UniqueID, IsDirectory);
>      }
>
>      // Negative stat.  Don't read anything.
> @@ -677,25 +683,27 @@ public:
>
>    ~PTHStatCache() {}
>
> -  LookupResult getStat(const char *Path, struct stat &StatBuf,
> -                       bool isFile, int *FileDescriptor) {
> +  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
> +                       int *FileDescriptor) {
>      // Do the lookup for the file's data in the PTH file.
>      CacheTy::iterator I = Cache.find(Path);
>
>      // If we don't get a hit in the PTH file just forward to 'stat'.
>      if (I == Cache.end())
> -      return statChained(Path, StatBuf, isFile, FileDescriptor);
> +      return statChained(Path, Data, isFile, FileDescriptor);
>
> -    const PTHStatData &Data = *I;
> +    const PTHStatData &D = *I;
>
> -    if (!Data.hasStat)
> +    if (!D.HasData)
>        return CacheMissing;
>
> -    StatBuf.st_ino = Data.ino;
> -    StatBuf.st_dev = Data.dev;
> -    StatBuf.st_mtime = Data.mtime;
> -    StatBuf.st_mode = Data.mode;
> -    StatBuf.st_size = Data.size;
> +    Data.Size = D.Size;
> +    Data.ModTime = D.ModTime;
> +    Data.UniqueID = D.UniqueID;
> +    Data.IsDirectory = D.IsDirectory;
> +    Data.IsNamedPipe = false;
> +    Data.InPCH = true;
> +
>      return CacheExists;
>    }
>  };
>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Aug  1 16:42:11 2013
> @@ -3057,15 +3057,12 @@ int clang_getFileUniqueID(CXFile file, C
>    if (!file || !outID)
>      return 1;
>
> -#ifdef LLVM_ON_WIN32
> -  return 1; // inodes not supported on windows.
> -#else
>    FileEntry *FEnt = static_cast<FileEntry *>(file);
> -  outID->data[0] = FEnt->getDevice();
> -  outID->data[1] = FEnt->getInode();
> +  const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
> +  outID->data[0] = ID.getDevice();
> +  outID->data[1] = ID.getFile();
>    outID->data[2] = FEnt->getModificationTime();
>    return 0;
> -#endif
>  }
>
>  } // end: extern "C"
>
> Modified: cfe/trunk/tools/libclang/Indexing.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/Indexing.cpp (original)
> +++ cfe/trunk/tools/libclang/Indexing.cpp Thu Aug  1 16:42:11 2013
> @@ -88,25 +88,23 @@ public:
>  ///   #3 is identified as the location of "#ifdef CAKE"
>  ///
>  class PPRegion {
> -  ino_t ino;
> +  llvm::sys::fs::UniqueID UniqueID;
>    time_t ModTime;
> -  dev_t dev;
>    unsigned Offset;
>  public:
> -  PPRegion() : ino(), ModTime(), dev(), Offset() {}
> -  PPRegion(dev_t dev, ino_t ino, unsigned offset, time_t modTime)
> -    : ino(ino), ModTime(modTime), dev(dev), Offset(offset) {}
> +  PPRegion() : ModTime(), Offset() {}
> +  PPRegion(llvm::sys::fs::UniqueID UniqueID, unsigned offset, time_t
> modTime)
> +      : UniqueID(UniqueID), ModTime(modTime), Offset(offset) {}
>
> -  ino_t getIno() const { return ino; }
> -  dev_t getDev() const { return dev; }
> +  const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
>    unsigned getOffset() const { return Offset; }
>    time_t getModTime() const { return ModTime; }
>
>    bool isInvalid() const { return *this == PPRegion(); }
>
>    friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
> -    return lhs.dev == rhs.dev && lhs.ino == rhs.ino &&
> -        lhs.Offset == rhs.Offset && lhs.ModTime == rhs.ModTime;
> +    return lhs.UniqueID == rhs.UniqueID && lhs.Offset == rhs.Offset &&
> +           lhs.ModTime == rhs.ModTime;
>    }
>  };
>
> @@ -122,16 +120,17 @@ namespace llvm {
>    template <>
>    struct DenseMapInfo<PPRegion> {
>      static inline PPRegion getEmptyKey() {
> -      return PPRegion(0, 0, unsigned(-1), 0);
> +      return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
>      }
>      static inline PPRegion getTombstoneKey() {
> -      return PPRegion(0, 0, unsigned(-2), 0);
> +      return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-2), 0);
>      }
>
>      static unsigned getHashValue(const PPRegion &S) {
>        llvm::FoldingSetNodeID ID;
> -      ID.AddInteger(S.getIno());
> -      ID.AddInteger(S.getDev());
> +      const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();
> +      ID.AddInteger(UniqueID.getFile());
> +      ID.AddInteger(UniqueID.getDevice());
>        ID.AddInteger(S.getOffset());
>        ID.AddInteger(S.getModTime());
>        return ID.ComputeHash();
> @@ -208,9 +207,10 @@ private:
>    PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE)
> {
>      SourceLocation RegionLoc =
> PPRec.findConditionalDirectiveRegionLoc(Loc);
>      if (RegionLoc.isInvalid()) {
> -      if (isParsedOnceInclude(FE))
> -        return PPRegion(FE->getDevice(), FE->getInode(), 0,
> -                        FE->getModificationTime());
> +      if (isParsedOnceInclude(FE)) {
> +        const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
> +        return PPRegion(ID, 0, FE->getModificationTime());
> +      }
>        return PPRegion();
>      }
>
> @@ -221,14 +221,15 @@ private:
>      llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
>
>      if (RegionFID != FID) {
> -      if (isParsedOnceInclude(FE))
> -        return PPRegion(FE->getDevice(), FE->getInode(), 0,
> -                        FE->getModificationTime());
> +      if (isParsedOnceInclude(FE)) {
> +        const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
> +        return PPRegion(ID, 0, FE->getModificationTime());
> +      }
>        return PPRegion();
>      }
>
> -    return PPRegion(FE->getDevice(), FE->getInode(), RegionOffset,
> -                    FE->getModificationTime());
> +    const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
> +    return PPRegion(ID, RegionOffset, FE->getModificationTime());
>    }
>
>    bool isParsedOnceInclude(const FileEntry *FE) {
>
> Modified: cfe/trunk/unittests/Basic/FileManagerTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/FileManagerTest.cpp?rev=187619&r1=187618&r2=187619&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/Basic/FileManagerTest.cpp (original)
> +++ cfe/trunk/unittests/Basic/FileManagerTest.cpp Thu Aug  1 16:42:11 2013
> @@ -24,18 +24,15 @@ class FakeStatCache : public FileSystemS
>  private:
>    // Maps a file/directory path to its desired stat result.  Anything
>    // not in this map is considered to not exist in the file system.
> -  llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls;
> +  llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
>
>    void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) {
> -    struct stat statBuf;
> -    memset(&statBuf, 0, sizeof(statBuf));
> -    statBuf.st_dev = 1;
> -#ifndef _WIN32  // struct stat has no st_ino field on Windows.
> -    statBuf.st_ino = INode;
> -#endif
> -    statBuf.st_mode = IsFile ? (0777 | S_IFREG)  // a regular file
> -        : (0777 | S_IFDIR);  // a directory
> -    StatCalls[Path] = statBuf;
> +    FileData Data;
> +    memset(&Data, 0, sizeof(FileData));
> +    llvm::sys::fs::UniqueID ID(1, INode);
> +    Data.UniqueID = ID;
> +    Data.IsDirectory = !IsFile;
> +    StatCalls[Path] = Data;
>    }
>
>  public:
> @@ -50,10 +47,10 @@ public:
>    }
>
>    // Implement FileSystemStatCache::getStat().
> -  virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
> -                               bool isFile, int *FileDescriptor) {
> +  virtual LookupResult getStat(const char *Path, FileData &Data, bool
> isFile,
> +                               int *FileDescriptor) {
>      if (StatCalls.count(Path) != 0) {
> -      StatBuf = StatCalls[Path];
> +      Data = StatCalls[Path];
>        return CacheExists;
>      }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



-- 
Alexey Samsonov, MSK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130802/f612d150/attachment.html>


More information about the cfe-commits mailing list