]> granicus.if.org Git - clang/commitdiff
FileManager: Use llvm::Expected in new getFileRef API
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 26 Aug 2019 18:29:51 +0000 (18:29 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 26 Aug 2019 18:29:51 +0000 (18:29 +0000)
`FileManager::getFileRef` is a modern API which we expect to convert to
over time.  We should modernize the error handling as well, using
`llvm::Expected` instead of `llvm::ErrorOr`, to help clients that care
about errors to ensure nothing is missed.

However, not all clients care.  I've also added another path for those
that don't:

- `FileEntryRef` is now copy- and move-assignable (using a pointer
  instead of a reference).
- `FileManager::getOptionalFileRef` returns an `llvm::Optional` instead
  of `llvm::Expected`.
- Added an `llvm::expectedToOptional` utility in case this is useful
  elsewhere.

https://reviews.llvm.org/D66705

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369943 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/FileManager.h
lib/Basic/FileManager.cpp
lib/Frontend/CompilerInstance.cpp
lib/Lex/HeaderMap.cpp
lib/Lex/HeaderSearch.cpp

index b22afec54e4f491165a0b9ae06294876236d1f33..9e54669efc532ec60d16c510fc5474704215a229 100644 (file)
@@ -110,26 +110,27 @@ public:
 /// accessed by the FileManager's client.
 class FileEntryRef {
 public:
+  FileEntryRef() = delete;
   FileEntryRef(StringRef Name, const FileEntry &Entry)
-      : Name(Name), Entry(Entry) {}
+      : Name(Name), Entry(&Entry) {}
 
   const StringRef getName() const { return Name; }
 
-  const FileEntry &getFileEntry() const { return Entry; }
+  const FileEntry &getFileEntry() const { return *Entry; }
 
-  off_t getSize() const { return Entry.getSize(); }
+  off_t getSize() const { return Entry->getSize(); }
 
-  unsigned getUID() const { return Entry.getUID(); }
+  unsigned getUID() const { return Entry->getUID(); }
 
   const llvm::sys::fs::UniqueID &getUniqueID() const {
-    return Entry.getUniqueID();
+    return Entry->getUniqueID();
   }
 
-  time_t getModificationTime() const { return Entry.getModificationTime(); }
+  time_t getModificationTime() const { return Entry->getModificationTime(); }
 
 private:
   StringRef Name;
-  const FileEntry &Entry;
+  const FileEntry *Entry;
 };
 
 /// Implements support for file system lookup, file system caching,
@@ -284,9 +285,17 @@ public:
   ///
   /// \param CacheFailure If true and the file does not exist, we'll cache
   /// the failure to find this file.
-  llvm::ErrorOr<FileEntryRef> getFileRef(StringRef Filename,
-                                         bool OpenFile = false,
-                                         bool CacheFailure = true);
+  llvm::Expected<FileEntryRef> getFileRef(StringRef Filename,
+                                          bool OpenFile = false,
+                                          bool CacheFailure = true);
+
+  /// Get a FileEntryRef if it exists, without doing anything on error.
+  llvm::Optional<FileEntryRef> getOptionalFileRef(StringRef Filename,
+                                                  bool OpenFile = false,
+                                                  bool CacheFailure = true) {
+    return llvm::expectedToOptional(
+        getFileRef(Filename, OpenFile, CacheFailure));
+  }
 
   /// Returns the current file system options
   FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
index 649e4d2239bc1b77e3c8c1060fcf3929012f9ff9..8e186713a9264e80763e5989e9fe68bb1c87823e 100644 (file)
@@ -187,10 +187,10 @@ FileManager::getFile(StringRef Filename, bool openFile, bool CacheFailure) {
   auto Result = getFileRef(Filename, openFile, CacheFailure);
   if (Result)
     return &Result->getFileEntry();
-  return Result.getError();
+  return llvm::errorToErrorCode(Result.takeError());
 }
 
-llvm::ErrorOr<FileEntryRef>
+llvm::Expected<FileEntryRef>
 FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
   ++NumFileLookups;
 
@@ -199,7 +199,8 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
       SeenFileEntries.insert({Filename, std::errc::no_such_file_or_directory});
   if (!SeenFileInsertResult.second) {
     if (!SeenFileInsertResult.first->second)
-      return SeenFileInsertResult.first->second.getError();
+      return llvm::errorCodeToError(
+          SeenFileInsertResult.first->second.getError());
     // Construct and return and FileEntryRef, unless it's a redirect to another
     // filename.
     SeenFileEntryOrRedirect Value = *SeenFileInsertResult.first->second;
@@ -230,7 +231,7 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
     else
       SeenFileEntries.erase(Filename);
 
-    return DirInfoOrErr.getError();
+    return llvm::errorCodeToError(DirInfoOrErr.getError());
   }
   const DirectoryEntry *DirInfo = *DirInfoOrErr;
 
@@ -249,7 +250,7 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
     else
       SeenFileEntries.erase(Filename);
 
-    return statError;
+    return llvm::errorCodeToError(statError);
   }
 
   assert((openFile || !F) && "undesired open file");
index f0227d0501c03b8e00e0a7d409e6600f27251d6e..a7b7114f791bd2b62dc07b7ee8dcbe056840052c 100644 (file)
@@ -833,6 +833,8 @@ bool CompilerInstance::InitializeSourceManager(
   if (InputFile != "-") {
     auto FileOrErr = FileMgr.getFileRef(InputFile, /*OpenFile=*/true);
     if (!FileOrErr) {
+      // FIXME: include the error in the diagnostic.
+      consumeError(FileOrErr.takeError());
       Diags.Report(diag::err_fe_error_reading) << InputFile;
       return false;
     }
index 1c7fb1a476465b8794b5e95b5f39fdc0e3ba17ee..d44ef29c05d13971999b1e4d6b03e92f6a8a489e 100644 (file)
@@ -204,9 +204,7 @@ Optional<FileEntryRef> HeaderMap::LookupFile(StringRef Filename,
   if (Dest.empty())
     return None;
 
-  if (auto File = FM.getFileRef(Dest))
-    return *File;
-  return None;
+  return FM.getOptionalFileRef(Dest);
 }
 
 StringRef HeaderMapImpl::lookupFilename(StringRef Filename,
index 84af65c30d504f611036c0b0dd98b3e44445f005..0160677b2ecc6a4090ee86a7df13faf81c7fa90f 100644 (file)
@@ -314,7 +314,7 @@ Optional<FileEntryRef> HeaderSearch::getFileAndSuggestModule(
   if (!File) {
     // For rare, surprising errors (e.g. "out of file handles"), diag the EC
     // message.
-    std::error_code EC = File.getError();
+    std::error_code EC = llvm::errorToErrorCode(File.takeError());
     if (EC != llvm::errc::no_such_file_or_directory &&
         EC != llvm::errc::invalid_argument &&
         EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
@@ -401,7 +401,7 @@ Optional<FileEntryRef> DirectoryLookup::LookupFile(
       FixupSearchPath();
       return *Result;
     }
-  } else if (auto Res = HS.getFileMgr().getFileRef(Dest)) {
+  } else if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest)) {
     FixupSearchPath();
     return *Res;
   }
@@ -553,9 +553,8 @@ Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup(
 
   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
 
-  llvm::ErrorOr<FileEntryRef> File =
-      FileMgr.getFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
-
+  auto File =
+      FileMgr.getOptionalFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
   if (!File) {
     // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
     const char *Private = "Private";
@@ -565,7 +564,8 @@ Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup(
       SearchPath->insert(SearchPath->begin()+OrigSize, Private,
                          Private+strlen(Private));
 
-    File = FileMgr.getFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
+    File = FileMgr.getOptionalFileRef(FrameworkName,
+                                      /*OpenFile=*/!SuggestedModule);
   }
 
   // If we found the header and are allowed to suggest a module, do so now.
@@ -1076,9 +1076,7 @@ Optional<FileEntryRef> HeaderSearch::LookupSubframeworkHeader(
   }
 
   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-  llvm::ErrorOr<FileEntryRef> File =
-      FileMgr.getFileRef(HeadersFilename, /*OpenFile=*/true);
-
+  auto File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
   if (!File) {
     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
     HeadersFilename = FrameworkName;
@@ -1090,7 +1088,7 @@ Optional<FileEntryRef> HeaderSearch::LookupSubframeworkHeader(
     }
 
     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
-    File = FileMgr.getFileRef(HeadersFilename, /*OpenFile=*/true);
+    File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
 
     if (!File)
       return None;