harlanhaskins created this revision.
harlanhaskins added reviewers: arphaman, bruno.
Herald added subscribers: lldb-commits, cfe-commits, jsji, kadircet, 
dexonsmith, jkorous, MaskRay, kbarton, nemanjai.
Herald added a reviewer: martong.
Herald added a reviewer: shafik.
Herald added projects: clang, LLDB.
harlanhaskins edited the summary of this revision.
Herald added subscribers: wuzish, ormris, rnkovacs.

Currently, clang's FileManager uses NULL as an indicator that a particular file
did not exist, but would not propagate errors like permission issues. Instead,
teach FileManager to use llvm::ErrorOr internally and return rich errors for
failures.

This patch updates the existing API and updates the callers throughout clang.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D65534

Files:
  clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
  clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
  clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
  clang-tools-extra/clang-move/Move.cpp
  clang-tools-extra/clang-move/tool/ClangMove.cpp
  clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clangd/ClangdUnit.cpp
  clang-tools-extra/clangd/SourceCode.cpp
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/modularize/ModularizeUtilities.cpp
  clang/include/clang/Basic/FileManager.h
  clang/lib/ARCMigrate/FileRemapper.cpp
  clang/lib/ARCMigrate/ObjCMT.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/Basic/FileManager.cpp
  clang/lib/Basic/Module.cpp
  clang/lib/Basic/SourceManager.cpp
  clang/lib/CodeGen/CodeGenAction.cpp
  clang/lib/Frontend/ASTUnit.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Frontend/FrontendAction.cpp
  clang/lib/Frontend/InitHeaderSearch.cpp
  clang/lib/Frontend/PrecompiledPreamble.cpp
  clang/lib/Frontend/Rewrite/FrontendActions.cpp
  clang/lib/Frontend/TextDiagnostic.cpp
  clang/lib/Lex/HeaderMap.cpp
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/GlobalModuleIndex.cpp
  clang/lib/Serialization/ModuleManager.cpp
  clang/lib/Tooling/Core/Replacement.cpp
  clang/lib/Tooling/Refactoring.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/tools/clang-import-test/clang-import-test.cpp
  clang/tools/clang-refactor/ClangRefactor.cpp
  clang/tools/clang-refactor/TestSupport.cpp
  clang/tools/clang-rename/ClangRename.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/Indexing.cpp
  clang/unittests/Basic/FileManagerTest.cpp
  clang/unittests/Lex/HeaderSearchTest.cpp
  clang/unittests/Lex/PPCallbacksTest.cpp
  clang/unittests/Tooling/RefactoringTest.cpp
  clang/unittests/Tooling/RewriterTestContext.h
  lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
  lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp

Index: lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -247,11 +247,11 @@
 
       bool is_system = true;
       bool is_framework = false;
-      auto *dir =
+      auto dir =
           HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
       if (!dir)
         return error();
-      auto *file = HS.lookupModuleMapFile(dir, is_framework);
+      auto *file = HS.lookupModuleMapFile(*dir, is_framework);
       if (!file)
         return error();
       if (!HS.loadModuleMapFile(file, is_system))
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -908,10 +908,13 @@
       if (file.Write(expr_text, bytes_written).Success()) {
         if (bytes_written == expr_text_len) {
           file.Close();
-          source_mgr.setMainFileID(source_mgr.createFileID(
-              m_compiler->getFileManager().getFile(result_path),
-              SourceLocation(), SrcMgr::C_User));
-          created_main_file = true;
+          if (auto fileEntry =
+                  m_compiler->getFileManager().getFile(result_path)) {
+            source_mgr.setMainFileID(source_mgr.createFileID(
+                *fileEntry,
+                SourceLocation(), SrcMgr::C_User));
+            created_main_file = true;
+          }
         }
       }
     }
Index: clang/unittests/Tooling/RewriterTestContext.h
===================================================================
--- clang/unittests/Tooling/RewriterTestContext.h
+++ clang/unittests/Tooling/RewriterTestContext.h
@@ -56,9 +56,9 @@
         llvm::MemoryBuffer::getMemBuffer(Content);
     InMemoryFileSystem->addFile(Name, 0, std::move(Source));
 
-    const FileEntry *Entry = Files.getFile(Name);
-    assert(Entry != nullptr);
-    return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+    auto Entry = Files.getFile(Name);
+    assert(Entry);
+    return Sources.createFileID(*Entry, SourceLocation(), SrcMgr::C_User);
   }
 
   // FIXME: this code is mostly a duplicate of
@@ -73,14 +73,14 @@
     llvm::raw_fd_ostream OutStream(FD, true);
     OutStream << Content;
     OutStream.close();
-    const FileEntry *File = Files.getFile(Path);
-    assert(File != nullptr);
+    auto File = Files.getFile(Path);
+    assert(File);
 
     StringRef Found =
         TemporaryFiles.insert(std::make_pair(Name, Path.str())).first->second;
     assert(Found == Path);
     (void)Found;
-    return Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
+    return Sources.createFileID(*File, SourceLocation(), SrcMgr::C_User);
   }
 
   SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) {
Index: clang/unittests/Tooling/RefactoringTest.cpp
===================================================================
--- clang/unittests/Tooling/RefactoringTest.cpp
+++ clang/unittests/Tooling/RefactoringTest.cpp
@@ -608,14 +608,15 @@
     llvm::raw_fd_ostream OutStream(FD, true);
     OutStream << Content;
     OutStream.close();
-    const FileEntry *File = Context.Files.getFile(Path);
-    assert(File != nullptr);
+    auto File = Context.Files.getFile(Path);
+    assert(File);
 
     StringRef Found =
         TemporaryFiles.insert(std::make_pair(Name, Path.str())).first->second;
     assert(Found == Path);
     (void)Found;
-    return Context.Sources.createFileID(File, SourceLocation(), SrcMgr::C_User);
+    return Context.Sources.createFileID(*File, SourceLocation(),
+                                        SrcMgr::C_User);
   }
 
   std::string getFileContentFromDisk(llvm::StringRef Name) {
Index: clang/unittests/Lex/PPCallbacksTest.cpp
===================================================================
--- clang/unittests/Lex/PPCallbacksTest.cpp
+++ clang/unittests/Lex/PPCallbacksTest.cpp
@@ -145,8 +145,8 @@
 
     // Add header's parent path to search path.
     StringRef SearchPath = llvm::sys::path::parent_path(HeaderPath);
-    const DirectoryEntry *DE = FileMgr.getDirectory(SearchPath);
-    DirectoryLookup DL(DE, SrcMgr::C_User, false);
+    auto DE = FileMgr.getDirectory(SearchPath);
+    DirectoryLookup DL(*DE, SrcMgr::C_User, false);
     HeaderInfo.AddSearchPath(DL, IsSystemHeader);
   }
 
Index: clang/unittests/Lex/HeaderSearchTest.cpp
===================================================================
--- clang/unittests/Lex/HeaderSearchTest.cpp
+++ clang/unittests/Lex/HeaderSearchTest.cpp
@@ -39,9 +39,9 @@
   void addSearchDir(llvm::StringRef Dir) {
     VFS->addFile(Dir, 0, llvm::MemoryBuffer::getMemBuffer(""), /*User=*/None,
                  /*Group=*/None, llvm::sys::fs::file_type::directory_file);
-    const DirectoryEntry *DE = FileMgr.getDirectory(Dir);
+    auto DE = FileMgr.getDirectory(Dir);
     assert(DE);
-    auto DL = DirectoryLookup(DE, SrcMgr::C_User, /*isFramework=*/false);
+    auto DL = DirectoryLookup(*DE, SrcMgr::C_User, /*isFramework=*/false);
     Search.AddSearchPath(DL, /*isAngled=*/false);
   }
 
Index: clang/unittests/Basic/FileManagerTest.cpp
===================================================================
--- clang/unittests/Basic/FileManagerTest.cpp
+++ clang/unittests/Basic/FileManagerTest.cpp
@@ -112,9 +112,9 @@
   // by what's in the real file system.
   manager.setStatCache(llvm::make_unique<FakeStatCache>());
 
-  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
-  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir"));
-  EXPECT_EQ(nullptr, manager.getDirectory("virtual"));
+  ASSERT_FALSE(manager.getDirectory("virtual/dir/foo"));
+  ASSERT_FALSE(manager.getDirectory("virtual/dir"));
+  ASSERT_FALSE(manager.getDirectory("virtual"));
 }
 
 // When a virtual file is added, all of its ancestors should be created.
@@ -123,15 +123,15 @@
   manager.setStatCache(llvm::make_unique<FakeStatCache>());
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
-  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
+  ASSERT_FALSE(manager.getDirectory("virtual/dir/foo"));
 
-  const DirectoryEntry *dir = manager.getDirectory("virtual/dir");
-  ASSERT_TRUE(dir != nullptr);
-  EXPECT_EQ("virtual/dir", dir->getName());
+  auto dir = manager.getDirectory("virtual/dir");
+  ASSERT_TRUE(dir);
+  EXPECT_EQ("virtual/dir", (*dir)->getName());
 
   dir = manager.getDirectory("virtual");
-  ASSERT_TRUE(dir != nullptr);
-  EXPECT_EQ("virtual", dir->getName());
+  ASSERT_TRUE(dir);
+  EXPECT_EQ("virtual", (*dir)->getName());
 }
 
 // getFile() returns non-NULL if a real file exists at the given path.
@@ -150,18 +150,18 @@
 
   manager.setStatCache(std::move(statCache));
 
-  const FileEntry *file = manager.getFile("/tmp/test");
-  ASSERT_TRUE(file != nullptr);
-  ASSERT_TRUE(file->isValid());
-  EXPECT_EQ("/tmp/test", file->getName());
+  auto file = manager.getFile("/tmp/test");
+  ASSERT_TRUE(file);
+  ASSERT_TRUE((*file)->isValid());
+  EXPECT_EQ("/tmp/test", (*file)->getName());
 
-  const DirectoryEntry *dir = file->getDir();
+  const DirectoryEntry *dir = (*file)->getDir();
   ASSERT_TRUE(dir != nullptr);
   EXPECT_EQ("/tmp", dir->getName());
 
 #ifdef _WIN32
   file = manager.getFile(FileName);
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file);
 
   dir = file->getDir();
   ASSERT_TRUE(dir != NULL);
@@ -175,12 +175,12 @@
   manager.setStatCache(llvm::make_unique<FakeStatCache>());
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
-  const FileEntry *file = manager.getFile("virtual/dir/bar.h");
-  ASSERT_TRUE(file != nullptr);
-  ASSERT_TRUE(file->isValid());
-  EXPECT_EQ("virtual/dir/bar.h", file->getName());
+  auto file = manager.getFile("virtual/dir/bar.h");
+  ASSERT_TRUE(file);
+  ASSERT_TRUE((*file)->isValid());
+  EXPECT_EQ("virtual/dir/bar.h", (*file)->getName());
 
-  const DirectoryEntry *dir = file->getDir();
+  const DirectoryEntry *dir = (*file)->getDir();
   ASSERT_TRUE(dir != nullptr);
   EXPECT_EQ("virtual/dir", dir->getName());
 }
@@ -196,13 +196,13 @@
   statCache->InjectFile("bar.cpp", 43);
   manager.setStatCache(std::move(statCache));
 
-  const FileEntry *fileFoo = manager.getFile("foo.cpp");
-  const FileEntry *fileBar = manager.getFile("bar.cpp");
-  ASSERT_TRUE(fileFoo != nullptr);
-  ASSERT_TRUE(fileFoo->isValid());
-  ASSERT_TRUE(fileBar != nullptr);
-  ASSERT_TRUE(fileBar->isValid());
-  EXPECT_NE(fileFoo, fileBar);
+  auto fileFoo = manager.getFile("foo.cpp");
+  auto fileBar = manager.getFile("bar.cpp");
+  ASSERT_TRUE(fileFoo);
+  ASSERT_TRUE((*fileFoo)->isValid());
+  ASSERT_TRUE(fileBar);
+  ASSERT_TRUE((*fileBar)->isValid());
+  EXPECT_NE(*fileFoo, *fileBar);
 }
 
 // getFile() returns NULL if neither a real file nor a virtual file
@@ -217,8 +217,8 @@
   // Create a virtual bar.cpp file.
   manager.getVirtualFile("bar.cpp", 200, 0);
 
-  const FileEntry *file = manager.getFile("xyz.txt");
-  EXPECT_EQ(nullptr, file);
+  auto file = manager.getFile("xyz.txt");
+  ASSERT_FALSE(file);
 }
 
 // The following tests apply to Unix-like system only.
@@ -234,7 +234,11 @@
   statCache->InjectFile("abc/bar.cpp", 42);
   manager.setStatCache(std::move(statCache));
 
-  EXPECT_EQ(manager.getFile("abc/foo.cpp"), manager.getFile("abc/bar.cpp"));
+  auto f1 = manager.getFile("abc/foo.cpp");
+  auto f2 = manager.getFile("abc/bar.cpp");
+
+  EXPECT_EQ(f1 ? *f1 : nullptr,
+            f2 ? *f2 : nullptr);
 }
 
 // getFile() returns the same FileEntry for virtual files that have
@@ -250,7 +254,11 @@
   ASSERT_TRUE(manager.getVirtualFile("abc/foo.cpp", 100, 0)->isValid());
   ASSERT_TRUE(manager.getVirtualFile("abc/bar.cpp", 200, 0)->isValid());
 
-  EXPECT_EQ(manager.getFile("abc/foo.cpp"), manager.getFile("abc/bar.cpp"));
+  auto f1 = manager.getFile("abc/foo.cpp");
+  auto f2 = manager.getFile("abc/bar.cpp");
+
+  EXPECT_EQ(f1 ? *f1 : nullptr,
+            f2 ? *f2 : nullptr);
 }
 
 // getFile() Should return the same entry as getVirtualFile if the file actually
@@ -273,15 +281,15 @@
   EXPECT_EQ(123, file1->getSize());
 
   // Lookup the virtual file with a different name:
-  const FileEntry *file2 = manager.getFile("c:/tmp/test", 100, 1);
-  ASSERT_TRUE(file2 != nullptr);
-  ASSERT_TRUE(file2->isValid());
+  auto file2 = manager.getFile("c:/tmp/test", 100, 1);
+  ASSERT_TRUE(file2);
+  ASSERT_TRUE((*file2)->isValid());
   // Check that it's the same UFE:
-  EXPECT_EQ(file1, file2);
-  EXPECT_EQ(43U, file2->getUniqueID().getFile());
+  EXPECT_EQ(file1, *file2);
+  EXPECT_EQ(43U, (*file2)->getUniqueID().getFile());
   // Check that the contents of the UFE are not overwritten by the entry in the
   // filesystem:
-  EXPECT_EQ(123, file2->getSize());
+  EXPECT_EQ(123, (*file2)->getSize());
 }
 
 #endif  // !_WIN32
@@ -370,13 +378,13 @@
   Manager.setStatCache(std::move(statCache));
 
   // Check for real path.
-  const FileEntry *file = Manager.getFile("/tmp/test", /*OpenFile=*/false);
-  ASSERT_TRUE(file != nullptr);
-  ASSERT_TRUE(file->isValid());
+  auto file = Manager.getFile("/tmp/test", /*OpenFile=*/false);
+  ASSERT_TRUE(file);
+  ASSERT_TRUE((*file)->isValid());
   SmallString<64> ExpectedResult = CustomWorkingDir;
 
   llvm::sys::path::append(ExpectedResult, "tmp", "test");
-  EXPECT_EQ(file->tryGetRealPathName(), ExpectedResult);
+  EXPECT_EQ((*file)->tryGetRealPathName(), ExpectedResult);
 }
 
 } // anonymous namespace
Index: clang/tools/libclang/Indexing.cpp
===================================================================
--- clang/tools/libclang/Indexing.cpp
+++ clang/tools/libclang/Indexing.cpp
@@ -363,8 +363,9 @@
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
 
     if (!PPOpts.ImplicitPCHInclude.empty()) {
-      DataConsumer->importedPCH(
-                        CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
+      auto File = CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude);
+      if (File)
+        DataConsumer->importedPCH(*File);
     }
 
     DataConsumer->setASTContext(CI.getASTContext());
@@ -677,9 +678,10 @@
 
   if (Unit->getOriginalSourceFileName().empty())
     DataConsumer.enteredMainFile(nullptr);
+  else if (auto MainFile = FileMgr.getFile(Unit->getOriginalSourceFileName()))
+    DataConsumer.enteredMainFile(*MainFile);
   else
-    DataConsumer.enteredMainFile(
-        FileMgr.getFile(Unit->getOriginalSourceFileName()));
+    DataConsumer.enteredMainFile(nullptr);
 
   DataConsumer.setASTContext(Unit->getASTContext());
   DataConsumer.startedTranslationUnit();
Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -4232,7 +4232,10 @@
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
 
   FileManager &FMgr = CXXUnit->getFileManager();
-  return const_cast<FileEntry *>(FMgr.getFile(file_name));
+  auto File = FMgr.getFile(file_name);
+  if (!File)
+    return nullptr;
+  return const_cast<FileEntry *>(*File);
 }
 
 const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
Index: clang/tools/clang-rename/ClangRename.cpp
===================================================================
--- clang/tools/clang-rename/ClangRename.cpp
+++ clang/tools/clang-rename/ClangRename.cpp
@@ -222,8 +222,8 @@
 
     Tool.applyAllReplacements(Rewrite);
     for (const auto &File : Files) {
-      const auto *Entry = FileMgr.getFile(File);
-      const auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User);
+      auto Entry = FileMgr.getFile(File);
+      const auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
       Rewrite.getEditBuffer(ID).write(outs());
     }
   }
Index: clang/tools/clang-refactor/TestSupport.cpp
===================================================================
--- clang/tools/clang-refactor/TestSupport.cpp
+++ clang/tools/clang-refactor/TestSupport.cpp
@@ -41,8 +41,8 @@
 bool TestSelectionRangesInFile::foreachRange(
     const SourceManager &SM,
     llvm::function_ref<void(SourceRange)> Callback) const {
-  const FileEntry *FE = SM.getFileManager().getFile(Filename);
-  FileID FID = FE ? SM.translateFile(FE) : FileID();
+  auto FE = SM.getFileManager().getFile(Filename);
+  FileID FID = FE ? SM.translateFile(*FE) : FileID();
   if (!FE || FID.isInvalid()) {
     llvm::errs() << "error: -selection=test:" << Filename
                  << " : given file is not in the target TU";
Index: clang/tools/clang-refactor/ClangRefactor.cpp
===================================================================
--- clang/tools/clang-refactor/ClangRefactor.cpp
+++ clang/tools/clang-refactor/ClangRefactor.cpp
@@ -116,8 +116,8 @@
 
   bool forAllRanges(const SourceManager &SM,
                     llvm::function_ref<void(SourceRange R)> Callback) override {
-    const FileEntry *FE = SM.getFileManager().getFile(Range.FileName);
-    FileID FID = FE ? SM.translateFile(FE) : FileID();
+    auto FE = SM.getFileManager().getFile(Range.FileName);
+    FileID FID = FE ? SM.translateFile(*FE) : FileID();
     if (!FE || FID.isInvalid()) {
       llvm::errs() << "error: -selection=" << Range.FileName
                    << ":... : given file is not in the target TU\n";
Index: clang/tools/clang-import-test/clang-import-test.cpp
===================================================================
--- clang/tools/clang-import-test/clang-import-test.cpp
+++ clang/tools/clang-import-test/clang-import-test.cpp
@@ -286,12 +286,12 @@
 llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI,
                         ASTConsumer &Consumer) {
   SourceManager &SM = CI.getSourceManager();
-  const FileEntry *FE = CI.getFileManager().getFile(Path);
+  auto FE = CI.getFileManager().getFile(Path);
   if (!FE) {
     return llvm::make_error<llvm::StringError>(
         llvm::Twine("Couldn't open ", Path), std::error_code());
   }
-  SM.setMainFileID(SM.createFileID(FE, SourceLocation(), SrcMgr::C_User));
+  SM.setMainFileID(SM.createFileID(*FE, SourceLocation(), SrcMgr::C_User));
   ParseAST(CI.getPreprocessor(), &Consumer, CI.getASTContext());
   return llvm::Error::success();
 }
Index: clang/tools/clang-format/ClangFormat.cpp
===================================================================
--- clang/tools/clang-format/ClangFormat.cpp
+++ clang/tools/clang-format/ClangFormat.cpp
@@ -117,7 +117,8 @@
                                  SourceManager &Sources, FileManager &Files,
                                  llvm::vfs::InMemoryFileSystem *MemFS) {
   MemFS->addFileNoOwn(FileName, 0, Source);
-  return Sources.createFileID(Files.getFile(FileName), SourceLocation(),
+  auto File = Files.getFile(FileName);
+  return Sources.createFileID(File ? *File : nullptr, SourceLocation(),
                               SrcMgr::C_User);
 }
 
Index: clang/lib/Tooling/Refactoring.cpp
===================================================================
--- clang/lib/Tooling/Refactoring.cpp
+++ clang/lib/Tooling/Refactoring.cpp
@@ -78,7 +78,10 @@
     const std::string &FilePath = FileAndReplaces.first;
     auto &CurReplaces = FileAndReplaces.second;
 
-    const FileEntry *Entry = Files.getFile(FilePath);
+    const FileEntry *Entry = nullptr;
+    if (auto File = Files.getFile(FilePath))
+      Entry = *File;
+
     FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User);
     StringRef Code = SM.getBufferData(ID);
 
Index: clang/lib/Tooling/Core/Replacement.cpp
===================================================================
--- clang/lib/Tooling/Core/Replacement.cpp
+++ clang/lib/Tooling/Core/Replacement.cpp
@@ -67,11 +67,11 @@
 
 bool Replacement::apply(Rewriter &Rewrite) const {
   SourceManager &SM = Rewrite.getSourceMgr();
-  const FileEntry *Entry = SM.getFileManager().getFile(FilePath);
+  auto Entry = SM.getFileManager().getFile(FilePath);
   if (!Entry)
     return false;
 
-  FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User);
+  FileID ID = SM.getOrCreateFileID(*Entry, SrcMgr::C_User);
   const SourceLocation Start =
     SM.getLocForStartOfFile(ID).
     getLocWithOffset(ReplacementRange.getOffset());
@@ -591,7 +591,8 @@
   Rewriter Rewrite(SourceMgr, LangOptions());
   InMemoryFileSystem->addFile(
       "<stdin>", 0, llvm::MemoryBuffer::getMemBuffer(Code, "<stdin>"));
-  FileID ID = SourceMgr.createFileID(Files.getFile("<stdin>"), SourceLocation(),
+  FileID ID = SourceMgr.createFileID(*Files.getFile("<stdin>"),
+                                     SourceLocation(),
                                      clang::SrcMgr::C_User);
   for (auto I = Replaces.rbegin(), E = Replaces.rend(); I != E; ++I) {
     Replacement Replace("<stdin>", I->getOffset(), I->getLength(),
@@ -613,10 +614,10 @@
   std::map<std::string, Replacements> Result;
   llvm::SmallPtrSet<const FileEntry *, 16> ProcessedFileEntries;
   for (const auto &Entry : FileToReplaces) {
-    const FileEntry *FE = FileMgr.getFile(Entry.first);
+    auto FE = FileMgr.getFile(Entry.first);
     if (!FE)
       llvm::errs() << "File path " << Entry.first << " is invalid.\n";
-    else if (ProcessedFileEntries.insert(FE).second)
+    else if (ProcessedFileEntries.insert(*FE).second)
       Result[Entry.first] = std::move(Entry.second);
   }
   return Result;
Index: clang/lib/Serialization/ModuleManager.cpp
===================================================================
--- clang/lib/Serialization/ModuleManager.cpp
+++ clang/lib/Serialization/ModuleManager.cpp
@@ -42,10 +42,10 @@
 using namespace serialization;
 
 ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
-  const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
-                                           /*CacheFailure=*/false);
+  auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
+                               /*CacheFailure=*/false);
   if (Entry)
-    return lookup(Entry);
+    return lookup(*Entry);
 
   return nullptr;
 }
@@ -68,9 +68,11 @@
 
 std::unique_ptr<llvm::MemoryBuffer>
 ModuleManager::lookupBuffer(StringRef Name) {
-  const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
-                                           /*CacheFailure=*/false);
-  return std::move(InMemoryBuffers[Entry]);
+  auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
+                               /*CacheFailure=*/false);
+  if (!Entry)
+    return nullptr;
+  return std::move(InMemoryBuffers[*Entry]);
 }
 
 static bool checkSignature(ASTFileSignature Signature,
@@ -447,9 +449,13 @@
 
   // Open the file immediately to ensure there is no race between stat'ing and
   // opening the file.
-  File = FileMgr.getFile(FileName, /*OpenFile=*/true, /*CacheFailure=*/false);
-  if (!File)
+  auto FileOrErr = FileMgr.getFile(FileName, /*OpenFile=*/true, 
+                                   /*CacheFailure=*/false);
+  if (!FileOrErr) {
+    File = nullptr;
     return false;
+  }
+  File = *FileOrErr;
 
   if ((ExpectedSize && ExpectedSize != File->getSize()) ||
       (ExpectedModTime && ExpectedModTime != File->getModificationTime()))
Index: clang/lib/Serialization/GlobalModuleIndex.cpp
===================================================================
--- clang/lib/Serialization/GlobalModuleIndex.cpp
+++ clang/lib/Serialization/GlobalModuleIndex.cpp
@@ -657,7 +657,7 @@
         Idx += Length;
 
         // Find the imported module file.
-        const FileEntry *DependsOnFile
+        auto DependsOnFile
           = FileMgr.getFile(ImportedFile, /*OpenFile=*/false,
                             /*CacheFailure=*/false);
 
@@ -669,11 +669,11 @@
         // Save the information in ImportedModuleFileInfo so we can verify after
         // loading all pcms.
         ImportedModuleFiles.insert(std::make_pair(
-            DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
-                                                  StoredSignature)));
+            *DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
+                                                   StoredSignature)));
 
         // Record the dependency.
-        unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
+        unsigned DependsOnID = getModuleFileInfo(*DependsOnFile).ID;
         getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
       }
 
@@ -894,12 +894,12 @@
     }
 
     // If we can't find the module file, skip it.
-    const FileEntry *ModuleFile = FileMgr.getFile(D->path());
+    auto ModuleFile = FileMgr.getFile(D->path());
     if (!ModuleFile)
       continue;
 
     // Load this module file.
-    if (llvm::Error Err = Builder.loadModuleFile(ModuleFile))
+    if (llvm::Error Err = Builder.loadModuleFile(*ModuleFile))
       return Err;
   }
 
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1822,12 +1822,17 @@
   // Determine whether the actual files are equivalent.
   FileManager &FileMgr = Reader.getFileManager();
   auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* {
-    if (!Key.Imported)
-      return FileMgr.getFile(Key.Filename);
+    if (!Key.Imported) {
+      if (auto File = FileMgr.getFile(Key.Filename))
+        return *File;
+      return nullptr;
+    }
 
     std::string Resolved = Key.Filename;
     Reader.ResolveImportedPath(M, Resolved);
-    return FileMgr.getFile(Resolved);
+    if (auto File = FileMgr.getFile(Resolved))
+      return *File;
+    return nullptr;
   };
 
   const FileEntry *FEA = GetFile(a);
@@ -1904,7 +1909,7 @@
     // FIXME: This is not always the right filename-as-written, but we're not
     // going to use this information to rebuild the module, so it doesn't make
     // a lot of difference.
-    Module::Header H = { key.Filename, FileMgr.getFile(Filename) };
+    Module::Header H = { key.Filename, *FileMgr.getFile(Filename) };
     ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
     HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
   }
@@ -2266,7 +2271,10 @@
   bool Transient = FI.Transient;
   StringRef Filename = FI.Filename;
 
-  const FileEntry *File = FileMgr.getFile(Filename, /*OpenFile=*/false);
+  const FileEntry *File = nullptr;
+  if (auto FE = FileMgr.getFile(Filename, /*OpenFile=*/false))
+    File = *FE;
+
   // If we didn't find the file, resolve it relative to the
   // original directory from which this AST file was created.
   if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() &&
@@ -2274,7 +2282,8 @@
     std::string Resolved = resolveFileRelativeToOriginalDir(
         Filename, F.OriginalDir, F.BaseDirectory);
     if (!Resolved.empty())
-      File = FileMgr.getFile(Resolved);
+      if (auto FE = FileMgr.getFile(Resolved))
+        File = *FE;
   }
 
   // For an overridden file, create a virtual file with the stored
@@ -2820,9 +2829,8 @@
         // Don't emit module relocation error if we have -fno-validate-pch
         if (!PP.getPreprocessorOpts().DisablePCHValidation &&
             F.Kind != MK_ExplicitModule && F.Kind != MK_PrebuiltModule) {
-          const DirectoryEntry *BuildDir =
-              PP.getFileManager().getDirectory(Blob);
-          if (!BuildDir || BuildDir != M->Directory) {
+          auto BuildDir = PP.getFileManager().getDirectory(Blob);
+          if (!BuildDir || *BuildDir != M->Directory) {
             if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
               Diag(diag::err_imported_module_relocated)
                   << F.ModuleName << Blob << M->Directory->getName();
@@ -3839,8 +3847,8 @@
     assert(M->Name == F.ModuleName && "found module with different name");
 
     // Check the primary module map file.
-    const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
-    if (StoredModMap == nullptr || StoredModMap != ModMap) {
+    auto StoredModMap = FileMgr.getFile(F.ModuleMapPath);
+    if (!StoredModMap || *StoredModMap != ModMap) {
       assert(ModMap && "found module is missing module map file");
       assert(ImportedBy && "top-level import should be verified");
       if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
@@ -3854,14 +3862,13 @@
     for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) {
       // FIXME: we should use input files rather than storing names.
       std::string Filename = ReadPath(F, Record, Idx);
-      const FileEntry *F =
-          FileMgr.getFile(Filename, false, false);
-      if (F == nullptr) {
+      auto F = FileMgr.getFile(Filename, false, false);
+      if (!F) {
         if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
           Error("could not find file '" + Filename +"' referenced by AST file");
         return OutOfDate;
       }
-      AdditionalStoredMaps.insert(F);
+      AdditionalStoredMaps.insert(*F);
     }
 
     // Check any additional module map files (e.g. module.private.modulemap)
@@ -5459,10 +5466,10 @@
     case SUBMODULE_UMBRELLA_HEADER: {
       std::string Filename = Blob;
       ResolveImportedPath(F, Filename);
-      if (auto *Umbrella = PP.getFileManager().getFile(Filename)) {
+      if (auto Umbrella = PP.getFileManager().getFile(Filename)) {
         if (!CurrentModule->getUmbrellaHeader())
-          ModMap.setUmbrellaHeader(CurrentModule, Umbrella, Blob);
-        else if (CurrentModule->getUmbrellaHeader().Entry != Umbrella) {
+          ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob);
+        else if (CurrentModule->getUmbrellaHeader().Entry != *Umbrella) {
           if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
             Error("mismatched umbrella headers in submodule");
           return OutOfDate;
@@ -5492,10 +5499,10 @@
     case SUBMODULE_UMBRELLA_DIR: {
       std::string Dirname = Blob;
       ResolveImportedPath(F, Dirname);
-      if (auto *Umbrella = PP.getFileManager().getDirectory(Dirname)) {
+      if (auto Umbrella = PP.getFileManager().getDirectory(Dirname)) {
         if (!CurrentModule->getUmbrellaDir())
-          ModMap.setUmbrellaDir(CurrentModule, Umbrella, Blob);
-        else if (CurrentModule->getUmbrellaDir().Entry != Umbrella) {
+          ModMap.setUmbrellaDir(CurrentModule, *Umbrella, Blob);
+        else if (CurrentModule->getUmbrellaDir().Entry != *Umbrella) {
           if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
             Error("mismatched umbrella directories in submodule");
           return OutOfDate;
@@ -5890,7 +5897,8 @@
     StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
     const FileEntry *File = nullptr;
     if (!FullFileName.empty())
-      File = PP.getFileManager().getFile(FullFileName);
+      if (auto FE = PP.getFileManager().getFile(FullFileName))
+        File = *FE;
 
     // FIXME: Stable encoding
     InclusionDirective::InclusionKind Kind
Index: clang/lib/Lex/PPLexerChange.cpp
===================================================================
--- clang/lib/Lex/PPLexerChange.cpp
+++ clang/lib/Lex/PPLexerChange.cpp
@@ -206,8 +206,8 @@
   StringRef FilePath = File->getDir()->getName();
   StringRef Path = FilePath;
   while (!Path.empty()) {
-    if (const DirectoryEntry *CurDir = FM.getDirectory(Path)) {
-      if (CurDir == Dir) {
+    if (auto CurDir = FM.getDirectory(Path)) {
+      if (*CurDir == Dir) {
         Result = FilePath.substr(Path.size());
         llvm::sys::path::append(Result,
                                 llvm::sys::path::filename(File->getName()));
@@ -287,12 +287,12 @@
              .Default(false))
       continue;
 
-    if (const FileEntry *Header = getFileManager().getFile(Entry->path()))
-      if (!getSourceManager().hasFileInfo(Header)) {
-        if (!ModMap.isHeaderInUnavailableModule(Header)) {
+    if (auto Header = getFileManager().getFile(Entry->path()))
+      if (!getSourceManager().hasFileInfo(*Header)) {
+        if (!ModMap.isHeaderInUnavailableModule(*Header)) {
           // Find the relative path that would access this header.
           SmallString<128> RelativePath;
-          computeRelativePath(FileMgr, Dir, Header, RelativePath);
+          computeRelativePath(FileMgr, Dir, *Header, RelativePath);
           Diag(StartLoc, diag::warn_uncovered_module_header)
               << Mod.getFullModuleName() << RelativePath;
         }
Index: clang/lib/Lex/PPDirectives.cpp
===================================================================
--- clang/lib/Lex/PPDirectives.cpp
+++ clang/lib/Lex/PPDirectives.cpp
@@ -715,7 +715,7 @@
         BuildSystemModule = getCurrentModule()->IsSystem;
       } else if ((FileEnt =
                     SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())))
-        Includers.push_back(std::make_pair(FileEnt, FileMgr.getDirectory(".")));
+        Includers.push_back(std::make_pair(FileEnt, *FileMgr.getDirectory(".")));
     } else {
       Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir()));
     }
@@ -1764,9 +1764,9 @@
       // Give the clients a chance to recover.
       SmallString<128> RecoveryPath;
       if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
-        if (const DirectoryEntry *DE = FileMgr.getDirectory(RecoveryPath)) {
+        if (auto DE = FileMgr.getDirectory(RecoveryPath)) {
           // Add the recovery path to the list of search paths.
-          DirectoryLookup DL(DE, SrcMgr::C_User, false);
+          DirectoryLookup DL(*DE, SrcMgr::C_User, false);
           HeaderInfo.AddSearchPath(DL, isAngled);
 
           // Try the lookup again, skipping the cache.
Index: clang/lib/Lex/ModuleMap.cpp
===================================================================
--- clang/lib/Lex/ModuleMap.cpp
+++ clang/lib/Lex/ModuleMap.cpp
@@ -179,12 +179,12 @@
   SmallString<128> FullPathName(Directory->getName());
 
   auto GetFile = [&](StringRef Filename) -> const FileEntry * {
-    auto *File = SourceMgr.getFileManager().getFile(Filename);
+    auto File = SourceMgr.getFileManager().getFile(Filename);
     if (!File ||
-        (Header.Size && File->getSize() != *Header.Size) ||
-        (Header.ModTime && File->getModificationTime() != *Header.ModTime))
+        (Header.Size && (*File)->getSize() != *Header.Size) ||
+        (Header.ModTime && (*File)->getModificationTime() != *Header.ModTime))
       return nullptr;
-    return File;
+    return *File;
   };
 
   auto GetFrameworkFile = [&]() -> const FileEntry * {
@@ -300,12 +300,12 @@
   // supplied by Clang. Find that builtin header.
   SmallString<128> Path;
   llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
-  auto *File = SourceMgr.getFileManager().getFile(Path);
+  auto File = SourceMgr.getFileManager().getFile(Path);
   if (!File)
     return false;
 
   auto Role = headerKindToRole(Header.Kind);
-  Module::Header H = {Path.str(), File};
+  Module::Header H = {Path.str(), *File};
   addHeader(Mod, H, Role);
   return true;
 }
@@ -430,7 +430,10 @@
       break;
 
     // Resolve the parent path to a directory entry.
-    Dir = SourceMgr.getFileManager().getDirectory(DirName);
+    if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
+      Dir = *DirEntry;
+    else
+      Dir = nullptr;
   } while (Dir);
   return {};
 }
@@ -755,7 +758,10 @@
       break;
 
     // Resolve the parent path to a directory entry.
-    Dir = SourceMgr.getFileManager().getDirectory(DirName);
+    if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
+      Dir = *DirEntry;
+    else
+      Dir = nullptr;
   } while (Dir);
 
   return false;
@@ -938,24 +944,24 @@
     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
       // Figure out the parent path.
       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
-      if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
+      if (auto ParentDir = FileMgr.getDirectory(Parent)) {
         // Check whether we have already looked into the parent directory
         // for a module map.
         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
-          inferred = InferredDirectories.find(ParentDir);
+          inferred = InferredDirectories.find(*ParentDir);
         if (inferred == InferredDirectories.end()) {
           // We haven't looked here before. Load a module map, if there is
           // one.
           bool IsFrameworkDir = Parent.endswith(".framework");
           if (const FileEntry *ModMapFile =
-                HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
-            parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
-            inferred = InferredDirectories.find(ParentDir);
+                HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
+            parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir);
+            inferred = InferredDirectories.find(*ParentDir);
           }
 
           if (inferred == InferredDirectories.end())
             inferred = InferredDirectories.insert(
-                         std::make_pair(ParentDir, InferredDirectory())).first;
+                         std::make_pair(*ParentDir, InferredDirectory())).first;
         }
 
         if (inferred->second.InferModules) {
@@ -986,7 +992,7 @@
   // Look for an umbrella header.
   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
   llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
-  const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
+  auto 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
@@ -1016,7 +1022,7 @@
   //
   // The "Headers/" component of the name is implied because this is
   // a framework module.
-  setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
+  setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h");
 
   // export *
   Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -1039,13 +1045,14 @@
     if (!StringRef(Dir->path()).endswith(".framework"))
       continue;
 
-    if (const DirectoryEntry *SubframeworkDir =
+    if (auto SubframeworkDir =
             FileMgr.getDirectory(Dir->path())) {
       // Note: as an egregious but useful hack, we use the real path here and
       // check whether it is actually a subdirectory of the parent directory.
       // This will not be the case if the 'subframework' is actually a symlink
       // out to a top-level framework.
-      StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
+      StringRef SubframeworkDirName =
+          FileMgr.getCanonicalName(*SubframeworkDir);
       bool FoundParent = false;
       do {
         // Get the parent directory name.
@@ -1054,9 +1061,11 @@
         if (SubframeworkDirName.empty())
           break;
 
-        if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
-          FoundParent = true;
-          break;
+        if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
+          if (*SubDir == FrameworkDir) {
+            FoundParent = true;
+            break;
+          }
         }
       } while (true);
 
@@ -1064,7 +1073,7 @@
         continue;
 
       // FIXME: Do we want to warn about subframeworks without umbrella headers?
-      inferFrameworkModule(SubframeworkDir, Attrs, Result);
+      inferFrameworkModule(*SubframeworkDir, Attrs, Result);
     }
   }
 
@@ -2130,12 +2139,12 @@
     llvm::sys::path::append(ModuleMapFileName, FileName);
     FileNameRef = ModuleMapFileName;
   }
-  if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
+  if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
     Map.parseModuleMapFile(
-        File, /*IsSystem=*/false,
+        *File, /*IsSystem=*/false,
         Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
             ? Directory
-            : File->getDir(),
+            : (*File)->getDir(),
         FileID(), nullptr, ExternLoc);
 }
 
@@ -2385,12 +2394,18 @@
   // Look for this file.
   const DirectoryEntry *Dir = nullptr;
   if (llvm::sys::path::is_absolute(DirName))
-    Dir = SourceMgr.getFileManager().getDirectory(DirName);
+    if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
+      Dir = *D;
+    else
+      Dir = nullptr;
   else {
     SmallString<128> PathName;
     PathName = Directory->getName();
     llvm::sys::path::append(PathName, DirName);
-    Dir = SourceMgr.getFileManager().getDirectory(PathName);
+    if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
+      Dir = *D;
+    else
+      Dir = nullptr;
   }
 
   if (!Dir) {
@@ -2410,9 +2425,9 @@
         SourceMgr.getFileManager().getVirtualFileSystem();
     for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
          I != E && !EC; I.increment(EC)) {
-      if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
+      if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
 
-        Module::Header Header = {I->path(), FE};
+        Module::Header Header = {I->path(), *FE};
         Headers.push_back(std::move(Header));
       }
     }
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -175,10 +175,10 @@
     std::string Parent = llvm::sys::path::parent_path(ModuleMapPath);
     if (Parent.empty())
       Parent = ".";
-    auto *Dir = FileMgr.getDirectory(Parent);
+    auto Dir = FileMgr.getDirectory(Parent);
     if (!Dir)
       return {};
-    auto DirName = FileMgr.getCanonicalName(Dir);
+    auto DirName = FileMgr.getCanonicalName(*Dir);
     auto FileName = llvm::sys::path::filename(ModuleMapPath);
 
     llvm::hash_code Hash =
@@ -230,11 +230,10 @@
       SmallString<128> FrameworkDirName;
       FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
       llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
-      if (const DirectoryEntry *FrameworkDir
-            = FileMgr.getDirectory(FrameworkDirName)) {
+      if (auto FrameworkDir = FileMgr.getDirectory(FrameworkDirName)) {
         bool IsSystem
           = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
-        Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
+        Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
         if (Module)
           break;
       }
@@ -310,17 +309,17 @@
     ModuleMap::KnownHeader *SuggestedModule) {
   // If we have a module map that might map this header, load it and
   // check whether we'll have a suggestion for a module.
-  const FileEntry *File = getFileMgr().getFile(FileName, /*OpenFile=*/true);
+  auto File = getFileMgr().getFile(FileName, /*OpenFile=*/true);
   if (!File)
     return nullptr;
 
   // If there is a module that corresponds to this header, suggest it.
-  if (!findUsableModuleForHeader(File, Dir ? Dir : File->getDir(),
+  if (!findUsableModuleForHeader(*File, Dir ? Dir : (*File)->getDir(),
                                  RequestingModule, SuggestedModule,
                                  IsSystemHeaderDir))
     return nullptr;
 
-  return File;
+  return *File;
 }
 
 /// LookupFile - Lookup the specified file in this search path, returning it
@@ -383,8 +382,10 @@
     Filename = StringRef(MappedName.begin(), MappedName.size());
     HasBeenMapped = true;
     Result = HM->LookupFile(Filename, HS.getFileMgr());
+  } else if (auto Res = HS.getFileMgr().getFile(Dest)) {
+    Result = *Res;
   } else {
-    Result = HS.getFileMgr().getFile(Dest);
+    Result = nullptr;
   }
 
   if (Result) {
@@ -427,8 +428,12 @@
   //
   // Similar issues occur when a top-level framework has moved into an
   // embedded framework.
-  const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName);
-  DirName = FileMgr.getCanonicalName(TopFrameworkDir);
+  const DirectoryEntry *TopFrameworkDir = nullptr;
+  if (auto TopFrameworkDirOrErr = FileMgr.getDirectory(DirName))
+    TopFrameworkDir = *TopFrameworkDirOrErr;
+
+  if (TopFrameworkDir)
+    DirName = FileMgr.getCanonicalName(TopFrameworkDir);
   do {
     // Get the parent directory name.
     DirName = llvm::sys::path::parent_path(DirName);
@@ -436,7 +441,7 @@
       break;
 
     // Determine whether this directory exists.
-    const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
+    auto Dir = FileMgr.getDirectory(DirName);
     if (!Dir)
       break;
 
@@ -444,7 +449,7 @@
     // framework.
     if (llvm::sys::path::extension(DirName) == ".framework") {
       SubmodulePath.push_back(llvm::sys::path::stem(DirName));
-      TopFrameworkDir = Dir;
+      TopFrameworkDir = *Dir;
     }
   } while (true);
 
@@ -499,7 +504,7 @@
     HS.IncrementFrameworkLookupCount();
 
     // If the framework dir doesn't exist, we fail.
-    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
+    auto Dir = FileMgr.getDirectory(FrameworkName);
     if (!Dir) return nullptr;
 
     // Otherwise, if it does, remember that this is the right direntry for this
@@ -538,8 +543,11 @@
   }
 
   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
-  const FileEntry *FE = FileMgr.getFile(FrameworkName,
-                                        /*OpenFile=*/!SuggestedModule);
+
+  const FileEntry *FE = nullptr;
+  if (auto File = FileMgr.getFile(FrameworkName, /*OpenFile=*/!SuggestedModule))
+    FE = *File;
+
   if (!FE) {
     // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
     const char *Private = "Private";
@@ -549,7 +557,9 @@
       SearchPath->insert(SearchPath->begin()+OrigSize, Private,
                          Private+strlen(Private));
 
-    FE = FileMgr.getFile(FrameworkName, /*OpenFile=*/!SuggestedModule);
+    if (auto File = FileMgr.getFile(FrameworkName, 
+                                    /*OpenFile=*/!SuggestedModule))
+      FE = *File;
   }
 
   // If we found the header and are allowed to suggest a module, do so now.
@@ -559,7 +569,7 @@
     bool FoundFramework = false;
     do {
       // Determine whether this directory exists.
-      const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath);
+      auto Dir = FileMgr.getDirectory(FrameworkPath);
       if (!Dir)
         break;
 
@@ -1022,12 +1032,12 @@
     ++NumSubFrameworkLookups;
 
     // If the framework dir doesn't exist, we fail.
-    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
+    auto Dir = FileMgr.getDirectory(FrameworkName);
     if (!Dir) return nullptr;
 
     // Otherwise, if it does, remember that this is the right direntry for this
     // framework.
-    CacheLookup.second.Directory = Dir;
+    CacheLookup.second.Directory = *Dir;
   }
 
   const FileEntry *FE = nullptr;
@@ -1047,7 +1057,10 @@
   }
 
   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-  if (!(FE = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true))) {
+  if (auto File = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true))
+    FE = *File;
+
+  if (!FE) {
     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
     HeadersFilename = FrameworkName;
     HeadersFilename += "PrivateHeaders/";
@@ -1058,7 +1071,10 @@
     }
 
     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-    if (!(FE = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true)))
+    if (auto File = FileMgr.getFile(HeadersFilename, /*OpenFile=*/true))
+      FE = *File;
+  
+    if (!FE)
       return nullptr;
   }
 
@@ -1306,13 +1322,13 @@
       return false;
 
     // Determine whether this directory exists.
-    const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
+    auto Dir = FileMgr.getDirectory(DirName);
     if (!Dir)
       return false;
 
     // Try to load the module map file in this directory.
-    switch (loadModuleMapFile(Dir, IsSystem,
-                              llvm::sys::path::extension(Dir->getName()) ==
+    switch (loadModuleMapFile(*Dir, IsSystem,
+                              llvm::sys::path::extension((*Dir)->getName()) ==
                                   ".framework")) {
     case LMM_NewlyLoaded:
     case LMM_AlreadyLoaded:
@@ -1328,12 +1344,12 @@
     }
 
     // If we hit the top of our search, we're done.
-    if (Dir == Root)
+    if (*Dir == Root)
       return false;
 
     // Keep track of all of the directories we checked, so we can mark them as
     // having module maps if we eventually do find a module map.
-    FixUpDirectories.push_back(Dir);
+    FixUpDirectories.push_back(*Dir);
   } while (true);
 }
 
@@ -1417,7 +1433,9 @@
     llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
   else
     return nullptr;
-  return FileMgr.getFile(PrivateFilename);
+  if (auto File = FileMgr.getFile(PrivateFilename))
+    return *File;
+  return nullptr;
 }
 
 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem,
@@ -1427,14 +1445,16 @@
   // up from the 'Modules' directory.
   const DirectoryEntry *Dir = nullptr;
   if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd)
-    Dir = FileMgr.getDirectory(".");
+    Dir = *FileMgr.getDirectory(".");
   else {
     if (!OriginalModuleMapFile.empty()) {
       // We're building a preprocessed module map. Find or invent the directory
       // that it originally occupied.
-      Dir = FileMgr.getDirectory(
+      auto DirOrErr = FileMgr.getDirectory(
           llvm::sys::path::parent_path(OriginalModuleMapFile));
-      if (!Dir) {
+      if (DirOrErr) {
+        Dir = *DirOrErr;
+      } else {
         auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0);
         Dir = FakeFile->getDir();
       }
@@ -1446,7 +1466,8 @@
     if (llvm::sys::path::filename(DirName) == "Modules") {
       DirName = llvm::sys::path::parent_path(DirName);
       if (DirName.endswith(".framework"))
-        Dir = FileMgr.getDirectory(DirName);
+        if (auto DirOrErr = FileMgr.getDirectory(DirName))
+          Dir = *DirOrErr;
       // FIXME: This assert can fail if there's a race between the above check
       // and the removal of the directory.
       assert(Dir && "parent must exist");
@@ -1503,13 +1524,15 @@
   if (IsFramework)
     llvm::sys::path::append(ModuleMapFileName, "Modules");
   llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
-  if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
-    return F;
+  if (auto F = FileMgr.getFile(ModuleMapFileName))
+    return *F;
 
   // Continue to allow module.map
   ModuleMapFileName = Dir->getName();
   llvm::sys::path::append(ModuleMapFileName, "module.map");
-  return FileMgr.getFile(ModuleMapFileName);
+  if (auto F = FileMgr.getFile(ModuleMapFileName))
+    return *F;
+  return nullptr;
 }
 
 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
@@ -1540,8 +1563,8 @@
 HeaderSearch::LoadModuleMapResult
 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
                                 bool IsFramework) {
-  if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
-    return loadModuleMapFile(Dir, IsSystem, IsFramework);
+  if (auto Dir = FileMgr.getDirectory(DirName))
+    return loadModuleMapFile(*Dir, IsSystem, IsFramework);
 
   return LMM_NoDirectory;
 }
@@ -1589,13 +1612,13 @@
           if (llvm::sys::path::extension(Dir->path()) != ".framework")
             continue;
 
-          const DirectoryEntry *FrameworkDir =
+          auto FrameworkDir =
               FileMgr.getDirectory(Dir->path());
           if (!FrameworkDir)
             continue;
 
           // Load this framework module.
-          loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir,
+          loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
                               IsSystem);
         }
         continue;
Index: clang/lib/Lex/HeaderMap.cpp
===================================================================
--- clang/lib/Lex/HeaderMap.cpp
+++ clang/lib/Lex/HeaderMap.cpp
@@ -204,7 +204,9 @@
   if (Dest.empty())
     return nullptr;
 
-  return FM.getFile(Dest);
+  if (auto File = FM.getFile(Dest))
+    return *File;
+  return nullptr;
 }
 
 StringRef HeaderMapImpl::lookupFilename(StringRef Filename,
Index: clang/lib/Frontend/TextDiagnostic.cpp
===================================================================
--- clang/lib/Frontend/TextDiagnostic.cpp
+++ clang/lib/Frontend/TextDiagnostic.cpp
@@ -762,7 +762,7 @@
 void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
   SmallVector<char, 128> AbsoluteFilename;
   if (DiagOpts->AbsolutePath) {
-    const DirectoryEntry *Dir = SM.getFileManager().getDirectory(
+    auto Dir = SM.getFileManager().getDirectory(
         llvm::sys::path::parent_path(Filename));
     if (Dir) {
       // We want to print a simplified absolute path, i. e. without "dots".
@@ -780,12 +780,12 @@
       // on Windows we can just use llvm::sys::path::remove_dots(), because,
       // on that system, both aforementioned paths point to the same place.
 #ifdef _WIN32
-      SmallString<4096> DirName = Dir->getName();
+      SmallString<4096> DirName = (*Dir)->getName();
       llvm::sys::fs::make_absolute(DirName);
       llvm::sys::path::native(DirName);
       llvm::sys::path::remove_dots(DirName, /* remove_dot_dot */ true);
 #else
-      StringRef DirName = SM.getFileManager().getCanonicalName(Dir);
+      StringRef DirName = SM.getFileManager().getCanonicalName(*Dir);
 #endif
       llvm::sys::path::append(AbsoluteFilename, DirName,
                               llvm::sys::path::filename(Filename));
Index: clang/lib/Frontend/Rewrite/FrontendActions.cpp
===================================================================
--- clang/lib/Frontend/Rewrite/FrontendActions.cpp
+++ clang/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -211,16 +211,16 @@
 
   void visitModuleFile(StringRef Filename,
                        serialization::ModuleKind Kind) override {
-    auto *File = CI.getFileManager().getFile(Filename);
+    auto File = CI.getFileManager().getFile(Filename);
     assert(File && "missing file for loaded module?");
 
     // Only rewrite each module file once.
-    if (!Rewritten.insert(File).second)
+    if (!Rewritten.insert(*File).second)
       return;
 
     serialization::ModuleFile *MF =
-        CI.getModuleManager()->getModuleManager().lookup(File);
-    assert(File && "missing module file for loaded module?");
+        CI.getModuleManager()->getModuleManager().lookup(*File);
+    assert(MF && "missing module file for loaded module?");
 
     // Not interested in PCH / preambles.
     if (!MF->isModule())
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===================================================================
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -369,9 +369,11 @@
 
   SourceManager &SourceMgr = Clang->getSourceManager();
   for (auto &Filename : PreambleDepCollector->getDependencies()) {
-    const FileEntry *File = Clang->getFileManager().getFile(Filename);
-    if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
+    auto FileOrErr = Clang->getFileManager().getFile(Filename);
+    if (!FileOrErr ||
+        *FileOrErr == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
       continue;
+    auto File = *FileOrErr;
     if (time_t ModTime = File->getModificationTime()) {
       FilesInPreamble[File->getName()] =
           PrecompiledPreamble::PreambleFileHash::createForFile(File->getSize(),
Index: clang/lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- clang/lib/Frontend/InitHeaderSearch.cpp
+++ clang/lib/Frontend/InitHeaderSearch.cpp
@@ -148,17 +148,17 @@
   }
 
   // If the directory exists, add it.
-  if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
+  if (auto DE = FM.getDirectory(MappedPathStr)) {
     IncludePath.push_back(
-      std::make_pair(Group, DirectoryLookup(DE, Type, isFramework)));
+      std::make_pair(Group, DirectoryLookup(*DE, Type, isFramework)));
     return true;
   }
 
   // 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 (auto FE = FM.getFile(MappedPathStr)) {
+      if (const HeaderMap *HM = Headers.CreateHeaderMap(*FE)) {
         // It is a headermap, add it to the search path.
         IncludePath.push_back(
           std::make_pair(Group,
@@ -636,8 +636,8 @@
     // Set up the builtin include directory in the module map.
     SmallString<128> P = StringRef(HSOpts.ResourceDir);
     llvm::sys::path::append(P, "include");
-    if (const DirectoryEntry *Dir = HS.getFileMgr().getDirectory(P))
-      HS.getModuleMap().setBuiltinIncludeDir(Dir);
+    if (auto Dir = HS.getFileMgr().getDirectory(P))
+      HS.getModuleMap().setBuiltinIncludeDir(*Dir);
   }
 
   Init.Realize(Lang);
Index: clang/lib/Frontend/FrontendAction.cpp
===================================================================
--- clang/lib/Frontend/FrontendAction.cpp
+++ clang/lib/Frontend/FrontendAction.cpp
@@ -370,7 +370,7 @@
                .Default(false))
         continue;
 
-      const FileEntry *Header = FileMgr.getFile(Dir->path());
+      auto Header = FileMgr.getFile(Dir->path());
       // FIXME: This shouldn't happen unless there is a file system race. Is
       // that worth diagnosing?
       if (!Header)
@@ -378,7 +378,7 @@
 
       // If this header is marked 'unavailable' in this module, don't include
       // it.
-      if (ModMap.isHeaderUnavailableInModule(Header, Module))
+      if (ModMap.isHeaderUnavailableInModule(*Header, Module))
         continue;
 
       // Compute the relative path from the directory to this file.
@@ -392,7 +392,7 @@
         llvm::sys::path::append(RelativeHeader, *It);
 
       // Include this header as part of the umbrella directory.
-      Module->addTopHeader(Header);
+      Module->addTopHeader(*Header);
       addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC);
     }
 
@@ -481,7 +481,7 @@
   // the module map, rather than adding it after the fact.
   StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
   if (!OriginalModuleMapName.empty()) {
-    auto *OriginalModuleMap =
+    auto OriginalModuleMap =
         CI.getFileManager().getFile(OriginalModuleMapName,
                                     /*openFile*/ true);
     if (!OriginalModuleMap) {
@@ -489,11 +489,11 @@
         << OriginalModuleMapName;
       return nullptr;
     }
-    if (OriginalModuleMap != CI.getSourceManager().getFileEntryForID(
+    if (*OriginalModuleMap != CI.getSourceManager().getFileEntryForID(
                                  CI.getSourceManager().getMainFileID())) {
       M->IsInferred = true;
       CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()
-        .setInferredModuleAllowedBy(M, OriginalModuleMap);
+        .setInferredModuleAllowedBy(M, *OriginalModuleMap);
     }
   }
 
@@ -674,8 +674,8 @@
   // Set up embedding for any specified files. Do this before we load any
   // source files, including the primary module map for the compilation.
   for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
-    if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
-      CI.getSourceManager().setFileIsTransient(FE);
+    if (auto FE = CI.getFileManager().getFile(F, /*openFile*/true))
+      CI.getSourceManager().setFileIsTransient(*FE);
     else
       CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
   }
@@ -709,10 +709,13 @@
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
     StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
     std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
-    if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
+    if (auto PCHDir = FileMgr.getDirectory(PCHInclude)) {
       std::error_code EC;
       SmallString<128> DirNative;
-      llvm::sys::path::native(PCHDir->getName(), DirNative);
+      if (*PCHDir == nullptr) {
+        llvm::dbgs() << "Directory " << PCHInclude << " was null but no error thrown";
+      }
+      llvm::sys::path::native((*PCHDir)->getName(), DirNative);
       bool Found = false;
       llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
       for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
@@ -792,9 +795,9 @@
 
   // If we were asked to load any module map files, do so now.
   for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
-    if (auto *File = CI.getFileManager().getFile(Filename))
+    if (auto File = CI.getFileManager().getFile(Filename))
       CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
-          File, /*IsSystem*/false);
+          *File, /*IsSystem*/false);
     else
       CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
   }
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -161,7 +161,7 @@
 
   StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
   FileManager &FileMgr = CI.getFileManager();
-  const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude);
+  auto PCHDir = FileMgr.getDirectory(PCHInclude);
   if (!PCHDir) {
     MDC->addFile(PCHInclude);
     return;
@@ -169,7 +169,7 @@
 
   std::error_code EC;
   SmallString<128> DirNative;
-  llvm::sys::path::native(PCHDir->getName(), DirNative);
+  llvm::sys::path::native((*PCHDir)->getName(), DirNative);
   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
   SimpleASTReaderListener Validator(CI.getPreprocessor());
   for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
@@ -342,7 +342,7 @@
   // Remap files in the source manager (with other files).
   for (const auto &RF : InitOpts.RemappedFiles) {
     // Find the file that we're mapping to.
-    const FileEntry *ToFile = FileMgr.getFile(RF.second);
+    auto ToFile = FileMgr.getFile(RF.second);
     if (!ToFile) {
       Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
       continue;
@@ -350,7 +350,7 @@
 
     // Create the file entry for the file that we're mapping from.
     const FileEntry *FromFile =
-        FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
+        FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
     if (!FromFile) {
       Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
       continue;
@@ -358,7 +358,7 @@
 
     // Override the contents of the "from" file with the contents of
     // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, ToFile);
+    SourceMgr.overrideFileContents(FromFile, *ToFile);
   }
 
   SourceMgr.setOverridenFilesKeepOriginalName(
@@ -558,7 +558,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);
+  auto Entry = PP.getFileManager().getFile(Filename);
   if (!Entry) {
     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
       << Filename;
@@ -566,7 +566,7 @@
   }
 
   // Truncate the named file at the given line/column.
-  PP.SetCodeCompletionPoint(Entry, Line, Column);
+  PP.SetCodeCompletionPoint(*Entry, Line, Column);
   return false;
 }
 
@@ -830,11 +830,12 @@
 
   // Figure out where to get and map in the main file.
   if (InputFile != "-") {
-    const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
-    if (!File) {
+    auto FileOrErr = FileMgr.getFile(InputFile, /*OpenFile=*/true);
+    if (!FileOrErr) {
       Diags.Report(diag::err_fe_error_reading) << InputFile;
       return false;
     }
+    auto File = *FileOrErr;
 
     // The natural SourceManager infrastructure can't currently handle named
     // pipes, but we would at least like to accept them for the main
@@ -1154,7 +1155,9 @@
     llvm::sys::path::append(PublicFilename, "module.modulemap");
   else
     return nullptr;
-  return FileMgr.getFile(PublicFilename);
+  if (auto FE = FileMgr.getFile(PublicFilename))
+    return *FE;
+  return nullptr;
 }
 
 /// Compile a module file for the given module, using the options
@@ -1718,8 +1721,9 @@
       if (Source != ModuleCache && !Module) {
         Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true,
                                                         !IsInclusionDirective);
+        auto ModuleFile = FileMgr->getFile(ModuleFileName);
         if (!Module || !Module->getASTFile() ||
-            FileMgr->getFile(ModuleFileName) != Module->getASTFile()) {
+            !ModuleFile || (*ModuleFile != Module->getASTFile())) {
           // Error out if Module does not refer to the file in the prebuilt
           // module path.
           getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt)
Index: clang/lib/Frontend/ASTUnit.cpp
===================================================================
--- clang/lib/Frontend/ASTUnit.cpp
+++ clang/lib/Frontend/ASTUnit.cpp
@@ -2368,13 +2368,13 @@
     // Rebuild the StoredDiagnostic.
     if (SD.Filename.empty())
       continue;
-    const FileEntry *FE = FileMgr.getFile(SD.Filename);
+    auto FE = FileMgr.getFile(SD.Filename);
     if (!FE)
       continue;
     SourceLocation FileLoc;
     auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
     if (ItFileID == PreambleSrcLocCache.end()) {
-      FileID FID = SrcMgr.translateFile(FE);
+      FileID FID = SrcMgr.translateFile(*FE);
       FileLoc = SrcMgr.getLocForStartOfFile(FID);
       PreambleSrcLocCache[SD.Filename] = FileLoc;
     } else {
Index: clang/lib/CodeGen/CodeGenAction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenAction.cpp
+++ clang/lib/CodeGen/CodeGenAction.cpp
@@ -561,13 +561,13 @@
   if (D.isLocationAvailable()) {
     D.getLocation(Filename, Line, Column);
     if (Line > 0) {
-      const FileEntry *FE = FileMgr.getFile(Filename);
+      auto FE = FileMgr.getFile(Filename);
       if (!FE)
         FE = FileMgr.getFile(D.getAbsolutePath());
       if (FE) {
         // If -gcolumn-info was not used, Column will be 0. This upsets the
         // source manager, so pass 1 if Column is not set.
-        DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
+        DILoc = SourceMgr.translateFileLineCol(*FE, Line, Column ? Column : 1);
       }
     }
     BadDebugInfo = DILoc.isInvalid();
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -2263,7 +2263,7 @@
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
       new DiagnosticOptions);
   SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr);
-  FileID ID = SourceMgr->createFileID(FileMgr->getFile(FileName),
+  FileID ID = SourceMgr->createFileID(*FileMgr->getFile(FileName),
                                       SourceLocation(), clang::SrcMgr::C_User);
   assert(ID.isValid());
   SourceMgr->setMainFileID(ID);
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -246,8 +246,8 @@
   if (!TopHeaderNames.empty()) {
     for (std::vector<std::string>::iterator
            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
-      if (const FileEntry *FE = FileMgr.getFile(*I))
-        TopHeaders.insert(FE);
+      if (auto FE = FileMgr.getFile(*I))
+        TopHeaders.insert(*FE);
     }
     TopHeaderNames.clear();
   }
Index: clang/lib/Basic/FileManager.cpp
===================================================================
--- clang/lib/Basic/FileManager.cpp
+++ clang/lib/Basic/FileManager.cpp
@@ -61,23 +61,42 @@
 
 void FileManager::clearStatCache() { StatCache.reset(); }
 
+/// Determines if the given llvm::ErrorOr erroneously contains a nullptr without
+/// an error, which should not be included in the cache.
+template <typename T>
+static bool isNotNull(llvm::ErrorOr<T *> &value) {
+  if (value.getError())
+    return true;
+  return *value != nullptr;
+}
+
+/// Determines if the given llvm::ErrorOr contains a valid, non-null pointer and
+/// no error. Similar to \c isNotNull above, but only for values that are not
+/// errors.
+template <typename T>
+static bool containsValue(llvm::ErrorOr<T *> &value) {
+  return value && *value != nullptr;
+}
+
 /// Retrieve the directory that the given file name resides in.
 /// Filename can point to either a real file or a virtual file.
-static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
-                                                  StringRef Filename,
-                                                  bool CacheFailure) {
+static llvm::ErrorOr<const DirectoryEntry *>
+getDirectoryFromFile(FileManager &FileMgr, StringRef Filename,
+                     bool CacheFailure) {
   if (Filename.empty())
-    return nullptr;
+    return std::errc::no_such_file_or_directory;
 
   if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))
-    return nullptr; // If Filename is a directory.
+    return std::errc::is_a_directory; // If Filename is a directory.
 
   StringRef DirName = llvm::sys::path::parent_path(Filename);
   // Use the current directory if file has no path component.
   if (DirName.empty())
     DirName = ".";
 
-  return FileMgr.getDirectory(DirName, CacheFailure);
+  auto DirEntry = FileMgr.getDirectory(DirName, CacheFailure);
+  assert(isNotNull(DirEntry) && "no error but returned NULL");
+  return DirEntry;
 }
 
 /// Add all ancestors of the given path (pointing to either a file or
@@ -93,7 +112,7 @@
   // at the same time.  Therefore, if DirName is already in the cache,
   // we don't need to recurse as its ancestors must also already be in
   // the cache (or it's a known non-virtual directory).
-  if (NamedDirEnt.second)
+  if (containsValue(NamedDirEnt.second))
     return;
 
   // Add the virtual directory to the cache.
@@ -106,8 +125,8 @@
   addAncestorsAsVirtualDirs(DirName);
 }
 
-const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
-                                                bool CacheFailure) {
+llvm::ErrorOr<const DirectoryEntry *>
+FileManager::getDirectory(StringRef DirName, bool CacheFailure) {
   // stat doesn't like trailing separators except for root directory.
   // At least, on Win32 MSVCRT, stat() cannot strip trailing '/'.
   // (though it can strip '\\')
@@ -131,13 +150,17 @@
   // See if there was already an entry in the map.  Note that the map
   // contains both virtual and real directories.
   auto SeenDirInsertResult = SeenDirEntries.insert({DirName, nullptr});
-  if (!SeenDirInsertResult.second)
-    return SeenDirInsertResult.first->second;
+  if (!SeenDirInsertResult.second) {
+    auto &ExistingCachedDir = SeenDirInsertResult.first->second;
+    assert(isNotNull(ExistingCachedDir) &&
+           "should not have inserted a NULL into the cache");
+    return ExistingCachedDir;
+  }
 
   // We've not seen this before. Fill it in.
   ++NumDirCacheMisses;
   auto &NamedDirEnt = *SeenDirInsertResult.first;
-  assert(!NamedDirEnt.second && "should be newly-created");
+  assert(!containsValue(NamedDirEnt.second) && "should be newly-created");
 
   // Get the null-terminated directory name as stored as the key of the
   // SeenDirEntries map.
@@ -145,11 +168,15 @@
 
   // Check to see if the directory exists.
   llvm::vfs::Status Status;
-  if (getStatValue(InterndDirName, Status, false, nullptr /*directory lookup*/)) {
+  auto statError = getStatValue(InterndDirName, Status, false,
+                                nullptr /*directory lookup*/);
+  if (statError) {
     // There's no real directory at the given path.
-    if (!CacheFailure)
+    if (CacheFailure)
+      NamedDirEnt.second = statError;
+    else
       SeenDirEntries.erase(DirName);
-    return nullptr;
+    return statError;
   }
 
   // It exists.  See if we have already opened a directory with the
@@ -168,19 +195,22 @@
   return &UDE;
 }
 
-const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
-                                      bool CacheFailure) {
+llvm::ErrorOr<const FileEntry *>
+FileManager::getFile(StringRef Filename, bool openFile, bool CacheFailure) {
   ++NumFileLookups;
 
   // See if there is already an entry in the map.
   auto SeenFileInsertResult = SeenFileEntries.insert({Filename, nullptr});
-  if (!SeenFileInsertResult.second)
-    return SeenFileInsertResult.first->second;
+  if (!SeenFileInsertResult.second) {
+    auto &CachedFile = SeenFileInsertResult.first->second;
+    assert(isNotNull(CachedFile) && "inserted a NULL into the cache");
+    return CachedFile;
+  }
 
   // We've not seen this before. Fill it in.
   ++NumFileCacheMisses;
   auto &NamedFileEnt = *SeenFileInsertResult.first;
-  assert(!NamedFileEnt.second && "should be newly-created");
+  assert(!containsValue(NamedFileEnt.second) && "should be newly-created");
 
   // Get the null-terminated file name as stored as the key of the
   // SeenFileEntries map.
@@ -191,14 +221,17 @@
   // 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 == nullptr) { // Directory doesn't exist, file can't exist.
-    if (!CacheFailure)
+  auto DirInfoOrErr = getDirectoryFromFile(*this, Filename, CacheFailure);
+  if (!DirInfoOrErr) { // Directory doesn't exist, file can't exist.
+    if (CacheFailure)
+      NamedFileEnt.second = DirInfoOrErr.getError();
+    else
       SeenFileEntries.erase(Filename);
 
-    return nullptr;
+    return DirInfoOrErr.getError();
   }
+  const DirectoryEntry *DirInfo = *DirInfoOrErr;
+  assert(DirInfo != nullptr && "null directory but no error?");
 
   // FIXME: Use the directory info to prune this, before doing the stat syscall.
   // FIXME: This will reduce the # syscalls.
@@ -206,12 +239,16 @@
   // Check to see if the file exists.
   std::unique_ptr<llvm::vfs::File> F;
   llvm::vfs::Status Status;
-  if (getStatValue(InterndFileName, Status, true, openFile ? &F : nullptr)) {
+  auto statError = getStatValue(InterndFileName, Status, true,
+                                openFile ? &F : nullptr);
+  if (statError) {
     // There's no real file at the given path.
-    if (!CacheFailure)
+    if (CacheFailure)
+      NamedFileEnt.second = statError;
+    else
       SeenFileEntries.erase(Filename);
 
-    return nullptr;
+    return statError;
   }
 
   assert((openFile || !F) && "undesired open file");
@@ -227,7 +264,7 @@
   if (Status.getName() != Filename) {
     auto &NamedFileEnt =
       *SeenFileEntries.insert({Status.getName(), &UFE}).first;
-    assert(NamedFileEnt.second == &UFE &&
+    assert(*NamedFileEnt.second == &UFE &&
            "filename from getStatValue() refers to wrong file");
     InterndFileName = NamedFileEnt.first().data();
   }
@@ -281,8 +318,8 @@
 
   // See if there is already an entry in the map for an existing file.
   auto &NamedFileEnt = *SeenFileEntries.insert({Filename, nullptr}).first;
-  if (NamedFileEnt.second)
-    return NamedFileEnt.second;
+  if (NamedFileEnt.second && *NamedFileEnt.second)
+    return *NamedFileEnt.second;
 
   // We've not seen this before, or the file is cached as non-existent.
   ++NumFileCacheMisses;
@@ -292,15 +329,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 &&
+  auto DirInfo = getDirectoryFromFile(*this, Filename, /*CacheFailure=*/true);
+  assert(containsValue(DirInfo) &&
          "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
   llvm::vfs::Status Status;
   const char *InterndFileName = NamedFileEnt.first().data();
-  if (getStatValue(InterndFileName, Status, true, nullptr) == 0) {
+  if (!getStatValue(InterndFileName, Status, true, nullptr)) {
     UFE = &UniqueRealFiles[Status.getUniqueID()];
     Status = llvm::vfs::Status(
       Status.getName(), Status.getUniqueID(),
@@ -332,7 +368,7 @@
   UFE->Name    = InterndFileName;
   UFE->Size    = Size;
   UFE->ModTime = ModificationTime;
-  UFE->Dir     = DirInfo;
+  UFE->Dir     = *DirInfo;
   UFE->UID     = NextFileUID++;
   UFE->IsValid = true;
   UFE->File.reset();
@@ -423,32 +459,43 @@
 /// if the path points to a virtual file or does not exist, or returns
 /// false if it's an existent real file.  If FileDescriptor is NULL,
 /// do directory look-up instead of file look-up.
-bool FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status,
-                               bool isFile,
-                               std::unique_ptr<llvm::vfs::File> *F) {
+std::error_code
+FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status,
+                          bool isFile, std::unique_ptr<llvm::vfs::File> *F) {
   // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
   // absolute!
   if (FileSystemOpts.WorkingDir.empty())
-    return bool(FileSystemStatCache::get(Path, Status, isFile, F,
-                                         StatCache.get(), *FS));
+    return FileSystemStatCache::get(Path, Status, isFile, F,
+                                    StatCache.get(), *FS);
 
   SmallString<128> FilePath(Path);
   FixupRelativePath(FilePath);
 
-  return bool(FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F,
-                                       StatCache.get(), *FS));
+  return FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F,
+                                  StatCache.get(), *FS);
 }
 
-bool FileManager::getNoncachedStatValue(StringRef Path,
-                                        llvm::vfs::Status &Result) {
+llvm::ErrorOr<llvm::vfs::Status>
+FileManager::getStatus(StringRef path, bool isDir) {
+  llvm::vfs::Status status;
+  auto error = getStatValue(path, status, /*isFile*/!isDir,
+                            /*file to open*/nullptr);
+  if (error)
+    return error;
+  return status;
+}
+
+std::error_code 
+FileManager::getNoncachedStatValue(StringRef Path,
+                                   llvm::vfs::Status &Result) {
   SmallString<128> FilePath(Path);
   FixupRelativePath(FilePath);
 
   llvm::ErrorOr<llvm::vfs::Status> S = FS->status(FilePath.c_str());
   if (!S)
-    return true;
+    return S.getError();
   Result = *S;
-  return false;
+  return std::error_code();
 }
 
 void FileManager::invalidateCache(const FileEntry *Entry) {
@@ -471,11 +518,14 @@
   UIDToFiles.resize(NextFileUID);
 
   // Map file entries
-  for (llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator>::const_iterator
+  for (llvm::StringMap<llvm::ErrorOr<FileEntry*>,
+                       llvm::BumpPtrAllocator>::const_iterator
          FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end();
        FE != FEEnd; ++FE)
-    if (FE->getValue())
-      UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
+    if (auto FileEntryOrErr = FE->getValue()) {
+      const FileEntry *Entry = *FileEntryOrErr;
+      UIDToFiles[Entry->getUID()] = Entry;
+    }
 
   // Map virtual file entries
   for (const auto &VFE : VirtualFileEntries)
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -8442,13 +8442,13 @@
         // disk again
         // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
         // than mmap the files several times.
-        const FileEntry *Entry =
+        auto Entry =
             ToFileManager.getFile(Cache->OrigEntry->getName());
         // FIXME: The filename may be a virtual name that does probably not
         // point to a valid file and we get no Entry here. In this case try with
         // the memory buffer below.
         if (Entry)
-          ToID = ToSM.createFileID(Entry, *ToIncludeLoc,
+          ToID = ToSM.createFileID(*Entry, *ToIncludeLoc,
                                    FromSLoc.getFile().getFileCharacteristic());
       }
     }
Index: clang/lib/ARCMigrate/ObjCMT.cpp
===================================================================
--- clang/lib/ARCMigrate/ObjCMT.cpp
+++ clang/lib/ARCMigrate/ObjCMT.cpp
@@ -2141,10 +2141,11 @@
       StringRef Val = ValueString->getValue(ValueStorage);
 
       if (Key == "file") {
-        const FileEntry *FE = FileMgr.getFile(Val);
-        if (!FE)
+        auto FE = FileMgr.getFile(Val);
+        if (FE)
+          Entry.File = *FE;
+        else
           Ignore = true;
-        Entry.File = FE;
       } else if (Key == "offset") {
         if (Val.getAsInteger(10, Entry.Offset))
           Ignore = true;
Index: clang/lib/ARCMigrate/FileRemapper.cpp
===================================================================
--- clang/lib/ARCMigrate/FileRemapper.cpp
+++ clang/lib/ARCMigrate/FileRemapper.cpp
@@ -78,26 +78,26 @@
                     Diag);
     StringRef toFilename = lines[idx+2];
 
-    const FileEntry *origFE = FileMgr->getFile(fromFilename);
+    llvm::ErrorOr<const FileEntry *> origFE = FileMgr->getFile(fromFilename);
     if (!origFE) {
       if (ignoreIfFilesChanged)
         continue;
       return report("File does not exist: " + fromFilename, Diag);
     }
-    const FileEntry *newFE = FileMgr->getFile(toFilename);
+    llvm::ErrorOr<const FileEntry *> newFE = FileMgr->getFile(toFilename);
     if (!newFE) {
       if (ignoreIfFilesChanged)
         continue;
       return report("File does not exist: " + toFilename, Diag);
     }
 
-    if ((uint64_t)origFE->getModificationTime() != timeModified) {
+    if ((uint64_t)(*origFE)->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(*origFE, *newFE));
   }
 
   for (unsigned i = 0, e = pairs.size(); i != e; ++i)
@@ -152,9 +152,11 @@
       newOut.write(mem->getBufferStart(), mem->getBufferSize());
       newOut.close();
 
-      const FileEntry *newE = FileMgr->getFile(tempPath);
-      remap(origFE, newE);
-      infoOut << newE->getName() << '\n';
+      auto newE = FileMgr->getFile(tempPath);
+      if (newE) {
+        remap(origFE, *newE);
+        infoOut << (*newE)->getName() << '\n';
+      }
     }
   }
 
@@ -224,7 +226,9 @@
 }
 
 const FileEntry *FileRemapper::getOriginalFile(StringRef filePath) {
-  const FileEntry *file = FileMgr->getFile(filePath);
+  const FileEntry *file;
+  if (auto fileOrErr = FileMgr->getFile(filePath))
+    file = *fileOrErr;
   // If we are updating a file that overridden an original file,
   // actually update the original file.
   llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
Index: clang/include/clang/Basic/FileManager.h
===================================================================
--- clang/include/clang/Basic/FileManager.h
+++ clang/include/clang/Basic/FileManager.h
@@ -132,20 +132,24 @@
   SmallVector<std::unique_ptr<FileEntry>, 4> VirtualFileEntries;
 
   /// A cache that maps paths to directory entries (either real or
-  /// virtual) we have looked up
+  /// virtual) we have looked up, or an error that occurred when we looked up
+  /// the directory.
   ///
   /// The actual Entries for real directories/files are
   /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
   /// for virtual directories/files are owned by
   /// VirtualDirectoryEntries/VirtualFileEntries above.
   ///
-  llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
+  llvm::StringMap<llvm::ErrorOr<DirectoryEntry*>, llvm::BumpPtrAllocator>
+  SeenDirEntries;
 
   /// A cache that maps paths to file entries (either real or
-  /// virtual) we have looked up.
+  /// virtual) we have looked up, or an error that occurred when we looked up
+  /// the file.
   ///
   /// \see SeenDirEntries
-  llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
+  llvm::StringMap<llvm::ErrorOr<FileEntry*>, llvm::BumpPtrAllocator>
+  SeenFileEntries;
 
   /// The canonical names of directories.
   llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
@@ -164,8 +168,9 @@
   // Caching.
   std::unique_ptr<FileSystemStatCache> StatCache;
 
-  bool getStatValue(StringRef Path, llvm::vfs::Status &Status, bool isFile,
-                    std::unique_ptr<llvm::vfs::File> *F);
+  std::error_code getStatValue(StringRef Path, llvm::vfs::Status &Status,
+                               bool isFile,
+                               std::unique_ptr<llvm::vfs::File> *F);
 
   /// Add all ancestors of the given path (pointing to either a file
   /// or a directory) as virtual directories.
@@ -198,24 +203,30 @@
   /// Lookup, cache, and verify the specified directory (real or
   /// virtual).
   ///
-  /// This returns NULL if the directory doesn't exist.
+  /// This returns a \c std::error_code if there was an error reading the
+  /// directory.
   ///
   /// \param CacheFailure If true and the file does not exist, we'll cache
   /// the failure to find this file.
-  const DirectoryEntry *getDirectory(StringRef DirName,
-                                     bool CacheFailure = true);
+  llvm::ErrorOr<const DirectoryEntry *>
+  getDirectory(StringRef DirName, bool CacheFailure = true);
 
   /// Lookup, cache, and verify the specified file (real or
   /// virtual).
   ///
-  /// This returns NULL if the file doesn't exist.
+  /// This returns a \c std::error_code if there was an error loading the file.
   ///
   /// \param OpenFile if true and the file exists, it will be opened.
   ///
   /// \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);
+  llvm::ErrorOr<const FileEntry *>
+  getFile(StringRef Filename, bool OpenFile = false, bool CacheFailure = true);
+
+  /// Lookup, cache, and return the \c Status of the given file path.
+  /// @param path The path to the file or directory on disk.
+  /// @param isDir Whether the file is a directory or a regular file.
+  llvm::ErrorOr<llvm::vfs::Status> getStatus(StringRef path, bool isDir);
 
   /// Returns the current file system options
   FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
@@ -243,8 +254,9 @@
   /// If the path is relative, it will be resolved against the WorkingDir of the
   /// FileManager's FileSystemOptions.
   ///
-  /// \returns false on success, true on error.
-  bool getNoncachedStatValue(StringRef Path, llvm::vfs::Status &Result);
+  /// \returns a \c std::error_code describing an error, if there was one
+  std::error_code getNoncachedStatValue(StringRef Path,
+                                        llvm::vfs::Status &Result);
 
   /// Remove the real file \p Entry from the cache.
   void invalidateCache(const FileEntry *Entry);
Index: clang-tools-extra/modularize/ModularizeUtilities.cpp
===================================================================
--- clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -258,14 +258,15 @@
 std::error_code ModularizeUtilities::loadModuleMap(
     llvm::StringRef InputPath) {
   // Get file entry for module.modulemap file.
-  const FileEntry *ModuleMapEntry =
+  auto ModuleMapEntryOrErr =
     SourceMgr->getFileManager().getFile(InputPath);
 
   // return error if not found.
-  if (!ModuleMapEntry) {
+  if (!ModuleMapEntryOrErr) {
     llvm::errs() << "error: File \"" << InputPath << "\" not found.\n";
-    return std::error_code(1, std::generic_category());
+    return ModuleMapEntryOrErr.getError();
   }
+  const FileEntry *ModuleMapEntry = *ModuleMapEntryOrErr;
 
   // Because the module map parser uses a ForwardingDiagnosticConsumer,
   // which doesn't forward the BeginSourceFile call, we do it explicitly here.
@@ -276,8 +277,12 @@
   StringRef DirName(Dir->getName());
   if (llvm::sys::path::filename(DirName) == "Modules") {
     DirName = llvm::sys::path::parent_path(DirName);
-    if (DirName.endswith(".framework"))
-      Dir = FileMgr->getDirectory(DirName);
+    if (DirName.endswith(".framework")) {
+      if (auto DirEntry = FileMgr->getDirectory(DirName))
+        Dir = *DirEntry;
+      else
+        Dir = nullptr;
+    }
     // FIXME: This assert can fail if there's a race between the above check
     // and the removal of the directory.
     assert(Dir && "parent must exist");
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -56,9 +56,10 @@
 std::string toURI(const SourceManager &SM, llvm::StringRef Path,
                   const SymbolCollector::Options &Opts) {
   llvm::SmallString<128> AbsolutePath(Path);
-  if (auto CanonPath =
-          getCanonicalPath(SM.getFileManager().getFile(Path), SM)) {
-    AbsolutePath = *CanonPath;
+  if (auto File = SM.getFileManager().getFile(Path)) {
+    if (auto CanonPath = getCanonicalPath(*File, SM)) {
+      AbsolutePath = *CanonPath;
+    }
   }
   // We don't perform is_absolute check in an else branch because makeAbsolute
   // might return a relative path on some InMemoryFileSystems.
Index: clang-tools-extra/clangd/SourceCode.cpp
===================================================================
--- clang-tools-extra/clangd/SourceCode.cpp
+++ clang-tools-extra/clangd/SourceCode.cpp
@@ -442,10 +442,10 @@
   //
   //  The file path of Symbol is "/project/src/foo.h" instead of
   //  "/tmp/build/foo.h"
-  if (const DirectoryEntry *Dir = SourceMgr.getFileManager().getDirectory(
+  if (auto Dir = SourceMgr.getFileManager().getDirectory(
           llvm::sys::path::parent_path(FilePath))) {
     llvm::SmallString<128> RealPath;
-    llvm::StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
+    llvm::StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
     llvm::sys::path::append(RealPath, DirName,
                             llvm::sys::path::filename(FilePath));
     return RealPath.str().str();
Index: clang-tools-extra/clangd/ClangdUnit.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdUnit.cpp
+++ clang-tools-extra/clangd/ClangdUnit.cpp
@@ -236,7 +236,8 @@
     for (const auto &Inc : Includes.MainFileIncludes) {
       const FileEntry *File = nullptr;
       if (Inc.Resolved != "")
-        File = SM.getFileManager().getFile(Inc.Resolved);
+        if (auto FE = SM.getFileManager().getFile(Inc.Resolved))
+          File = *FE;
 
       llvm::StringRef WrittenFilename =
           llvm::StringRef(Inc.Written).drop_front().drop_back();
Index: clang-tools-extra/clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -236,8 +236,11 @@
     if (FilePath.empty())
       return SourceLocation();
 
-    const FileEntry *File = SourceMgr.getFileManager().getFile(FilePath);
-    FileID ID = SourceMgr.getOrCreateFileID(File, SrcMgr::C_User);
+    auto File = SourceMgr.getFileManager().getFile(FilePath);
+    if (!File)
+      return SourceLocation();
+
+    FileID ID = SourceMgr.getOrCreateFileID(*File, SrcMgr::C_User);
     return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
   }
 
Index: clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
===================================================================
--- clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
+++ clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
@@ -78,8 +78,8 @@
   Tool.applyAllReplacements(Rewrite);
 
   for (const auto &File : Files) {
-    const auto *Entry = FileMgr.getFile(File);
-    const auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User);
+    auto Entry = FileMgr.getFile(File);
+    const auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
     Rewrite.getEditBuffer(ID).write(outs());
   }
 
Index: clang-tools-extra/clang-move/tool/ClangMove.cpp
===================================================================
--- clang-tools-extra/clang-move/tool/ClangMove.cpp
+++ clang-tools-extra/clang-move/tool/ClangMove.cpp
@@ -191,8 +191,8 @@
       for (auto I = Files.begin(), E = Files.end(); I != E; ++I) {
         OS << "  {\n";
         OS << "    \"FilePath\": \"" << *I << "\",\n";
-        const auto *Entry = FileMgr.getFile(*I);
-        auto ID = SM.translateFile(Entry);
+        const auto Entry = FileMgr.getFile(*I);
+        auto ID = SM.translateFile(*Entry);
         std::string Content;
         llvm::raw_string_ostream ContentStream(Content);
         Rewrite.getEditBuffer(ID).write(ContentStream);
Index: clang-tools-extra/clang-move/Move.cpp
===================================================================
--- clang-tools-extra/clang-move/Move.cpp
+++ clang-tools-extra/clang-move/Move.cpp
@@ -92,10 +92,10 @@
                  << '\n';
   // Handle symbolic link path cases.
   // We are trying to get the real file path of the symlink.
-  const DirectoryEntry *Dir = SM.getFileManager().getDirectory(
+  auto Dir = SM.getFileManager().getDirectory(
       llvm::sys::path::parent_path(AbsolutePath.str()));
   if (Dir) {
-    StringRef DirName = SM.getFileManager().getCanonicalName(Dir);
+    StringRef DirName = SM.getFileManager().getCanonicalName(*Dir);
     // FIXME: getCanonicalName might fail to get real path on VFS.
     if (llvm::sys::path::is_absolute(DirName)) {
       SmallString<128> AbsoluteFilename;
@@ -115,7 +115,7 @@
   auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
   if (ExpansionLoc.isInvalid())
     return false;
-  auto FileEntry =
+  auto *FileEntry =
       SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
   if (!FileEntry)
     return false;
@@ -842,12 +842,12 @@
 // Move all contents from OldFile to NewFile.
 void ClangMoveTool::moveAll(SourceManager &SM, StringRef OldFile,
                             StringRef NewFile) {
-  const FileEntry *FE = SM.getFileManager().getFile(makeAbsolutePath(OldFile));
+  auto FE = SM.getFileManager().getFile(makeAbsolutePath(OldFile));
   if (!FE) {
     llvm::errs() << "Failed to get file: " << OldFile << "\n";
     return;
   }
-  FileID ID = SM.getOrCreateFileID(FE, SrcMgr::C_User);
+  FileID ID = SM.getOrCreateFileID(*FE, SrcMgr::C_User);
   auto Begin = SM.getLocForStartOfFile(ID);
   auto End = SM.getLocForEndOfFile(ID);
   tooling::Replacement RemoveAll(SM, CharSourceRange::getCharRange(Begin, End),
Index: clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
===================================================================
--- clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
+++ clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
@@ -306,8 +306,7 @@
 
   // Get the FileEntry for the include.
   StringRef StrippedInclude = Include.trim("\"<>");
-  const FileEntry *Entry =
-      SourceManager.getFileManager().getFile(StrippedInclude);
+  auto Entry = SourceManager.getFileManager().getFile(StrippedInclude);
 
   // If the file doesn't exist return the path from the database.
   // FIXME: This should never happen.
@@ -316,7 +315,7 @@
 
   bool IsSystem = false;
   std::string Suggestion =
-      HeaderSearch.suggestPathToFileForDiagnostics(Entry, "", &IsSystem);
+      HeaderSearch.suggestPathToFileForDiagnostics(*Entry, "", &IsSystem);
 
   return IsSystem ? '<' + Suggestion + '>' : '"' + Suggestion + '"';
 }
Index: clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
===================================================================
--- clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
+++ clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
@@ -147,8 +147,8 @@
       for (auto I = ChangedFiles.begin(), E = ChangedFiles.end(); I != E; ++I) {
         OS << "  {\n";
         OS << "    \"FilePath\": \"" << *I << "\",\n";
-        const auto *Entry = FileMgr.getFile(*I);
-        auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User);
+        const auto Entry = FileMgr.getFile(*I);
+        auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
         std::string Content;
         llvm::raw_string_ostream ContentStream(Content);
         Rewrite.getEditBuffer(ID).write(ContentStream);
@@ -165,9 +165,9 @@
   }
 
   for (const auto &File : ChangedFiles) {
-    const auto *Entry = FileMgr.getFile(File);
+    const auto Entry = FileMgr.getFile(File);
 
-    auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User);
+    auto ID = Sources.getOrCreateFileID(*Entry, SrcMgr::C_User);
     outs() << "============== " << File << " ==============\n";
     Rewrite.getEditBuffer(ID).write(llvm::outs());
     outs() << "\n============================================\n";
Index: clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
===================================================================
--- clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
+++ clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
@@ -151,13 +151,13 @@
   auto AddToGroup = [&](const tooling::Replacement &R, bool FromDiag) {
     // Use the file manager to deduplicate paths. FileEntries are
     // automatically canonicalized.
-    if (const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath())) {
+    if (auto Entry = SM.getFileManager().getFile(R.getFilePath())) {
       if (FromDiag) {
-        auto &Replaces = DiagReplacements[Entry];
+        auto &Replaces = DiagReplacements[*Entry];
         if (!Replaces.insert(R).second)
           return;
       }
-      GroupedReplacements[Entry].push_back(R);
+      GroupedReplacements[*Entry].push_back(R);
     } else if (Warned.insert(R.getFilePath()).second) {
       errs() << "Described file '" << R.getFilePath()
              << "' doesn't exist. Ignoring...\n";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to