[cfe-dev] Module maps, __FILE__ and lazy stat'ing of headers

Richard Smith richard at metafoo.co.uk
Tue Jul 29 15:04:48 PDT 2014


On Mon, Jul 28, 2014 at 11:40 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

>
> On 28 Jul 2014 17:57, "Ben Langmuir" <blangmuir at apple.com> wrote:
> >
> >
> >> On Jul 28, 2014, at 4:37 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
> >>
> >> On Mon, Jul 28, 2014 at 3:10 PM, Ben Langmuir <blangmuir at apple.com>
> wrote:
> >>>
> >>>
> >>> > On Jul 28, 2014, at 4:31 AM, Manuel Klimek <klimek at google.com>
> wrote:
> >>> >
> >>> > Hi Richard,
> >>> >
> >>> > while working with module maps for layering checks a problem with
> __FILE__ we noticed triggered a couple of questions.
> >>> >
> >>> > The problem is that __FILE__ uses the path of the first 'stat' call
> (as that is how FileManager::getFile() works).
> >>>
> >>> I was thinking about this a while ago and independently of this issue
> I would really like to change this behaviour at some point.  The name of a
> file is a property of how you look it up, not an intrinsic part of the file
> itself.
> >>
> >>
> >> I agree. We have incorrectly conflated the notion of the file identity
> (inode) with the directory entriy, and we can't tell the two apart. This
> leads to weird behavior in a number of places. For instance:
> >>
> >>  a/
> >>   x.h: #include "y.h"
> >>   y.h: int a = 0;
> >>  b/
> >>   x.h: symlink to a/x.h
> >>   y.h: int b = 0;
> >>  main.c:
> >>   #include "a/x.h"
> >>   #include "b/x.h"
> >>   int main() { return a + b; }
> >>
> >> On a correct compiler, this would work. For clang, it fails, because
> b/x.h's #include finds a/y.h, because we use the path by which we first
> found x.h as the One True Path to x.h. (This also leads to wrong __FILE__,
> etc.)
> >>
> >> I tried fixing this ~2 years ago by splitting FileEntry into separate
> dentry and inode classes, but this rapidly snowballed and exposed the same
> design error being made in various other components.
> >
> >
> > Interesting.  My motivation was keeping track of virtual and “real”
> paths for the VFS, which is a special case of the above.  Maybe we can sink
> the dentry/inode down to the VFS layer eventually?  Getting symlinks and
> “..” entries to work in the VFS make a lot more sense when we have explicit
> dentries rather than inferring from the file path.
> >
> > I’d be interested in what issues you ran into here if you remember.
>
> I'll see if I can dig out my patch tomorrow.
>
Attached is my WIP patch from (as it turns out) over 2 years ago. My (very)
hazy memories were that we had quite a few different places where people
were using FileEntry*s for things, and neither a dentry nor an inode seemed
like the "right" thing. I don't remember any more details than that. There
were also places where we would need to just make a decision, such as: what
should #pragma once use as its key? (I think dentry is the right answer
here, since the same file found in different directories might mean
different things, but that answer may break some people who use #pragma
once and don't also have include guards. Conversely, it fixes some builds
on content-addressed file systems.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140729/bfa71687/attachment.html>
-------------- next part --------------
Index: include/clang/Frontend/ASTUnit.h
===================================================================
--- include/clang/Frontend/ASTUnit.h	(revision 159287)
+++ include/clang/Frontend/ASTUnit.h	(working copy)
@@ -162,20 +162,18 @@
 
 public:
   class PreambleData {
-    const FileEntry *File;
     std::vector<char> Buffer;
     mutable unsigned NumLines;
     
   public:
-    PreambleData() : File(0), NumLines(0) { }
+    PreambleData() : NumLines(0) { }
     
-    void assign(const FileEntry *F, const char *begin, const char *end) {
-      File = F;
+    void assign(const char *begin, const char *end) {
       Buffer.assign(begin, end);
       NumLines = 0;
     }
 
-    void clear() { Buffer.clear(); File = 0; NumLines = 0; }
+    void clear() { Buffer.clear(); NumLines = 0; }
 
     size_t size() const { return Buffer.size(); }
     bool empty() const { return Buffer.empty(); }
Index: include/clang/Basic/Module.h
===================================================================
--- include/clang/Basic/Module.h	(revision 159287)
+++ include/clang/Basic/Module.h	(working copy)
@@ -31,7 +31,7 @@
 namespace clang {
   
 class DirectoryEntry;
-class FileEntry;
+class FileName;
 class LangOptions;
 class TargetInfo;
   
@@ -53,7 +53,7 @@
   Module *Parent;
   
   /// \brief The umbrella header or directory.
-  llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
+  llvm::PointerUnion<const DirectoryEntry *, const FileName *> Umbrella;
   
 private:
   /// \brief The submodules of this module, indexed by name.
@@ -65,7 +65,7 @@
   
 public:
   /// \brief The headers that are part of this module.
-  llvm::SmallVector<const FileEntry *, 2> Headers;
+  llvm::SmallVector<const FileName *, 2> Headers;
 
   /// \brief The set of language features required to use this module.
   ///
@@ -233,8 +233,8 @@
 
   /// \brief Retrieve the header that serves as the umbrella header for this
   /// module.
-  const FileEntry *getUmbrellaHeader() const {
-    return Umbrella.dyn_cast<const FileEntry *>();
+  const FileName *getUmbrellaHeader() const {
+    return Umbrella.dyn_cast<const FileName *>();
   }
 
   /// \brief Determine whether this module has an umbrella directory that is
Index: include/clang/Basic/SourceManager.h
===================================================================
--- include/clang/Basic/SourceManager.h	(revision 159287)
+++ include/clang/Basic/SourceManager.h	(working copy)
@@ -55,6 +55,7 @@
 class SourceManager;
 class FileManager;
 class FileEntry;
+class FileName;
 class LineTableInfo;
 class LangOptions;
 class ASTWriter;
@@ -233,6 +234,9 @@
     /// Zero means the preprocessor didn't provide such info for this SLocEntry.
     unsigned NumCreatedFIDs;
 
+    /// \brief The name by which this file was included.
+    const FileName *Name;
+
     /// \brief Contains the ContentCache* and the bits indicating the
     /// characteristic of the file and whether it has \#line info, all
     /// bitmangled together.
@@ -243,11 +247,13 @@
     friend class clang::ASTReader;
   public:
     /// \brief Return a FileInfo object.
-    static FileInfo get(SourceLocation IL, const ContentCache *Con,
+    static FileInfo get(SourceLocation IL, const FileName *Name,
+                        const ContentCache *Con,
                         CharacteristicKind FileCharacter) {
       FileInfo X;
       X.IncludeLoc = IL.getRawEncoding();
       X.NumCreatedFIDs = 0;
+      X.Name = Name;
       X.Data = (uintptr_t)Con;
       assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
       assert((unsigned)FileCharacter < 4 && "invalid file character");
@@ -258,6 +264,9 @@
     SourceLocation getIncludeLoc() const {
       return SourceLocation::getFromRawEncoding(IncludeLoc);
     }
+    const FileName *getName() const {
+      return Name;
+    }
     const ContentCache* getContentCache() const {
       return reinterpret_cast<const ContentCache*>(Data & ~7UL);
     }
@@ -663,7 +672,7 @@
   FileID getMainFileID() const { return MainFileID; }
 
   /// \brief Create the FileID for the main source file.
-  FileID createMainFileID(const FileEntry *SourceFile, 
+  FileID createMainFileID(const FileName *SourceFile,
                           SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
     assert(MainFileID.isInvalid() && "MainFileID already set!");
     MainFileID = createFileID(SourceFile, SourceLocation(), Kind);
@@ -693,12 +702,13 @@
   /// being \#included from the specified IncludePosition.
   ///
   /// This translates NULL into standard input.
-  FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
+  FileID createFileID(const FileName *SourceFile, SourceLocation IncludePos,
                       SrcMgr::CharacteristicKind FileCharacter,
                       int LoadedID = 0, unsigned LoadedOffset = 0) {
     const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
     assert(IR && "getOrCreateContentCache() cannot return NULL");
-    return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
+    return createFileID(IR, IncludePos, SourceFile, FileCharacter, LoadedID,
+                        LoadedOffset);
   }
 
   /// \brief Create a new FileID that represents the specified memory buffer.
@@ -708,7 +718,7 @@
   FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
                                   int LoadedID = 0, unsigned LoadedOffset = 0,
                                  SourceLocation IncludeLoc = SourceLocation()) {
-    return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
+    return createFileID(createMemBufferContentCache(Buffer), IncludeLoc, 0,
                         SrcMgr::C_User, LoadedID, LoadedOffset);
   }
 
@@ -816,27 +826,19 @@
                                                         Invalid);
   }
 
-  /// \brief Returns the FileEntry record for the provided FileID.
-  const FileEntry *getFileEntryForID(FileID FID) const {
+  /// \brief Returns the FileName record for the provided FileID.
+  const FileName *getFileNameForID(FileID FID) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile())
       return 0;
-
-    const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
-    if (!Content)
-      return 0;
-    return Content->OrigEntry;
+    return Entry.getFile().getName();
   }
+  const FileEntry *getFileEntryForID(FileID FID) const;
 
   /// \brief Returns the FileEntry record for the provided SLocEntry.
-  const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
-  {
-    const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
-    if (!Content)
-      return 0;
-    return Content->OrigEntry;
-  }
+  const FileEntry *
+      getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const;
 
   /// \brief Return a StringRef to the source buffer data for the
   /// specified FileID.
@@ -1497,11 +1499,14 @@
   ///  corresponds to a file or some other input source.
   FileID createFileID(const SrcMgr::ContentCache* File,
                       SourceLocation IncludePos,
+                      const FileName *Name,
                       SrcMgr::CharacteristicKind DirCharacter,
                       int LoadedID, unsigned LoadedOffset);
 
   const SrcMgr::ContentCache *
     getOrCreateContentCache(const FileEntry *SourceFile);
+  const SrcMgr::ContentCache *
+    getOrCreateContentCache(const FileName *SourceFile);
 
   /// createMemBufferContentCache - Create a new ContentCache for the specified
   ///  memory buffer.
Index: include/clang/Basic/FileManager.h
===================================================================
--- include/clang/Basic/FileManager.h	(revision 159287)
+++ include/clang/Basic/FileManager.h	(working copy)
@@ -56,10 +56,9 @@
 /// this FileEntry has an open file descriptor for the file.
 ///
 class FileEntry {
-  const char *Name;           // Name of the file.
+  const char *Name;           // A name by which this file can be found.
   off_t Size;                 // File size in bytes.
   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.
@@ -96,15 +95,41 @@
   time_t getModificationTime() const { return ModTime; }
   mode_t getFileMode() const { return FileMode; }
 
-  /// getDir - 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);
   }
 };
 
+/// \brief Cached information about a way of naming a file.
+class FileName {
+  /// Entry for the directory the file lives in.
+  const DirectoryEntry *Dir;
+
+  /// Entry for the contents of the file.
+  const FileEntry *Entry;
+
+  friend class FileManager;
+
+public:
+  FileName() : Entry(0) {}
+
+  /// \brief Get the name that was used to specify this file. This StringRef
+  /// is guaranteed to be nul-terminated.
+  StringRef getName() const {
+    return llvm::StringMapEntry<FileName>::
+        GetStringMapEntryFromValue(*this).getKey();
+  }
+
+  /// \brief Return the directory the file lives in.
+  const DirectoryEntry *getDir() const { return Dir; }
+
+  /// \brief Get information about the contents of the file. Multiple FileNames
+  /// can have the same FileEntity if the names are known to refer to the same
+  /// contents (through symlinks, hard links, case collapsing, or any other
+  /// platform-specific mechanism).
+  const FileEntry *getEntry() const { return Entry; }
+};
+
 /// FileManager - Implements support for file system lookup, file system
 /// caching, and directory search management.  This also handles more advanced
 /// properties, such as uniquing files based on "inode", so that a file with two
@@ -137,7 +162,7 @@
   /// VirtualDirectoryEntries/VirtualFileEntries above.
   ///
   llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
-  llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
+  llvm::StringMap<FileName, llvm::BumpPtrAllocator> SeenFileEntries;
 
   /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
   ///
@@ -196,8 +221,8 @@
   ///
   /// \param CacheFailure If true and the file does not exist, we'll cache
   /// the failure to find this file.
-  const FileEntry *getFile(StringRef Filename, bool OpenFile = false,
-                           bool CacheFailure = true);
+  const FileName *getFile(StringRef Filename, bool OpenFile = false,
+                          bool CacheFailure = true);
 
   /// \brief Returns the current file system options
   const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; }
@@ -206,8 +231,8 @@
   /// if there were a file with the given name on disk.
   ///
   /// The file itself is not accessed.
-  const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
-                                  time_t ModificationTime);
+  const FileName *getVirtualFile(StringRef Filename, off_t Size,
+                                 time_t ModificationTime);
 
   /// \brief Open the specified file as a MemoryBuffer, returning a new
   /// MemoryBuffer if successful, otherwise returning null.
Index: include/clang/Lex/DirectoryLookup.h
===================================================================
--- include/clang/Lex/DirectoryLookup.h	(revision 159287)
+++ include/clang/Lex/DirectoryLookup.h	(working copy)
@@ -149,14 +149,14 @@
   /// \param [out] InUserSpecifiedSystemFramework If the file is found,
   /// set to true if the file is located in a framework that has been
   /// user-specified to be treated as a system framework.
-  const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
-                              SmallVectorImpl<char> *SearchPath,
-                              SmallVectorImpl<char> *RelativePath,
-                              Module **SuggestedModule,
-                              bool &InUserSpecifiedSystemFramework) const;
+  const FileName *LookupFile(StringRef Filename, HeaderSearch &HS,
+                             SmallVectorImpl<char> *SearchPath,
+                             SmallVectorImpl<char> *RelativePath,
+                             Module **SuggestedModule,
+                             bool &InUserSpecifiedSystemFramework) const;
 
 private:
-  const FileEntry *DoFrameworkLookup(
+  const FileName *DoFrameworkLookup(
       StringRef Filename, HeaderSearch &HS,
       SmallVectorImpl<char> *SearchPath,
       SmallVectorImpl<char> *RelativePath,
Index: include/clang/Lex/HeaderSearch.h
===================================================================
--- include/clang/Lex/HeaderSearch.h	(revision 159287)
+++ include/clang/Lex/HeaderSearch.h	(working copy)
@@ -317,8 +317,8 @@
   /// \param CurDir If non-null, the file was found in the specified directory
   /// search location.  This is used to implement \#include_next.
   ///
-  /// \param CurFileEnt If non-null, indicates where the \#including file is, in
-  /// case a relative search is needed.
+  /// \param CurFileName If non-null, indicates where the \#including file is,
+  /// in case a relative search is needed.
   ///
   /// \param SearchPath If non-null, will be set to the search path relative
   /// to which the file was found. If the include path is absolute, SearchPath
@@ -331,22 +331,22 @@
   /// \param SuggestedModule If non-null, and the file found is semantically
   /// part of a known module, this will be set to the module that should
   /// be imported instead of preprocessing/parsing the file found.
-  const FileEntry *LookupFile(StringRef Filename, bool isAngled,
-                              const DirectoryLookup *FromDir,
-                              const DirectoryLookup *&CurDir,
-                              const FileEntry *CurFileEnt,
-                              SmallVectorImpl<char> *SearchPath,
-                              SmallVectorImpl<char> *RelativePath,
-                              Module **SuggestedModule,
-                              bool SkipCache = false);
+  const FileName *LookupFile(StringRef Filename, bool isAngled,
+                             const DirectoryLookup *FromDir,
+                             const DirectoryLookup *&CurDir,
+                             const FileName *CurFileName,
+                             SmallVectorImpl<char> *SearchPath,
+                             SmallVectorImpl<char> *RelativePath,
+                             Module **SuggestedModule,
+                             bool SkipCache = false);
 
   /// \brief Look up a subframework for the specified \#include file.
   ///
   /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
   /// HIToolbox is a subframework within Carbon.framework.  If so, return
-  /// the FileEntry for the designated file, otherwise return null.
-  const FileEntry *LookupSubframeworkHeader(
+  /// the FileName for the designated file, otherwise return null.
+  const FileName *LookupSubframeworkHeader(
       StringRef Filename,
       const FileEntry *RelativeFileEnt,
       SmallVectorImpl<char> *SearchPath,
@@ -455,14 +455,14 @@
   /// \brief Retrieve the module that corresponds to the given file, if any.
   ///
   /// \param File The header that we wish to map to a module.
-  Module *findModuleForHeader(const FileEntry *File);
+  Module *findModuleForHeader(const FileName *File);
   
   /// \brief Read the contents of the given module map file.
   ///
   /// \param File The module map file.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool loadModuleMapFile(const FileEntry *File);
+  bool loadModuleMapFile(const FileName *File);
 
   /// \brief Collect the set of all known, top-level modules.
   ///
Index: include/clang/Lex/ModuleMap.h
===================================================================
--- include/clang/Lex/ModuleMap.h	(revision 159287)
+++ include/clang/Lex/ModuleMap.h	(working copy)
@@ -29,7 +29,6 @@
 namespace clang {
   
 class DirectoryEntry;
-class FileEntry;
 class FileManager;
 class DiagnosticConsumer;
 class DiagnosticsEngine;
@@ -55,7 +54,7 @@
   
   /// \brief Mapping from each header to the module that owns the contents of the
   /// that header.
-  llvm::DenseMap<const FileEntry *, Module *> Headers;
+  llvm::DenseMap<const FileName *, Module *> Headers;
   
   /// \brief Mapping from directories with umbrella headers to the module
   /// that is generated from the umbrella header.
@@ -118,11 +117,11 @@
   ///
   /// \returns The module that owns the given header file, or null to indicate
   /// that no module owns this header file.
-  Module *findModuleForHeader(const FileEntry *File);
+  Module *findModuleForHeader(const FileName *File);
 
   /// \brief Determine whether the given header is part of a module
   /// marked 'unavailable'.
-  bool isHeaderInUnavailableModule(const FileEntry *Header);
+  bool isHeaderInUnavailableModule(const FileName *Header);
 
   /// \brief Retrieve a module with the given name.
   ///
@@ -182,9 +181,9 @@
   ///
   /// \param Module The module whose module map file will be returned, if known.
   ///
-  /// \returns The file entry for the module map file containing the given
+  /// \returns The file name for the module map file containing the given
   /// module, or NULL if the module definition was inferred.
-  const FileEntry *getContainingModuleMapFile(Module *Module);
+  const FileName *getContainingModuleMapFile(Module *Module);
 
   /// \brief Resolve all of the unresolved exports in the given module.
   ///
@@ -208,14 +207,14 @@
   
   /// \brief Sets the umbrella header of the given module to the given
   /// header.
-  void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
+  void setUmbrellaHeader(Module *Mod, const FileName *UmbrellaHeader);
 
   /// \brief Sets the umbrella directory of the given module to the given
   /// directory.
   void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
 
   /// \brief Adds this header to the given module.
-  void addHeader(Module *Mod, const FileEntry *Header);
+  void addHeader(Module *Mod, const FileName *Header);
 
   /// \brief Parse the given module map file, and record any modules we 
   /// encounter.
@@ -223,7 +222,7 @@
   /// \param File The file to be parsed.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool parseModuleMapFile(const FileEntry *File);
+  bool parseModuleMapFile(const FileName *File);
     
   /// \brief Dump the contents of the module map, for debugging purposes.
   void dump();
Index: include/clang/Lex/HeaderMap.h
===================================================================
--- include/clang/Lex/HeaderMap.h	(revision 159287)
+++ include/clang/Lex/HeaderMap.h	(working copy)
@@ -22,6 +22,7 @@
 namespace clang {
   class FileEntry;
   class FileManager;
+  class FileName;
   struct HMapBucket;
   struct HMapHeader;
 
@@ -47,12 +48,12 @@
   static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
 
   /// LookupFile - Check to see if the specified relative filename is located in
-  /// this HeaderMap.  If so, open it and return its FileEntry.
+  /// this HeaderMap.  If so, open it and return its FileName.
   /// If RawPath is not NULL and the file is found, RawPath will be set to the
   /// raw path at which the file was found in the file system. For example,
   /// for a search path ".." and a filename "../file.h" this would be
   /// "../../file.h".
-  const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
+  const FileName *LookupFile(StringRef Filename, FileManager &FM) const;
 
   /// getFileName - Return the filename of the headermap.
   const char *getFileName() const;
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h	(revision 159287)
+++ include/clang/Lex/Preprocessor.h	(working copy)
@@ -1083,13 +1083,13 @@
   ///
   /// Returns null on failure.  \p isAngled indicates whether the file
   /// reference is for system \#include's or not (i.e. using <> instead of "").
-  const FileEntry *LookupFile(StringRef Filename,
-                              bool isAngled, const DirectoryLookup *FromDir,
-                              const DirectoryLookup *&CurDir,
-                              SmallVectorImpl<char> *SearchPath,
-                              SmallVectorImpl<char> *RelativePath,
-                              Module **SuggestedModule,
-                              bool SkipCache = false);
+  const FileName *LookupFile(StringRef Filename,
+                             bool isAngled, const DirectoryLookup *FromDir,
+                             const DirectoryLookup *&CurDir,
+                             SmallVectorImpl<char> *SearchPath,
+                             SmallVectorImpl<char> *RelativePath,
+                             Module **SuggestedModule,
+                             bool SkipCache = false);
 
   /// GetCurLookup - The DirectoryLookup structure used to find the current
   /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
Index: tools/libclang/Indexing.cpp
===================================================================
--- tools/libclang/Indexing.cpp	(revision 159287)
+++ tools/libclang/Indexing.cpp	(working copy)
@@ -541,8 +541,11 @@
 
   if (Unit->getOriginalSourceFileName().empty())
     IndexCtx->enteredMainFile(0);
+  else if (const FileName *MainFile =
+             FileMgr.getFile(Unit->getOriginalSourceFileName()))
+    IndexCtx->enteredMainFile(MainFile->getEntry());
   else
-    IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
+    IndexCtx->enteredMainFile(0);
 
   IndexConsumer->Initialize(Unit->getASTContext());
 
@@ -815,4 +818,3 @@
 }
 
 } // end: extern "C"
-
Index: tools/libclang/CXLoadedDiagnostic.cpp
===================================================================
--- tools/libclang/CXLoadedDiagnostic.cpp	(revision 159287)
+++ tools/libclang/CXLoadedDiagnostic.cpp	(working copy)
@@ -49,7 +49,7 @@
   
   FileSystemOptions FO;
   FileManager FakeFiles;
-  llvm::DenseMap<unsigned, const FileEntry *> Files;
+  llvm::DenseMap<unsigned, const FileName *> Files;
 };
 }
 
@@ -507,12 +507,13 @@
     return Success;
   }
 
-  const FileEntry *FE = TopDiags.Files[fileID];
-  if (!FE) {
+  const FileName *FN = TopDiags.Files[fileID];
+  if (!FN) {
     reportInvalidFile("Corrupted file entry in source location");
     return Failure;
   }
-  Loc.file = (void*) FE;
+  // FIXME: CXFile should be represented as a FileName, not a FileEntry.
+  Loc.file = (void*) FN->getEntry();
   Loc.line = Record[offset++];
   Loc.column = Record[offset++];
   Loc.offset = Record[offset++];
@@ -617,12 +618,12 @@
           return Failure;
         }
         
-        const FileEntry *FE =
+        const FileName *FN =
           TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]],
                                             /* size */ Record[1],
                                             /* time */ Record[2]);
         
-        TopDiags.Files[Record[0]] = FE;
+        TopDiags.Files[Record[0]] = FN;
         continue;
       }
 
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp	(revision 159287)
+++ tools/libclang/CIndex.cpp	(working copy)
@@ -2868,7 +2868,8 @@
   ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
 
   FileManager &FMgr = CXXUnit->getFileManager();
-  return const_cast<FileEntry *>(FMgr.getFile(file_name));
+  const FileName *Name = FMgr.getFile(file_name);
+  return Name ? const_cast<FileEntry *>(Name->getEntry()) : 0;
 }
 
 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
@@ -6011,4 +6012,3 @@
 }
 
 } // end: extern "C"
-
Index: tools/libclang/CXSourceLocation.cpp
===================================================================
--- tools/libclang/CXSourceLocation.cpp	(revision 159287)
+++ tools/libclang/CXSourceLocation.cpp	(working copy)
@@ -323,4 +323,3 @@
 }
 
 } // end extern "C"
-
Index: unittests/Basic/FileManagerTest.cpp
===================================================================
--- unittests/Basic/FileManagerTest.cpp	(revision 159287)
+++ unittests/Basic/FileManagerTest.cpp	(working copy)
@@ -75,7 +75,7 @@
 // When a virtual file is added, its getDir() field is set correctly
 // (not NULL, correct name).
 TEST_F(FileManagerTest, getVirtualFileSetsTheDirFieldCorrectly) {
-  const FileEntry *file = manager.getVirtualFile("foo.cpp", 42, 0);
+  const FileName *file = manager.getVirtualFile("foo.cpp", 42, 0);
   ASSERT_TRUE(file != NULL);
 
   const DirectoryEntry *dir = file->getDir();
@@ -128,9 +128,9 @@
   statCache->InjectFile("/tmp/test", 43);
   manager.addStatCache(statCache);
 
-  const FileEntry *file = manager.getFile("/tmp/test");
+  const FileName *file = manager.getFile("/tmp/test");
   ASSERT_TRUE(file != NULL);
-  EXPECT_STREQ("/tmp/test", file->getName());
+  EXPECT_STREQ("/tmp/test", file->getName().data());
 
   const DirectoryEntry *dir = file->getDir();
   ASSERT_TRUE(dir != NULL);
@@ -143,9 +143,9 @@
   manager.addStatCache(new FakeStatCache);
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
-  const FileEntry *file = manager.getFile("virtual/dir/bar.h");
+  const FileName *file = manager.getFile("virtual/dir/bar.h");
   ASSERT_TRUE(file != NULL);
-  EXPECT_STREQ("virtual/dir/bar.h", file->getName());
+  EXPECT_STREQ("virtual/dir/bar.h", file->getName().data());
 
   const DirectoryEntry *dir = file->getDir();
   ASSERT_TRUE(dir != NULL);
@@ -163,11 +163,12 @@
   statCache->InjectFile("bar.cpp", 43);
   manager.addStatCache(statCache);
 
-  const FileEntry *fileFoo = manager.getFile("foo.cpp");
-  const FileEntry *fileBar = manager.getFile("bar.cpp");
+  const FileName *fileFoo = manager.getFile("foo.cpp");
+  const FileName *fileBar = manager.getFile("bar.cpp");
   ASSERT_TRUE(fileFoo != NULL);
   ASSERT_TRUE(fileBar != NULL);
   EXPECT_NE(fileFoo, fileBar);
+  EXPECT_NE(fileFoo->getEntry(), fileBar->getEntry());
 }
 
 // getFile() returns NULL if neither a real file nor a virtual file
@@ -182,7 +183,7 @@
   // Create a virtual bar.cpp file.
   manager.getVirtualFile("bar.cpp", 200, 0);
 
-  const FileEntry *file = manager.getFile("xyz.txt");
+  const FileName *file = manager.getFile("xyz.txt");
   EXPECT_EQ(NULL, file);
 }
 
Index: unittests/Basic/SourceManagerTest.cpp
===================================================================
--- unittests/Basic/SourceManagerTest.cpp	(revision 159287)
+++ unittests/Basic/SourceManagerTest.cpp	(working copy)
@@ -174,9 +174,9 @@
   MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
   FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf);
 
-  const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
+  const FileName *headerFile = FileMgr.getVirtualFile("/test-header.h",
                                                  headerBuf->getBufferSize(), 0);
-  SourceMgr.overrideFileContents(headerFile, headerBuf);
+  SourceMgr.overrideFileContents(headerFile->getEntry(), headerBuf);
 
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target);
@@ -271,9 +271,9 @@
   MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
   SourceMgr.createMainFileIDForMemBuffer(mainBuf);
 
-  const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
+  const FileName *headerFile = FileMgr.getVirtualFile("/test-header.h",
                                                  headerBuf->getBufferSize(), 0);
-  SourceMgr.overrideFileContents(headerFile, headerBuf);
+  SourceMgr.overrideFileContents(headerFile->getEntry(), headerBuf);
 
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target);
Index: unittests/Tooling/RefactoringTest.cpp
===================================================================
--- unittests/Tooling/RefactoringTest.cpp	(revision 159287)
+++ unittests/Tooling/RefactoringTest.cpp	(working copy)
@@ -173,7 +173,7 @@
     assert(ErrorInfo.empty());
     OutStream << Content;
     OutStream.close();
-    const FileEntry *File = Context.Files.getFile(Path);
+    const FileName *File = Context.Files.getFile(Path);
     assert(File != NULL);
     return Context.Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
   }
Index: unittests/Tooling/RewriterTestContext.h
===================================================================
--- unittests/Tooling/RewriterTestContext.h	(revision 159287)
+++ unittests/Tooling/RewriterTestContext.h	(working copy)
@@ -53,11 +53,11 @@
   FileID createInMemoryFile(StringRef Name, StringRef Content) {
     const llvm::MemoryBuffer *Source =
       llvm::MemoryBuffer::getMemBuffer(Content);
-    const FileEntry *Entry =
+    const FileName *File =
       Files.getVirtualFile(Name, Source->getBufferSize(), 0);
-    Sources.overrideFileContents(Entry, Source, true);
-    assert(Entry != NULL);
-    return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+    assert(File != NULL);
+    Sources.overrideFileContents(File->getEntry(), Source, true);
+    return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
   }
 
   FileID createOnDiskFile(StringRef Name, StringRef Content) {
@@ -78,7 +78,7 @@
     assert(ErrorInfo.empty());
     OutStream << Content;
     OutStream.close();
-    const FileEntry *File = Files.getFile(Path);
+    const FileName *File = Files.getFile(Path);
     assert(File != NULL);
     return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
   }
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp	(revision 159287)
+++ lib/Frontend/InitHeaderSearch.cpp	(working copy)
@@ -150,8 +150,8 @@
   // Check to see if this is an apple-style headermap (which are not allowed to
   // be frameworks).
   if (!isFramework) {
-    if (const FileEntry *FE = FM.getFile(MappedPathStr)) {
-      if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
+    if (const FileName *FN = FM.getFile(MappedPathStr)) {
+      if (const HeaderMap *HM = Headers.CreateHeaderMap(FN->getEntry())) {
         // It is a headermap, add it to the search path.
         IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type,
                               isUserSupplied, Group == IndexHeaderMap)));
Index: lib/Frontend/InitPreprocessor.cpp
===================================================================
--- lib/Frontend/InitPreprocessor.cpp	(revision 159287)
+++ lib/Frontend/InitPreprocessor.cpp	(working copy)
@@ -621,9 +621,8 @@
        Remap != RemapEnd;
        ++Remap) {
     // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                Remap->second->getBufferSize(),
-                                                       0);
+    const FileName *FromFile =
+        FileMgr.getVirtualFile(Remap->first, Remap->second->getBufferSize(), 0);
     if (!FromFile) {
       Diags.Report(diag::err_fe_remap_missing_from_file)
         << Remap->first;
@@ -634,7 +633,7 @@
 
     // Override the contents of the "from" file with the contents of
     // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, Remap->second,
+    SourceMgr.overrideFileContents(FromFile->getEntry(), Remap->second,
                                    InitOpts.RetainRemappedFileBuffers);
   }
 
@@ -645,7 +644,7 @@
        Remap != RemapEnd;
        ++Remap) {
     // Find the file that we're mapping to.
-    const FileEntry *ToFile = FileMgr.getFile(Remap->second);
+    const FileName *ToFile = FileMgr.getFile(Remap->second);
     if (!ToFile) {
       Diags.Report(diag::err_fe_remap_missing_to_file)
       << Remap->first << Remap->second;
@@ -653,8 +652,8 @@
     }
     
     // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                       ToFile->getSize(), 0);
+    const FileName *FromFile =
+        FileMgr.getVirtualFile(Remap->first, ToFile->getEntry()->getSize(), 0);
     if (!FromFile) {
       Diags.Report(diag::err_fe_remap_missing_from_file)
       << Remap->first;
@@ -663,7 +662,7 @@
     
     // Override the contents of the "from" file with the contents of
     // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, ToFile);
+    SourceMgr.overrideFileContents(FromFile->getEntry(), ToFile->getEntry());
   }
 
   SourceMgr.setOverridenFilesKeepOriginalName(
Index: lib/Frontend/ASTUnit.cpp
===================================================================
--- lib/Frontend/ASTUnit.cpp	(revision 159287)
+++ lib/Frontend/ASTUnit.cpp	(working copy)
@@ -681,7 +681,7 @@
     if (const llvm::MemoryBuffer *
           memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
       // Create the file entry for the file that we're mapping from.
-      const FileEntry *FromFile
+      const FileName *FromFile
         = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
                                                memBuf->getBufferSize(),
                                                0);
@@ -694,11 +694,11 @@
       
       // Override the contents of the "from" file with the contents of
       // the "to" file.
-      AST->getSourceManager().overrideFileContents(FromFile, memBuf);
-
+      AST->getSourceManager().overrideFileContents(FromFile->getEntry(),
+                                                   memBuf);
     } else {
       const char *fname = fileOrBuf.get<const char *>();
-      const FileEntry *ToFile = AST->FileMgr->getFile(fname);
+      const FileName *ToFile = AST->FileMgr->getFile(fname);
       if (!ToFile) {
         AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file)
         << RemappedFiles[I].first << fname;
@@ -706,9 +706,9 @@
       }
 
       // Create the file entry for the file that we're mapping from.
-      const FileEntry *FromFile
+      const FileName *FromFile
         = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
-                                               ToFile->getSize(),
+                                               ToFile->getEntry()->getSize(),
                                                0);
       if (!FromFile) {
         AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
@@ -719,7 +719,8 @@
       
       // Override the contents of the "from" file with the contents of
       // the "to" file.
-      AST->getSourceManager().overrideFileContents(FromFile, ToFile);
+      AST->getSourceManager().overrideFileContents(FromFile->getEntry(),
+                                                   ToFile->getEntry());
     }
   }
   
@@ -1473,10 +1474,8 @@
 
   // Save the preamble text for later; we'll need to compare against it for
   // subsequent reparses.
-  StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].File;
-  Preamble.assign(FileMgr->getFile(MainFilename),
-                  NewPreamble.first->getBufferStart(), 
-                  NewPreamble.first->getBufferStart() 
+  Preamble.assign(NewPreamble.first->getBufferStart(),
+                  NewPreamble.first->getBufferStart()
                                                   + NewPreamble.second.first);
   PreambleEndsAtStartOfLine = NewPreamble.second.second;
 
Index: lib/Frontend/CompilerInstance.cpp
===================================================================
--- lib/Frontend/CompilerInstance.cpp	(revision 159287)
+++ lib/Frontend/CompilerInstance.cpp	(working copy)
@@ -369,7 +369,7 @@
                                  unsigned Column) {
   // Tell the source manager to chop off the given file at a specific
   // line and column.
-  const FileEntry *Entry = PP.getFileManager().getFile(Filename);
+  const FileName *Entry = PP.getFileManager().getFile(Filename);
   if (!Entry) {
     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
       << Filename;
@@ -377,7 +377,7 @@
   }
 
   // Truncate the named file at the given line/column.
-  PP.SetCodeCompletionPoint(Entry, Line, Column);
+  PP.SetCodeCompletionPoint(Entry->getEntry(), Line, Column);
   return false;
 }
 
@@ -606,7 +606,7 @@
                                                const FrontendOptions &Opts) {
   // Figure out where to get and map in the main file.
   if (InputFile != "-") {
-    const FileEntry *File = FileMgr.getFile(InputFile);
+    const FileName *File = FileMgr.getFile(InputFile);
     if (!File) {
       Diags.Report(diag::err_fe_error_reading) << InputFile;
       return false;
@@ -619,10 +619,10 @@
       Diags.Report(diag::err_fe_error_reading_stdin);
       return false;
     }
-    const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
-                                                   SB->getBufferSize(), 0);
+    const FileName *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
+                                                  SB->getBufferSize(), 0);
     SourceMgr.createMainFileID(File, Kind);
-    SourceMgr.overrideFileContents(File, SB.take());
+    SourceMgr.overrideFileContents(File->getEntry(), SB.take());
   }
 
   assert(!SourceMgr.getMainFileID().isInvalid() &&
@@ -786,7 +786,7 @@
 
   // Get or create the module map that we'll use to build this module.
   SmallString<128> TempModuleMapFileName;
-  if (const FileEntry *ModuleMapFile
+  if (const FileName *ModuleMapFile
                                   = ModMap.getContainingModuleMapFile(Module)) {
     // Use the module map where this module resides.
     FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(), 
@@ -893,7 +893,7 @@
       return 0;
     }
     
-    const FileEntry *ModuleFile
+    const FileName *ModuleFile
       = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false,
                                  /*CacheFailure=*/false);
     bool BuildingModule = false;
Index: lib/Frontend/FrontendActions.cpp
===================================================================
--- lib/Frontend/FrontendActions.cpp	(revision 159287)
+++ lib/Frontend/FrontendActions.cpp	(working copy)
@@ -152,7 +152,7 @@
     Includes += "\"\n";
   }
 
-  if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
+  if (const FileName *UmbrellaHeader = Module->getUmbrellaHeader()) {
     if (Module->Parent) {
       // Include the umbrella header for submodules.
       if (LangOpts.ObjC1)
@@ -179,7 +179,7 @@
       
       // If this header is marked 'unavailable' in this module, don't include 
       // it.
-      if (const FileEntry *Header = FileMgr.getFile(Dir->path()))
+      if (const FileName *Header = FileMgr.getFile(Dir->path()))
         if (ModMap.isHeaderInUnavailableModule(Header))
           continue;
       
@@ -203,7 +203,7 @@
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
                                                  StringRef Filename) {
   // Find the module map file.  
-  const FileEntry *ModuleMap = CI.getFileManager().getFile(Filename);
+  const FileName *ModuleMap = CI.getFileManager().getFile(Filename);
   if (!ModuleMap)  {
     CI.getDiagnostics().Report(diag::err_module_map_not_found)
       << Filename;
@@ -246,7 +246,7 @@
   }
 
   // Do we have an umbrella header for this module?
-  const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader();
+  const FileName *UmbrellaHeader = Module->getUmbrellaHeader();
   
   // Collect the set of #includes we need to build the module.
   SmallString<256> HeaderContents;
@@ -271,7 +271,7 @@
     // been overridden.
     std::string ErrorStr;
     llvm::MemoryBuffer *UmbrellaContents
-      = FileMgr.getBufferForFile(UmbrellaHeader, &ErrorStr);
+      = FileMgr.getBufferForFile(UmbrellaHeader->getEntry(), &ErrorStr);
     if (!UmbrellaContents) {
       CI.getDiagnostics().Report(diag::err_missing_umbrella_header)
         << UmbrellaHeader->getName() << ErrorStr;
@@ -288,7 +288,7 @@
 
     // Pretend that we're parsing the umbrella header.
     HeaderName = UmbrellaHeader->getName();
-    ModTime = UmbrellaHeader->getModificationTime();
+    ModTime = UmbrellaHeader->getEntry()->getModificationTime();
     
     delete UmbrellaContents;
   } else {
@@ -309,12 +309,13 @@
   
   // Remap the contents of the header name we're using to our synthesized
   // buffer.
-  const FileEntry *HeaderFile = FileMgr.getVirtualFile(HeaderName, 
-                                                       HeaderContents.size(), 
-                                                       ModTime);
+  const FileName *HeaderFile = FileMgr.getVirtualFile(HeaderName, 
+                                                      HeaderContents.size(), 
+                                                      ModTime);
   llvm::MemoryBuffer *HeaderContentsBuf
     = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents);
-  CI.getSourceManager().overrideFileContents(HeaderFile, HeaderContentsBuf);  
+  CI.getSourceManager().overrideFileContents(HeaderFile->getEntry(),
+                                             HeaderContentsBuf);
   setCurrentInput(FrontendInputFile(HeaderName, getCurrentFileKind(),
                                     Module->IsSystem));
   return true;
Index: lib/Frontend/CacheTokens.cpp
===================================================================
--- lib/Frontend/CacheTokens.cpp	(revision 159287)
+++ lib/Frontend/CacheTokens.cpp	(working copy)
@@ -481,7 +481,11 @@
     const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics(), SM);
     if (!B) continue;
 
-    FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
+    // Pick an arbitrary way of naming this file. This doesn't matter, since
+    // we're not going to be producing diagnostics or processing #includes.
+    const FileName *FN = SM.getFileManager().getFile(FE->getName());
+
+    FileID FID = SM.createFileID(FN, SourceLocation(), SrcMgr::C_User);
     const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
     Lexer L(FID, FromFile, SM, LOpts);
     PM.insert(FE, LexTokens(L));
Index: lib/Basic/FileManager.cpp
===================================================================
--- lib/Basic/FileManager.cpp	(revision 159287)
+++ lib/Basic/FileManager.cpp	(working copy)
@@ -317,42 +317,37 @@
   return &UDE;
 }
 
-const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
-                                      bool CacheFailure) {
+const FileName *FileManager::getFile(StringRef Filename, bool OpenFile,
+                                     bool CacheFailure) {
   ++NumFileLookups;
 
   // See if there is already an entry in the map.
-  llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
-    SeenFileEntries.GetOrCreateValue(Filename);
+  FileName &Name = SeenFileEntries.GetOrCreateValue(Filename).getValue();
+  if (Name.Entry)
+    return Name.Entry == NON_EXISTENT_FILE ? 0 : &Name;
 
-  // See if there is already an entry in the map.
-  if (NamedFileEnt.getValue())
-    return NamedFileEnt.getValue() == NON_EXISTENT_FILE
-                 ? 0 : NamedFileEnt.getValue();
-
   ++NumFileCacheMisses;
 
   // By default, initialize it to invalid.
-  NamedFileEnt.setValue(NON_EXISTENT_FILE);
+  Name.Entry = NON_EXISTENT_FILE;
 
   // Get the null-terminated file name as stored as the key of the
   // SeenFileEntries map.
-  const char *InterndFileName = NamedFileEnt.getKeyData();
+  const char *InterndFileName = Name.getName().data();
 
   // Look up the directory for the file.  When looking up something like
   // sys/foo.h we'll discover all of the search directories that have a 'sys'
   // subdirectory.  This will let us avoid having to waste time on known-to-fail
   // searches when we go to find sys/bar.h, because all the search directories
   // without a 'sys' subdir will get a cached failure result.
-  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
-                                                       CacheFailure);
-  if (DirInfo == 0) {  // Directory doesn't exist, file can't exist.
+  Name.Dir = getDirectoryFromFile(*this, Filename, CacheFailure);
+  if (Name.Dir == 0) {  // Directory doesn't exist, file can't exist.
     if (!CacheFailure)
       SeenFileEntries.erase(Filename);
-    
+
     return 0;
   }
-  
+
   // FIXME: Use the directory info to prune this, before doing the stat syscall.
   // FIXME: This will reduce the # syscalls.
 
@@ -367,7 +362,7 @@
     return 0;
   }
 
-  if (FileDescriptor != -1 && !openFile) {
+  if (FileDescriptor != -1 && !OpenFile) {
     close(FileDescriptor);
     FileDescriptor = -1;
   }
@@ -376,44 +371,39 @@
   // This occurs when one dir is symlinked to another, for example.
   FileEntry &UFE = UniqueRealFiles.getFile(InterndFileName, StatBuf);
 
-  NamedFileEnt.setValue(&UFE);
+  Name.Entry = &UFE;
   if (UFE.getName()) { // Already have an entry with this inode, return it.
     // If the stat process opened the file, close it to avoid a FD leak.
     if (FileDescriptor != -1)
       close(FileDescriptor);
 
-    return &UFE;
+    return &Name;
   }
 
   // Otherwise, we don't have this directory yet, add it.
-  // FIXME: Change the name to be a char* that points back to the
-  // 'SeenFileEntries' key.
+  // FIXME: Remove Name, it's not a property of an inode.
   UFE.Name    = InterndFileName;
   UFE.Size    = StatBuf.st_size;
   UFE.ModTime = StatBuf.st_mtime;
-  UFE.Dir     = DirInfo;
   UFE.UID     = NextFileUID++;
   UFE.FD      = FileDescriptor;
-  return &UFE;
+  return &Name;
 }
 
-const FileEntry *
+const FileName *
 FileManager::getVirtualFile(StringRef Filename, off_t Size,
                             time_t ModificationTime) {
   ++NumFileLookups;
 
   // See if there is already an entry in the map.
-  llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
-    SeenFileEntries.GetOrCreateValue(Filename);
+  FileName &Name = SeenFileEntries.GetOrCreateValue(Filename).getValue();
+  if (Name.Entry && Name.Entry != NON_EXISTENT_FILE)
+    return &Name;
 
-  // See if there is already an entry in the map.
-  if (NamedFileEnt.getValue() && NamedFileEnt.getValue() != NON_EXISTENT_FILE)
-    return NamedFileEnt.getValue();
-
   ++NumFileCacheMisses;
 
   // By default, initialize it to invalid.
-  NamedFileEnt.setValue(NON_EXISTENT_FILE);
+  Name.Entry = NON_EXISTENT_FILE;
 
   addAncestorsAsVirtualDirs(Filename);
   FileEntry *UFE = 0;
@@ -421,15 +411,14 @@
   // Now that all ancestors of Filename are in the cache, the
   // following call is guaranteed to find the DirectoryEntry from the
   // cache.
-  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
-                                                       /*CacheFailure=*/true);
-  assert(DirInfo &&
+  Name.Dir = getDirectoryFromFile(*this, Filename, /*CacheFailure=*/true);
+  assert(Name.Dir &&
          "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
   int FileDescriptor = -1;
   struct stat StatBuf;
-  const char *InterndFileName = NamedFileEnt.getKeyData();
+  const char *InterndFileName = Name.getName().data();
   if (getStatValue(InterndFileName, StatBuf, &FileDescriptor) == 0) {
     // If the stat process opened the file, close it to avoid a FD leak.
     if (FileDescriptor != -1)
@@ -439,7 +428,7 @@
     StatBuf.st_mtime = ModificationTime;
     UFE = &UniqueRealFiles.getFile(InterndFileName, StatBuf);
 
-    NamedFileEnt.setValue(UFE);
+    Name.Entry = UFE;
 
     // If we had already opened this file, close it now so we don't
     // leak the descriptor. We're not going to use the file
@@ -451,22 +440,21 @@
 
     // If we already have an entry with this inode, return it.
     if (UFE->getName())
-      return UFE;
+      return &Name;
   }
 
   if (!UFE) {
     UFE = new FileEntry();
     VirtualFileEntries.push_back(UFE);
-    NamedFileEnt.setValue(UFE);
+    Name.Entry = UFE;
   }
 
   UFE->Name    = InterndFileName;
   UFE->Size    = Size;
   UFE->ModTime = ModificationTime;
-  UFE->Dir     = DirInfo;
   UFE->UID     = NextFileUID++;
   UFE->FD      = -1;
-  return UFE;
+  return &Name;
 }
 
 void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const {
@@ -582,11 +570,11 @@
   UIDToFiles.resize(NextFileUID);
   
   // Map file entries
-  for (llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator>::const_iterator
+  for (llvm::StringMap<FileName, llvm::BumpPtrAllocator>::const_iterator
          FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end();
        FE != FEEnd; ++FE)
-    if (FE->getValue() && FE->getValue() != NON_EXISTENT_FILE)
-      UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
+    if (FE->getValue().Entry && FE->getValue().Entry != NON_EXISTENT_FILE)
+      UIDToFiles[FE->getValue().Entry->getUID()] = FE->getValue().Entry;
   
   // Map virtual file entries
   for (SmallVector<FileEntry*, 4>::const_iterator 
Index: lib/Basic/Module.cpp
===================================================================
--- lib/Basic/Module.cpp	(revision 159287)
+++ lib/Basic/Module.cpp	(working copy)
@@ -123,7 +123,7 @@
 }
 
 const DirectoryEntry *Module::getUmbrellaDir() const {
-  if (const FileEntry *Header = getUmbrellaHeader())
+  if (const FileName *Header = getUmbrellaHeader())
     return Header->getDir();
   
   return Umbrella.dyn_cast<const DirectoryEntry *>();
@@ -201,7 +201,7 @@
     OS << "\n";
   }
   
-  if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
+  if (const FileName *UmbrellaHeader = getUmbrellaHeader()) {
     OS.indent(Indent + 2);
     OS << "umbrella header \"";
     OS.write_escaped(UmbrellaHeader->getName());
@@ -270,5 +270,3 @@
 void Module::dump() const {
   print(llvm::errs());
 }
-
-
Index: lib/Basic/SourceManager.cpp
===================================================================
--- lib/Basic/SourceManager.cpp	(revision 159287)
+++ lib/Basic/SourceManager.cpp	(working copy)
@@ -458,6 +458,12 @@
   return Entry;
 }
 
+/// getOrCreateContentCache - Create or return a cached ContentCache for the
+/// specified file.
+const ContentCache *
+SourceManager::getOrCreateContentCache(const FileName *FileEnt) {
+  return getOrCreateContentCache(FileEnt->getEntry());
+}
 
 /// createMemBufferContentCache - Create a new ContentCache for the specified
 ///  memory buffer.  This does no caching.
@@ -485,7 +491,7 @@
     if (!SLocEntryLoaded[Index]) {
       // Try to recover; create a SLocEntry so the rest of clang can handle it.
       LoadedSLocEntryTable[Index] = SLocEntry::get(0,
-                                 FileInfo::get(SourceLocation(),
+                                 FileInfo::get(SourceLocation(), 0,
                                                getFakeContentCacheForRecovery(),
                                                SrcMgr::C_User));
     }
@@ -537,6 +543,7 @@
 /// corresponds to a file or some other input source.
 FileID SourceManager::createFileID(const ContentCache *File,
                                    SourceLocation IncludePos,
+                                   const FileName *Name,
                                    SrcMgr::CharacteristicKind FileCharacter,
                                    int LoadedID, unsigned LoadedOffset) {
   if (LoadedID < 0) {
@@ -545,13 +552,13 @@
     assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
     assert(!SLocEntryLoaded[Index] && "FileID already loaded");
     LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
-        FileInfo::get(IncludePos, File, FileCharacter));
+        FileInfo::get(IncludePos, Name, File, FileCharacter));
     SLocEntryLoaded[Index] = true;
     return FileID::get(LoadedID);
   }
-  LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
-                                               FileInfo::get(IncludePos, File,
-                                                             FileCharacter)));
+  LocalSLocEntryTable.push_back(
+    SLocEntry::get(NextLocalOffset, FileInfo::get(IncludePos, Name, File,
+                                                  FileCharacter)));
   unsigned FileSize = File->getSize();
   assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
          NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
@@ -654,6 +661,17 @@
   OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
 }
 
+const FileEntry *SourceManager::getFileEntryForID(FileID FID) const {
+  const FileName *FN = getFileNameForID(FID);
+  return FN ? FN->getEntry() : 0;
+}
+
+const FileEntry *
+SourceManager::getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const {
+  const FileName *FN = sloc.getFile().getName();
+  return FN ? FN->getEntry() : 0;
+}
+
 StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
   bool MyInvalid = false;
   const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid);
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp	(revision 159287)
+++ lib/AST/ASTImporter.cpp	(working copy)
@@ -4483,8 +4483,8 @@
     // disk again
     // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
     // than mmap the files several times.
-    const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
-    ToID = ToSM.createFileID(Entry, ToIncludeLoc, 
+    const FileName *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
+    ToID = ToSM.createFileID(Entry, ToIncludeLoc,
                              FromSLoc.getFile().getFileCharacteristic());
   } else {
     // FIXME: We want to re-use the existing MemoryBuffer!
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp	(revision 159287)
+++ lib/Lex/PPDirectives.cpp	(working copy)
@@ -498,7 +498,7 @@
   }
 }
 
-const FileEntry *Preprocessor::LookupFile(
+const FileName *Preprocessor::LookupFile(
     StringRef Filename,
     bool isAngled,
     const DirectoryLookup *FromDir,
@@ -509,10 +509,10 @@
     bool SkipCache) {
   // If the header lookup mechanism may be relative to the current file, pass in
   // info about where the current file is.
-  const FileEntry *CurFileEnt = 0;
+  const FileName *CurFileName = 0;
   if (!FromDir) {
     FileID FID = getCurrentFileLexer()->getFileID();
-    CurFileEnt = SourceMgr.getFileEntryForID(FID);
+    CurFileName = SourceMgr.getFileNameForID(FID);
 
     // If there is no file entry associated with this file, it must be the
     // predefines buffer.  Any other file is not lexed with a normal lexer, so
@@ -520,38 +520,39 @@
     // predefines buffer, resolve #include references (which come from the
     // -include command line argument) as if they came from the main file, this
     // affects file lookup etc.
-    if (CurFileEnt == 0) {
+    if (CurFileName == 0) {
       FID = SourceMgr.getMainFileID();
-      CurFileEnt = SourceMgr.getFileEntryForID(FID);
+      CurFileName = SourceMgr.getFileNameForID(FID);
     }
   }
 
   // Do a standard file entry lookup.
   CurDir = CurDirLookup;
-  const FileEntry *FE = HeaderInfo.LookupFile(
-      Filename, isAngled, FromDir, CurDir, CurFileEnt,
+  const FileName *FN = HeaderInfo.LookupFile(
+      Filename, isAngled, FromDir, CurDir, CurFileName,
       SearchPath, RelativePath, SuggestedModule, SkipCache);
-  if (FE) return FE;
+  if (FN) return FN;
 
   // Otherwise, see if this is a subframework header.  If so, this is relative
   // to one of the headers on the #include stack.  Walk the list of the current
   // headers on the #include stack and pass them to HeaderInfo.
   // FIXME: SuggestedModule!
   if (IsFileLexer()) {
-    if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
-      if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
+    if ((CurFileName = SourceMgr.getFileNameForID(CurPPLexer->getFileID())))
+      if ((FN = HeaderInfo.LookupSubframeworkHeader(Filename,
+                                                    CurFileName->getEntry(),
                                                     SearchPath, RelativePath)))
-        return FE;
+        return FN;
   }
 
   for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
     IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
     if (IsFileLexer(ISEntry)) {
-      if ((CurFileEnt =
-           SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
-        if ((FE = HeaderInfo.LookupSubframeworkHeader(
-                Filename, CurFileEnt, SearchPath, RelativePath)))
-          return FE;
+      if ((CurFileName =
+           SourceMgr.getFileNameForID(ISEntry.ThePPLexer->getFileID())))
+        if ((FN = HeaderInfo.LookupSubframeworkHeader(
+                Filename, CurFileName->getEntry(), SearchPath, RelativePath)))
+          return FN;
     }
   }
 
@@ -1361,7 +1362,7 @@
   // We get the raw path only if we have 'Callbacks' to which we later pass
   // the path.
   Module *SuggestedModule = 0;
-  const FileEntry *File = LookupFile(
+  const FileName *File = LookupFile(
       Filename, isAngled, LookupFrom, CurDir,
       Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL,
       getLangOpts().Modules? &SuggestedModule : 0);
@@ -1385,8 +1386,9 @@
     }
     
     // Notify the callback object that we've seen an inclusion directive.
-    Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File,
-                                  End, SearchPath, RelativePath);
+    Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
+                                  File->getEntry(), End, SearchPath,
+                                  RelativePath);
   }
   
   if (File == 0) {
@@ -1471,14 +1473,14 @@
   // in a system include directory, or if the #includer is a system include
   // header.
   SrcMgr::CharacteristicKind FileCharacter =
-    std::max(HeaderInfo.getFileDirFlavor(File),
+    std::max(HeaderInfo.getFileDirFlavor(File->getEntry()),
              SourceMgr.getFileCharacteristic(FilenameTok.getLocation()));
 
   // Ask HeaderInfo if we should enter this #include file.  If not, #including
   // this file will have no effect.
-  if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
+  if (!HeaderInfo.ShouldEnterIncludeFile(File->getEntry(), isImport)) {
     if (Callbacks)
-      Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
+      Callbacks->FileSkipped(*File->getEntry(), FilenameTok, FileCharacter);
     return;
   }
 
Index: lib/Lex/Pragma.cpp
===================================================================
--- lib/Lex/Pragma.cpp	(revision 159287)
+++ lib/Lex/Pragma.cpp	(working copy)
@@ -440,8 +440,8 @@
 
   // Search include directories for this file.
   const DirectoryLookup *CurDir;
-  const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL,
-                                     NULL);
+  const FileName *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL,
+                                    NULL);
   if (File == 0) {
     if (!SuppressIncludeNotFoundError)
       Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
@@ -449,9 +449,11 @@
   }
 
   const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
+  const FileEntry *DepFile = File->getEntry();
 
   // If this file is older than the file it depends on, emit a diagnostic.
-  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
+  if (CurFile &&
+      CurFile->getModificationTime() < DepFile->getModificationTime()) {
     // Lex tokens at the end of the message and include them in the message.
     std::string Message;
     Lex(DependencyTok);
Index: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp	(revision 159287)
+++ lib/Lex/HeaderSearch.cpp	(working copy)
@@ -199,7 +199,7 @@
 
 /// LookupFile - Lookup the specified file in this search path, returning it
 /// if it exists or returning null if not.
-const FileEntry *DirectoryLookup::LookupFile(
+const FileName *DirectoryLookup::LookupFile(
     StringRef Filename,
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
@@ -226,10 +226,10 @@
     // If we have a module map that might map this header, load it and
     // check whether we'll have a suggestion for a module.
     if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) {
-      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 
-                                                      /*openFile=*/false);
+      const FileName *File = HS.getFileMgr().getFile(TmpDir.str(), 
+                                                     /*openFile=*/false);
       if (!File)
-        return File;
+        return 0;
       
       // If there is a module that corresponds to this header, 
       // suggest it.
@@ -245,7 +245,7 @@
                              SuggestedModule, InUserSpecifiedSystemFramework);
 
   assert(isHeaderMap() && "Unknown directory lookup");
-  const FileEntry * const Result = getHeaderMap()->LookupFile(
+  const FileName * const Result = getHeaderMap()->LookupFile(
       Filename, HS.getFileMgr());
   if (Result) {
     if (SearchPath != NULL) {
@@ -264,7 +264,7 @@
 
 /// DoFrameworkLookup - Do a lookup of the specified file in the current
 /// DirectoryLookup, which is a framework directory.
-const FileEntry *DirectoryLookup::DoFrameworkLookup(
+const FileName *DirectoryLookup::DoFrameworkLookup(
     StringRef Filename,
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
@@ -358,11 +358,11 @@
   // Determine whether this is the module we're building or not.
   bool AutomaticImport = Module;  
   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
-  if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
-                                            /*openFile=*/!AutomaticImport)) {
+  if (const FileName *FN = FileMgr.getFile(FrameworkName.str(),
+                                           /*openFile=*/!AutomaticImport)) {
     if (AutomaticImport)
-      *SuggestedModule = HS.findModuleForHeader(FE);
-    return FE;
+      *SuggestedModule = HS.findModuleForHeader(FN);
+    return FN;
   }
 
   // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
@@ -373,11 +373,11 @@
     SearchPath->insert(SearchPath->begin()+OrigSize, Private,
                        Private+strlen(Private));
 
-  const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 
-                                        /*openFile=*/!AutomaticImport);
-  if (FE && AutomaticImport)
-    *SuggestedModule = HS.findModuleForHeader(FE);
-  return FE;
+  const FileName *FN = FileMgr.getFile(FrameworkName.str(), 
+                                       /*openFile=*/!AutomaticImport);
+  if (FN && AutomaticImport)
+    *SuggestedModule = HS.findModuleForHeader(FN);
+  return FN;
 }
 
 void HeaderSearch::setTarget(const TargetInfo &Target) {
@@ -392,15 +392,15 @@
 
 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
 /// return null on failure.  isAngled indicates whether the file reference is
-/// for system \#include's or not (i.e. using <> instead of "").  CurFileEnt, if
-/// non-null, indicates where the \#including file is, in case a relative search
-/// is needed.
-const FileEntry *HeaderSearch::LookupFile(
+/// for system \#include's or not (i.e. using <> instead of "").  CurFileName,
+/// if non-null, indicates where the \#including file is, in case a relative
+/// search is needed.
+const FileName *HeaderSearch::LookupFile(
     StringRef Filename,
     bool isAngled,
     const DirectoryLookup *FromDir,
     const DirectoryLookup *&CurDir,
-    const FileEntry *CurFileEnt,
+    const FileName *CurFileName,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
     Module **SuggestedModule,
@@ -427,28 +427,28 @@
   }
 
   // Unless disabled, check to see if the file is in the #includer's
-  // directory.  This has to be based on CurFileEnt, not CurDir, because
-  // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
+  // directory.  This has to be based on CurFileName, not CurDir, because
+  // CurFileName could be a #include of a subdirectory (#include "foo/bar.h") and
   // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
   // This search is not done for <> headers.
-  if (CurFileEnt && !isAngled && !NoCurDirSearch) {
+  if (CurFileName && !isAngled && !NoCurDirSearch) {
     SmallString<1024> TmpDir;
     // Concatenate the requested file onto the directory.
     // FIXME: Portability.  Filename concatenation should be in sys::Path.
-    TmpDir += CurFileEnt->getDir()->getName();
+    TmpDir += CurFileName->getDir()->getName();
     TmpDir.push_back('/');
     TmpDir.append(Filename.begin(), Filename.end());
-    if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) {
+    if (const FileName *FN = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) {
       // Leave CurDir unset.
       // This file is a system header or C++ unfriendly if the old file is.
       //
       // Note that the temporary 'DirInfo' is required here, as either call to
       // getFileInfo could resize the vector and we don't want to rely on order
       // of evaluation.
-      unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
-      getFileInfo(FE).DirInfo = DirInfo;
+      unsigned DirInfo = getFileInfo(CurFileName->getEntry()).DirInfo;
+      getFileInfo(FN->getEntry()).DirInfo = DirInfo;
       if (SearchPath != NULL) {
-        StringRef SearchPathRef(CurFileEnt->getDir()->getName());
+        StringRef SearchPathRef(CurFileName->getDir()->getName());
         SearchPath->clear();
         SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
       }
@@ -456,7 +456,7 @@
         RelativePath->clear();
         RelativePath->append(Filename.begin(), Filename.end());
       }
-      return FE;
+      return FN;
     }
   }
 
@@ -493,15 +493,16 @@
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     bool InUserSpecifiedSystemFramework = false;
-    const FileEntry *FE =
+    const FileName *FN =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
                                SuggestedModule, InUserSpecifiedSystemFramework);
-    if (!FE) continue;
+    if (!FN) continue;
 
     CurDir = &SearchDirs[i];
 
     // This file is a system header or C++ unfriendly if the dir is.
-    HeaderFileInfo &HFI = getFileInfo(FE);
+    // FIXME: This should depend on how the file was named, not its inode.
+    HeaderFileInfo &HFI = getFileInfo(FN->getEntry());
     HFI.DirInfo = CurDir->getDirCharacteristic();
 
     // If the directory characteristic is User but this framework was
@@ -533,25 +534,25 @@
     
     // Remember this location for the next lookup we do.
     CacheLookup.second = i;
-    return FE;
+    return FN;
   }
 
   // If we are including a file with a quoted include "foo.h" from inside
   // a header in a framework that is currently being built, and we couldn't
   // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
   // "Foo" is the name of the framework in which the including header was found.
-  if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
-    HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
+  if (CurFileName && !isAngled && Filename.find('/') == StringRef::npos) {
+    HeaderFileInfo &IncludingHFI = getFileInfo(CurFileName->getEntry());
     if (IncludingHFI.IndexHeaderMapHeader) {
       SmallString<128> ScratchFilename;
       ScratchFilename += IncludingHFI.Framework;
       ScratchFilename += '/';
       ScratchFilename += Filename;
       
-      const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
-                                           FromDir, CurDir, CurFileEnt, 
-                                           SearchPath, RelativePath,
-                                           SuggestedModule);
+      const FileName *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
+                                          FromDir, CurDir, CurFileName, 
+                                          SearchPath, RelativePath,
+                                          SuggestedModule);
       std::pair<unsigned, unsigned> &CacheLookup 
         = LookupFileCache.GetOrCreateValue(Filename).getValue();
       CacheLookup.second
@@ -568,9 +569,9 @@
 /// LookupSubframeworkHeader - Look up a subframework for the specified
 /// \#include file.  For example, if \#include'ing <HIToolbox/HIToolbox.h> from
 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
-/// is a subframework within Carbon.framework.  If so, return the FileEntry
+/// is a subframework within Carbon.framework.  If so, return the FileName
 /// for the designated file, otherwise return null.
-const FileEntry *HeaderSearch::
+const FileName *HeaderSearch::
 LookupSubframeworkHeader(StringRef Filename,
                          const FileEntry *ContextFileEnt,
                          SmallVectorImpl<char> *SearchPath,
@@ -623,7 +624,7 @@
     CacheLookup.getValue().Directory = Dir;
   }
 
-  const FileEntry *FE = 0;
+  const FileName *FN = 0;
 
   if (RelativePath != NULL) {
     RelativePath->clear();
@@ -640,7 +641,7 @@
   }
 
   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-  if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
+  if (!(FN = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
 
     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
     HeadersFilename = FrameworkName;
@@ -652,7 +653,7 @@
     }
 
     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-    if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
+    if (!(FN = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
       return 0;
   }
 
@@ -662,8 +663,8 @@
   // getFileInfo could resize the vector and we don't want to rely on order
   // of evaluation.
   unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
-  getFileInfo(FE).DirInfo = DirInfo;
-  return FE;
+  getFileInfo(FN->getEntry()).DirInfo = DirInfo;
+  return FN;
 }
 
 /// \brief Helper static function to normalize a path for injection into
@@ -839,14 +840,14 @@
   } while (true);
 }
 
-Module *HeaderSearch::findModuleForHeader(const FileEntry *File) {
+Module *HeaderSearch::findModuleForHeader(const FileName *File) {
   if (Module *Mod = ModMap.findModuleForHeader(File))
     return Mod;
   
   return 0;
 }
 
-bool HeaderSearch::loadModuleMapFile(const FileEntry *File) {
+bool HeaderSearch::loadModuleMapFile(const FileName *File) {
   const DirectoryEntry *Dir = File->getDir();
   
   llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
@@ -860,7 +861,7 @@
     // module_private.map.
     SmallString<128> PrivateFilename(Dir->getName());
     llvm::sys::path::append(PrivateFilename, "module_private.map");
-    if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename))
+    if (const FileName *PrivateFile = FileMgr.getFile(PrivateFilename))
       Result = ModMap.parseModuleMapFile(PrivateFile);
   }
   
@@ -953,7 +954,7 @@
   ModuleMapFileName += Dir->getName();
   unsigned ModuleMapDirNameLen = ModuleMapFileName.size();
   llvm::sys::path::append(ModuleMapFileName, "module.map");
-  if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
+  if (const FileName *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
     // We have found a module map file. Try to parse it.
     if (ModMap.parseModuleMapFile(ModuleMapFile)) {
       // No suitable module map.
@@ -968,7 +969,7 @@
     ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen,
                             ModuleMapFileName.end());
     llvm::sys::path::append(ModuleMapFileName, "module_private.map");
-    if (const FileEntry *PrivateModuleMapFile
+    if (const FileName *PrivateModuleMapFile
                                         = FileMgr.getFile(ModuleMapFileName)) {
       if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) {
         // No suitable module map.
Index: lib/Lex/ModuleMap.cpp
===================================================================
--- lib/Lex/ModuleMap.cpp	(revision 159287)
+++ lib/Lex/ModuleMap.cpp	(working copy)
@@ -96,8 +96,8 @@
   this->Target = &Target;
 }
 
-Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
-  llvm::DenseMap<const FileEntry *, Module *>::iterator Known
+Module *ModuleMap::findModuleForHeader(const FileName *File) {
+  llvm::DenseMap<const FileName *, Module *>::iterator Known
     = Headers.find(File);
   if (Known != Headers.end()) {
     // If a header corresponds to an unavailable module, don't report
@@ -187,8 +187,8 @@
   return 0;
 }
 
-bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
-  llvm::DenseMap<const FileEntry *, Module *>::iterator Known
+bool ModuleMap::isHeaderInUnavailableModule(const FileName *Header) {
+  llvm::DenseMap<const FileName *, Module *>::iterator Known
     = Headers.find(Header);
   if (Known != Headers.end())
     return !Known->second->isAvailable();
@@ -302,7 +302,7 @@
   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
   llvm::sys::path::append(UmbrellaName, "Headers");
   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
-  const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
+  const FileName *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
   
   // FIXME: If there's no umbrella header, we could probably scan the
   // framework to load *everything*. But, it's not clear that this is a good
@@ -355,7 +355,7 @@
   return Result;
 }
 
-void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
+void ModuleMap::setUmbrellaHeader(Module *Mod, const FileName *UmbrellaHeader) {
   Headers[UmbrellaHeader] = Mod;
   Mod->Umbrella = UmbrellaHeader;
   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
@@ -366,17 +366,17 @@
   UmbrellaDirs[UmbrellaDir] = Mod;
 }
 
-void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
+void ModuleMap::addHeader(Module *Mod, const FileName *Header) {
   Mod->Headers.push_back(Header);
   Headers[Header] = Mod;
 }
 
-const FileEntry *
+const FileName *
 ModuleMap::getContainingModuleMapFile(Module *Module) {
   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
     return 0;
 
-  return SourceMgr->getFileEntryForID(
+  return SourceMgr->getFileNameForID(
            SourceMgr->getFileID(Module->DefinitionLoc));
 }
 
@@ -388,7 +388,7 @@
     M->getValue()->print(llvm::errs(), 2);
   
   llvm::errs() << "Headers:";
-  for (llvm::DenseMap<const FileEntry *, Module *>::iterator 
+  for (llvm::DenseMap<const FileName *, Module *>::iterator 
             H = Headers.begin(),
          HEnd = Headers.end();
        H != HEnd; ++H) {
@@ -424,8 +424,8 @@
   const SourceManager &SrcMgr = Loc.getManager();
   FileID ExpansionFileID = ExpansionLoc.getFileID();
   
-  while (const FileEntry *ExpansionFile
-           = SrcMgr.getFileEntryForID(ExpansionFileID)) {
+  while (const FileName *ExpansionFile
+           = SrcMgr.getFileNameForID(ExpansionFileID)) {
     // Find the module that owns this header (if any).
     if (Module *Mod = findModuleForHeader(ExpansionFile))
       return Mod;
@@ -1087,8 +1087,8 @@
   }
 
   // Look for this file.
-  const FileEntry *File = 0;
-  const FileEntry *BuiltinFile = 0;
+  const clang::FileName *File = 0;
+  const clang::FileName *BuiltinFile = 0;
   SmallString<128> PathName;
   if (llvm::sys::path::is_absolute(FileName)) {
     PathName = FileName;
@@ -1418,7 +1418,7 @@
   } while (true);
 }
 
-bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
+bool ModuleMap::parseModuleMapFile(const FileName *File) {
   assert(Target != 0 && "Missing target information");
   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
Index: lib/Lex/PPLexerChange.cpp
===================================================================
--- lib/Lex/PPLexerChange.cpp	(revision 159287)
+++ lib/Lex/PPLexerChange.cpp	(working copy)
@@ -205,7 +205,7 @@
 /// \brief Compute the relative path that names the given file relative to
 /// the given directory.
 static void computeRelativePath(FileManager &FM, const DirectoryEntry *Dir,
-                                const FileEntry *File,
+                                const FileName *File,
                                 SmallString<128> &Result) {
   Result.clear();
 
@@ -373,8 +373,8 @@
                  .Default(false))
             continue;
 
-          if (const FileEntry *Header = getFileManager().getFile(Entry->path()))
-            if (!getSourceManager().hasFileInfo(Header)) {
+          if (const FileName *Header = getFileManager().getFile(Entry->path()))
+            if (!getSourceManager().hasFileInfo(Header->getEntry())) {
               if (!ModMap.isHeaderInUnavailableModule(Header)) {
                 // Find the relative path that would access this header.
                 SmallString<128> RelativePath;
Index: lib/Lex/HeaderMap.cpp
===================================================================
--- lib/Lex/HeaderMap.cpp	(revision 159287)
+++ lib/Lex/HeaderMap.cpp	(working copy)
@@ -199,7 +199,7 @@
 
 /// LookupFile - Check to see if the specified relative filename is located in
 /// this HeaderMap.  If so, open it and return its FileEntry.
-const FileEntry *HeaderMap::LookupFile(
+const FileName *HeaderMap::LookupFile(
     StringRef Filename, FileManager &FM) const {
   const HMapHeader &Hdr = getHeader();
   unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp	(revision 159287)
+++ lib/Lex/PPMacroExpansion.cpp	(working copy)
@@ -873,7 +873,7 @@
 
   // Search include directories.
   const DirectoryLookup *CurDir;
-  const FileEntry *File =
+  const FileName *File =
       PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL);
 
   // Get the result value.  A result of true means the file exists.
Index: lib/CodeGen/CGObjCGNU.cpp
===================================================================
--- lib/CodeGen/CGObjCGNU.cpp	(revision 159287)
+++ lib/CodeGen/CGObjCGNU.cpp	(working copy)
@@ -2315,9 +2315,8 @@
 
   // The path to the source file where this module was declared
   SourceManager &SM = CGM.getContext().getSourceManager();
-  const FileEntry *mainFile = SM.getFileEntryForID(SM.getMainFileID());
-  std::string path =
-    std::string(mainFile->getDir()->getName()) + '/' + mainFile->getName();
+  const FileName *mainFile = SM.getFileNameForID(SM.getMainFileID());
+  std::string path = mainFile->getName();
   Elements.push_back(MakeConstantString(path, ".objc_source_file_name"));
   Elements.push_back(SymTab);
 
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp	(revision 159287)
+++ lib/CodeGen/CGDebugInfo.cpp	(working copy)
@@ -289,7 +289,7 @@
   // a relative path, so we look into the actual file entry for the main
   // file to determine the real absolute path for the file.
   std::string MainFileDir;
-  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
+  if (const FileName *MainFile = SM.getFileNameForID(SM.getMainFileID())) {
     MainFileDir = MainFile->getDir()->getName();
     if (MainFileDir != ".")
       MainFileName = MainFileDir + "/" + MainFileName;
Index: lib/Tooling/Refactoring.cpp
===================================================================
--- lib/Tooling/Refactoring.cpp	(revision 159287)
+++ lib/Tooling/Refactoring.cpp	(working copy)
@@ -49,15 +49,15 @@
 
 bool Replacement::apply(Rewriter &Rewrite) const {
   SourceManager &SM = Rewrite.getSourceMgr();
-  const FileEntry *Entry = SM.getFileManager().getFile(FilePath);
-  if (Entry == NULL)
+  const FileName *Name = SM.getFileManager().getFile(FilePath);
+  if (Name == NULL)
     return false;
   FileID ID;
   // FIXME: Use SM.translateFile directly.
-  SourceLocation Location = SM.translateFileLineCol(Entry, 1, 1);
+  SourceLocation Location = SM.translateFileLineCol(Name->getEntry(), 1, 1);
   ID = Location.isValid() ?
     SM.getFileID(Location) :
-    SM.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+    SM.createFileID(Name, SourceLocation(), SrcMgr::C_User);
   // FIXME: We cannot check whether Offset + Length is in the file, as
   // the remapping API is not public in the RewriteBuffer.
   const SourceLocation Start =
Index: lib/Tooling/Tooling.cpp
===================================================================
--- lib/Tooling/Tooling.cpp	(revision 159287)
+++ lib/Tooling/Tooling.cpp	(working copy)
@@ -231,9 +231,9 @@
     const llvm::MemoryBuffer *Input =
         llvm::MemoryBuffer::getMemBuffer(It->getValue());
     // FIXME: figure out what '0' stands for.
-    const FileEntry *FromFile = Files->getVirtualFile(
+    const FileName *FromFile = Files->getVirtualFile(
         It->getKey(), Input->getBufferSize(), 0);
-    Sources.overrideFileContents(FromFile, Input);
+    Sources.overrideFileContents(FromFile->getEntry(), Input);
   }
 }
 
Index: lib/Serialization/ModuleManager.cpp
===================================================================
--- lib/Serialization/ModuleManager.cpp	(revision 159287)
+++ lib/Serialization/ModuleManager.cpp	(working copy)
@@ -24,27 +24,27 @@
 using namespace serialization;
 
 ModuleFile *ModuleManager::lookup(StringRef Name) {
-  const FileEntry *Entry = FileMgr.getFile(Name);
-  return Modules[Entry];
+  const FileName *File = FileMgr.getFile(Name);
+  return File ? Modules[File->getEntry()] : 0;
 }
 
 llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
-  const FileEntry *Entry = FileMgr.getFile(Name);
-  return InMemoryBuffers[Entry];
+  const FileName *File = FileMgr.getFile(Name);
+  return File ? InMemoryBuffers[File->getEntry()] : 0;
 }
 
 std::pair<ModuleFile *, bool>
 ModuleManager::addModule(StringRef FileName, ModuleKind Type, 
                          ModuleFile *ImportedBy, unsigned Generation,
                          std::string &ErrorStr) {
-  const FileEntry *Entry = FileMgr.getFile(FileName);
+  const clang::FileName *Entry = FileMgr.getFile(FileName);
   if (!Entry && FileName != "-") {
     ErrorStr = "file not found";
     return std::make_pair(static_cast<ModuleFile*>(0), false);
   }
   
   // Check whether we already loaded this module, before 
-  ModuleFile *&ModuleEntry = Modules[Entry];
+  ModuleFile *&ModuleEntry = Modules[Entry->getEntry()];
   bool NewModule = false;
   if (!ModuleEntry) {
     // Allocate a new module.
@@ -90,9 +90,9 @@
 void ModuleManager::addInMemoryBuffer(StringRef FileName, 
                                       llvm::MemoryBuffer *Buffer) {
   
-  const FileEntry *Entry = FileMgr.getVirtualFile(FileName, 
-                                                  Buffer->getBufferSize(), 0);
-  InMemoryBuffers[Entry] = Buffer;
+  const clang::FileName *File =
+      FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0);
+  InMemoryBuffers[File->getEntry()] = Buffer;
 }
 
 ModuleManager::ModuleManager(const FileSystemOptions &FSO) : FileMgr(FSO) { }
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp	(revision 159287)
+++ lib/Serialization/ASTWriter.cpp	(working copy)
@@ -1985,7 +1985,7 @@
     }
 
     // Emit the umbrella header, if there is one.
-    if (const FileEntry *UmbrellaHeader = Mod->getUmbrellaHeader()) {
+    if (const FileName *UmbrellaHeader = Mod->getUmbrellaHeader()) {
       Record.clear();
       Record.push_back(SUBMODULE_UMBRELLA_HEADER);
       Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, 
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp	(revision 159287)
+++ lib/Serialization/ASTReader.cpp	(working copy)
@@ -1086,7 +1086,7 @@
     std::string OrigFilename(BlobStart, BlobStart + BlobLen);
     std::string Filename = OrigFilename;
     MaybeAddSystemRootToFilename(Filename);
-    const FileEntry *File = 
+    const FileName *File =
       OverriddenBuffer? FileMgr.getVirtualFile(Filename, (off_t)Record[4],
                                                (time_t)Record[5])
                       : FileMgr.getFile(Filename, /*OpenFile=*/false);
@@ -1110,12 +1110,12 @@
     }
 
     if (!DisableValidation &&
-        ((off_t)Record[4] != File->getSize()
+        ((off_t)Record[4] != File->getEntry()->getSize()
 #if !defined(LLVM_ON_WIN32)
         // In our regression testing, the Windows file system seems to
         // have inconsistent modification times that sometimes
         // erroneously trigger this error-handling path.
-         || (time_t)Record[5] != File->getModificationTime()
+         || (time_t)Record[5] != File->getEntry()->getModificationTime()
 #endif
         )) {
       Error(diag::err_fe_pch_file_modified, Filename);
@@ -1145,7 +1145,7 @@
     }
     
     const SrcMgr::ContentCache *ContentCache
-      = SourceMgr.getOrCreateContentCache(File);
+      = SourceMgr.getOrCreateContentCache(File->getEntry());
     if (OverriddenBuffer && !ContentCache->BufferOverridden &&
         ContentCache->ContentsEntry == ContentCache->OrigEntry) {
       unsigned Code = SLocEntryCursor.ReadCode();
@@ -1161,7 +1161,7 @@
       llvm::MemoryBuffer *Buffer
         = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),
                                            Filename);
-      SourceMgr.overrideFileContents(File, Buffer);
+      SourceMgr.overrideFileContents(File->getEntry(), Buffer);
     }
 
     if (Result == Failure)
@@ -1603,7 +1603,7 @@
 const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
   std::string Filename = filenameStrRef;
   MaybeAddSystemRootToFilename(Filename);
-  const FileEntry *File = FileMgr.getFile(Filename);
+  const FileName *File = FileMgr.getFile(Filename);
   if (File == 0 && !OriginalDir.empty() && !CurrentDir.empty() &&
       OriginalDir != CurrentDir) {
     std::string resolved = resolveFileRelativeToOriginalDir(Filename,
@@ -1613,7 +1613,7 @@
       File = FileMgr.getFile(resolved);
   }
 
-  return File;
+  return File ? File->getEntry() : 0;
 }
 
 /// \brief If we are loading a relocatable PCH file, and the filename is
@@ -3179,11 +3179,13 @@
       if (!CurrentModule)
         break;
       
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *Umbrella = PP.getFileManager().getFile(FileName)) {
+      StringRef Filename(BlobStart, BlobLen);
+      if (const clang::FileName *Umbrella =
+              PP.getFileManager().getFile(Filename)) {
         if (!CurrentModule->getUmbrellaHeader())
           ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
         else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
+          // FIXME: Should this be comparing by name or by entry?
           Error("mismatched umbrella headers in submodule");
           return Failure;
         }
@@ -3201,8 +3203,8 @@
         break;
       
       // FIXME: Be more lazy about this!
-      StringRef FileName(BlobStart, BlobLen);
-      if (const FileEntry *File = PP.getFileManager().getFile(FileName)) {
+      StringRef Filename(BlobStart, BlobLen);
+      if (const FileName *File = PP.getFileManager().getFile(Filename)) {
         if (std::find(CurrentModule->Headers.begin(), 
                       CurrentModule->Headers.end(), 
                       File) == CurrentModule->Headers.end())
@@ -3443,7 +3445,7 @@
   case PPD_INCLUSION_DIRECTIVE: {
     const char *FullFileNameStart = BlobStart + Record[0];
     StringRef FullFileName(FullFileNameStart, BlobLen - Record[0]);
-    const FileEntry *File = 0;
+    const FileName *File = 0;
     if (!FullFileName.empty())
       File = PP.getFileManager().getFile(FullFileName);
     
@@ -3454,7 +3456,7 @@
       = new (PPRec) InclusionDirective(PPRec, Kind,
                                        StringRef(BlobStart, Record[0]),
                                        Record[1],
-                                       File,
+                                       File->getEntry(),
                                        Range);
     return ID;
   }
Index: lib/ARCMigrate/FileRemapper.cpp
===================================================================
--- lib/ARCMigrate/FileRemapper.cpp	(revision 159287)
+++ lib/ARCMigrate/FileRemapper.cpp	(working copy)
@@ -82,26 +82,26 @@
                     Diag);
     StringRef toFilename = lines[idx+2];
     
-    const FileEntry *origFE = FileMgr->getFile(fromFilename);
-    if (!origFE) {
+    const FileName *origFN = FileMgr->getFile(fromFilename);
+    if (!origFN) {
       if (ignoreIfFilesChanged)
         continue;
       return report("File does not exist: " + fromFilename, Diag);
     }
-    const FileEntry *newFE = FileMgr->getFile(toFilename);
-    if (!newFE) {
+    const FileName *newFN = FileMgr->getFile(toFilename);
+    if (!newFN) {
       if (ignoreIfFilesChanged)
         continue;
       return report("File does not exist: " + toFilename, Diag);
     }
 
-    if ((uint64_t)origFE->getModificationTime() != timeModified) {
+    if ((uint64_t)origFN->getEntry()->getModificationTime() != timeModified) {
       if (ignoreIfFilesChanged)
         continue;
       return report("File was modified: " + fromFilename, Diag);
     }
 
-    pairs.push_back(std::make_pair(origFE, newFE));
+    pairs.push_back(std::make_pair(origFN->getEntry(), newFN->getEntry()));
   }
 
   for (unsigned i = 0, e = pairs.size(); i != e; ++i)
@@ -159,9 +159,9 @@
       newOut.write(mem->getBufferStart(), mem->getBufferSize());
       newOut.close();
       
-      const FileEntry *newE = FileMgr->getFile(tempPath);
-      remap(origFE, newE);
-      infoOut << newE->getName() << '\n';
+      const FileName *newN = FileMgr->getFile(tempPath);
+      remap(origFE, newN->getEntry());
+      infoOut << newN->getName() << '\n';
     }
   }
 
@@ -241,7 +241,7 @@
 
 void FileRemapper::remap(StringRef filePath, StringRef newPath) {
   const FileEntry *file = getOriginalFile(filePath);
-  const FileEntry *newfile = FileMgr->getFile(newPath);
+  const FileEntry *newfile = FileMgr->getFile(newPath)->getEntry();
   remap(file, newfile);
 }
 
@@ -261,7 +261,7 @@
 }
 
 const FileEntry *FileRemapper::getOriginalFile(StringRef filePath) {
-  const FileEntry *file = FileMgr->getFile(filePath);
+  const FileEntry *file = FileMgr->getFile(filePath)->getEntry();
   // If we are updating a file that overriden an original file,
   // actually update the original file.
   llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator


More information about the cfe-dev mailing list