uint32_t options -> File::OpenOptions options

Summary:
This patch re-types everywhere that passes a File::OpenOptions
as a uint32_t so it actually uses File::OpenOptions.

It also converts some OpenOptions related functions that fail
by returning 0 or NULL into llvm::Expected

split off from https://reviews.llvm.org/D68737

Reviewers: JDevlieghere, jasonmolenda, labath

Reviewed By: labath

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D68853

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@374817 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Core/StreamFile.h b/include/lldb/Core/StreamFile.h
index 77e1557..712b289 100644
--- a/include/lldb/Core/StreamFile.h
+++ b/include/lldb/Core/StreamFile.h
@@ -30,7 +30,7 @@
 
   StreamFile(const char *path);
 
-  StreamFile(const char *path, uint32_t options,
+  StreamFile(const char *path, File::OpenOptions options,
              uint32_t permissions = lldb::eFilePermissionsFileDefault);
 
   StreamFile(FILE *fh, bool transfer_ownership);
diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h
index b36b523..444e709 100644
--- a/include/lldb/Host/File.h
+++ b/include/lldb/Host/File.h
@@ -13,6 +13,7 @@
 #include "lldb/Utility/IOObject.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-private.h"
+#include "llvm/ADT/BitmaskEnum.h"
 
 #include <mutex>
 #include <stdarg.h>
@@ -21,6 +22,8 @@
 
 namespace lldb_private {
 
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
 /// \class File File.h "lldb/Host/File.h"
 /// An abstract base class for files.
 ///
@@ -35,7 +38,12 @@
 
   // NB this enum is used in the lldb platform gdb-remote packet
   // vFile:open: and existing values cannot be modified.
-  enum OpenOptions {
+  //
+  // FIXME
+  // These values do not match the values used by GDB
+  // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
+  // * rdar://problem/46788934
+  enum OpenOptions : uint32_t {
     eOpenOptionRead = (1u << 0),  // Open file for reading
     eOpenOptionWrite = (1u << 1), // Open file for writing
     eOpenOptionAppend =
@@ -47,11 +55,12 @@
         (1u << 6), // Can create file only if it doesn't already exist
     eOpenOptionDontFollowSymlinks = (1u << 7),
     eOpenOptionCloseOnExec =
-        (1u << 8) // Close the file when executing a new process
+        (1u << 8), // Close the file when executing a new process
+    LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec)
   };
 
-  static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options);
-  static uint32_t GetOptionsFromMode(llvm::StringRef mode);
+  static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options);
+  static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode);
   static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
 
   File()
@@ -358,13 +367,13 @@
 public:
   NativeFile()
       : m_descriptor(kInvalidDescriptor), m_own_descriptor(false),
-        m_stream(kInvalidStream), m_options(0), m_own_stream(false) {}
+        m_stream(kInvalidStream), m_options(), m_own_stream(false) {}
 
   NativeFile(FILE *fh, bool transfer_ownership)
       : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
-        m_options(0), m_own_stream(transfer_ownership) {}
+        m_options(), m_own_stream(transfer_ownership) {}
 
-  NativeFile(int fd, uint32_t options, bool transfer_ownership)
+  NativeFile(int fd, OpenOptions options, bool transfer_ownership)
       : m_descriptor(fd), m_own_descriptor(transfer_ownership),
         m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
 
@@ -401,7 +410,7 @@
   int m_descriptor;
   bool m_own_descriptor;
   FILE *m_stream;
-  uint32_t m_options;
+  OpenOptions m_options;
   bool m_own_stream;
   std::mutex offset_access_mutex;
 
diff --git a/include/lldb/Host/FileCache.h b/include/lldb/Host/FileCache.h
index 49f9660..c769167 100644
--- a/include/lldb/Host/FileCache.h
+++ b/include/lldb/Host/FileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-types.h"
 
+#include "lldb/Host/File.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Status.h"
 
@@ -27,7 +28,7 @@
 public:
   static FileCache &GetInstance();
 
-  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
                            uint32_t mode, Status &error);
   bool CloseFile(lldb::user_id_t fd, Status &error);
 
diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h
index 6900f3f..528c435 100644
--- a/include/lldb/Host/FileSystem.h
+++ b/include/lldb/Host/FileSystem.h
@@ -64,7 +64,7 @@
   int Open(const char *path, int flags, int mode);
 
   llvm::Expected<std::unique_ptr<File>>
-  Open(const FileSpec &file_spec, uint32_t options,
+  Open(const FileSpec &file_spec, File::OpenOptions options,
        uint32_t permissions = lldb::eFilePermissionsFileDefault,
        bool should_close_fd = true);
 
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index ba9e97b..6f643df 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -18,6 +18,7 @@
 
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Core/UserSettingsController.h"
+#include "lldb/Host/File.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/ConstString.h"
@@ -505,8 +506,9 @@
   virtual Status SetFilePermissions(const FileSpec &file_spec,
                                     uint32_t file_permissions);
 
-  virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
-                                   uint32_t mode, Status &error) {
+  virtual lldb::user_id_t OpenFile(const FileSpec &file_spec,
+                                   File::OpenOptions flags, uint32_t mode,
+                                   Status &error) {
     return UINT64_MAX;
   }
 
diff --git a/include/lldb/Target/RemoteAwarePlatform.h b/include/lldb/Target/RemoteAwarePlatform.h
index 524332f..55d5ff6 100644
--- a/include/lldb/Target/RemoteAwarePlatform.h
+++ b/include/lldb/Target/RemoteAwarePlatform.h
@@ -22,7 +22,7 @@
   bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
                      ModuleSpec &module_spec) override;
 
-  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
                            uint32_t mode, Status &error) override;
 
   bool CloseFile(lldb::user_id_t fd, Status &error) override;
diff --git a/source/API/SBFile.cpp b/source/API/SBFile.cpp
index 5c003bc..739de40 100644
--- a/source/API/SBFile.cpp
+++ b/source/API/SBFile.cpp
@@ -31,7 +31,12 @@
   LLDB_RECORD_DUMMY(void, SBFile, (int, const char *, bool), fd, mode,
                     transfer_owndership);
   auto options = File::GetOptionsFromMode(mode);
-  m_opaque_sp = std::make_shared<NativeFile>(fd, options, transfer_owndership);
+  if (!options) {
+    llvm::consumeError(options.takeError());
+    return;
+  }
+  m_opaque_sp =
+      std::make_shared<NativeFile>(fd, options.get(), transfer_owndership);
 }
 
 SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) {
diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp
index 9105638..e7c726b 100644
--- a/source/API/SBStream.cpp
+++ b/source/API/SBStream.cpp
@@ -82,7 +82,7 @@
     if (!m_is_file)
       local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString();
   }
-  uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+  auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
   if (append)
     open_options |= File::eOpenOptionAppend;
   else
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index ca2b3f5..38bd3d1 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -773,8 +773,7 @@
     std::string path = outfile_spec.GetPath();
     if (outfile_spec) {
 
-      uint32_t open_options =
-          File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+      auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
       const bool append = m_outfile_options.GetAppend().GetCurrentValue();
       if (append)
         open_options |= File::eOpenOptionAppend;
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index 6ed63c1..248a046 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -375,12 +375,11 @@
     FileSpec file_spec(m_options.m_filename);
     FileSystem::Instance().Resolve(file_spec);
     std::string path(file_spec.GetPath());
-    uint32_t options = File::OpenOptions::eOpenOptionWrite |
-                       File::OpenOptions::eOpenOptionCanCreate;
+    auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
     if (m_options.m_append)
-      options |= File::OpenOptions::eOpenOptionAppend;
+      options |= File::eOpenOptionAppend;
     else
-      options |= File::OpenOptions::eOpenOptionTruncate;
+      options |= File::eOpenOptionTruncate;
 
     StreamFile out_file(path.c_str(), options,
                         lldb::eFilePermissionsFileDefault);
diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp
index d12541c..2ddb396 100644
--- a/source/Core/StreamFile.cpp
+++ b/source/Core/StreamFile.cpp
@@ -46,7 +46,8 @@
   }
 }
 
-StreamFile::StreamFile(const char *path, uint32_t options, uint32_t permissions)
+StreamFile::StreamFile(const char *path, File::OpenOptions options,
+                       uint32_t permissions)
     : Stream() {
   auto file = FileSystem::Instance().Open(FileSpec(path), options, permissions);
   if (file)
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 6498ec5..2b096ab 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -37,8 +37,9 @@
 
 using namespace lldb;
 using namespace lldb_private;
+using llvm::Expected;
 
-static const char *GetStreamOpenModeFromOptions(uint32_t options) {
+static Expected<const char *> GetStreamOpenModeFromOptions(uint32_t options) {
   if (options & File::eOpenOptionAppend) {
     if (options & File::eOpenOptionRead) {
       if (options & File::eOpenOptionCanCreateNewOnly)
@@ -65,23 +66,31 @@
   } else if (options & File::eOpenOptionWrite) {
     return "w";
   }
-  return nullptr;
+  return llvm::createStringError(
+      llvm::inconvertibleErrorCode(),
+      "invalid options, cannot convert to mode string");
 }
 
-uint32_t File::GetOptionsFromMode(llvm::StringRef mode) {
-  return llvm::StringSwitch<uint32_t>(mode)
-      .Cases("r", "rb", eOpenOptionRead)
-      .Cases("w", "wb", eOpenOptionWrite)
-      .Cases("a", "ab",
-             eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate)
-      .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite)
-      .Cases("w+", "wb+", "w+b",
-             eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate |
-                 eOpenOptionTruncate)
-      .Cases("a+", "ab+", "a+b",
-             eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend |
-                 eOpenOptionCanCreate)
-      .Default(0);
+Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
+  OpenOptions opts =
+      llvm::StringSwitch<OpenOptions>(mode)
+          .Cases("r", "rb", eOpenOptionRead)
+          .Cases("w", "wb", eOpenOptionWrite)
+          .Cases("a", "ab",
+                 eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate)
+          .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite)
+          .Cases("w+", "wb+", "w+b",
+                 eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate |
+                     eOpenOptionTruncate)
+          .Cases("a+", "ab+", "a+b",
+                 eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend |
+                     eOpenOptionCanCreate)
+          .Default(OpenOptions());
+  if (opts)
+    return opts;
+  return llvm::createStringError(
+      llvm::inconvertibleErrorCode(),
+      "invalid mode, cannot convert to File::OpenOptions");
 }
 
 int File::kInvalidDescriptor = -1;
@@ -257,8 +266,10 @@
 FILE *NativeFile::GetStream() {
   if (!StreamIsValid()) {
     if (DescriptorIsValid()) {
-      const char *mode = GetStreamOpenModeFromOptions(m_options);
-      if (mode) {
+      auto mode = GetStreamOpenModeFromOptions(m_options);
+      if (!mode)
+        llvm::consumeError(mode.takeError());
+      else {
         if (!m_own_descriptor) {
 // We must duplicate the file descriptor if we don't own it because when you
 // call fdopen, the stream will own the fd
@@ -270,8 +281,8 @@
           m_own_descriptor = true;
         }
 
-        m_stream =
-            llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
+        m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor,
+                                               mode.get());
 
         // If we got a stream, then we own the stream and should no longer own
         // the descriptor because fclose() will close it for us
@@ -303,7 +314,7 @@
   }
   m_descriptor = kInvalidDescriptor;
   m_stream = kInvalidStream;
-  m_options = 0;
+  m_options = OpenOptions(0);
   m_own_stream = false;
   m_own_descriptor = false;
   m_is_interactive = eLazyBoolCalculate;
@@ -315,7 +326,7 @@
   FILE *stream = GetStream();
   m_stream = NULL;
   m_descriptor = kInvalidDescriptor;
-  m_options = 0;
+  m_options = OpenOptions();
   m_own_stream = false;
   m_own_descriptor = false;
   m_is_interactive = m_supports_colors = m_is_real_terminal =
@@ -724,7 +735,7 @@
   }
 }
 
-mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) {
+mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
   mode_t mode = 0;
   if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite)
     mode |= O_RDWR;
@@ -747,4 +758,3 @@
 
   return mode;
 }
-
diff --git a/source/Host/common/FileCache.cpp b/source/Host/common/FileCache.cpp
index 0a7197e..d9dcad9 100644
--- a/source/Host/common/FileCache.cpp
+++ b/source/Host/common/FileCache.cpp
@@ -23,8 +23,9 @@
   return *m_instance;
 }
 
-lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags,
-                                    uint32_t mode, Status &error) {
+lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec,
+                                    File::OpenOptions flags, uint32_t mode,
+                                    Status &error) {
   if (!file_spec) {
     error.SetErrorString("empty path");
     return UINT64_MAX;
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index ba581ae..2db5bff 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -415,7 +415,8 @@
   return mode;
 }
 
-Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, uint32_t options,
+Expected<FileUP> FileSystem::Open(const FileSpec &file_spec,
+                                  File::OpenOptions options,
                                   uint32_t permissions, bool should_close_fd) {
   if (m_collector)
     m_collector->addFile(file_spec.GetPath());
diff --git a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 622df13..15ae82e 100644
--- a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -429,7 +429,7 @@
         int created_fd =
             open(file_spec.GetPath().c_str(), oflag, S_IRUSR | S_IWUSR);
         if (created_fd >= 0) {
-          uint32_t file_options = 0;
+          auto file_options = File::OpenOptions(0);
           if ((oflag & O_RDWR) || (oflag & O_RDONLY))
             file_options |= File::eOpenOptionRead;
           if ((oflag & O_RDWR) || (oflag & O_RDONLY))
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index a63e6ea..1e62ddf 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -629,7 +629,8 @@
 }
 
 lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
-                                                  uint32_t flags, uint32_t mode,
+                                                  File::OpenOptions flags,
+                                                  uint32_t mode,
                                                   Status &error) {
   return m_gdb_client.OpenFile(file_spec, flags, mode, error);
 }
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index c774daa..13edcba 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -113,7 +113,7 @@
   Status SetFilePermissions(const FileSpec &file_spec,
                             uint32_t file_permissions) override;
 
-  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
                            uint32_t mode, Status &error) override;
 
   bool CloseFile(lldb::user_id_t fd, Status &error) override;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f6ef457..072d566 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -2895,7 +2895,7 @@
 }
 lldb::user_id_t
 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
-                                       uint32_t flags, mode_t mode,
+                                       File::OpenOptions flags, mode_t mode,
                                        Status &error) {
   std::string path(file_spec.GetPath(false));
   lldb_private::StreamString stream;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 898942b..574cd0f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -17,6 +17,7 @@
 #include <string>
 #include <vector>
 
+#include "lldb/Host/File.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/GDBRemote.h"
 #include "lldb/Utility/StructuredData.h"
@@ -350,7 +351,7 @@
   size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
                              bool &sequence_mutex_unavailable);
 
-  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
                            mode_t mode, Status &error);
 
   bool CloseFile(lldb::user_id_t fd, Status &error);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index c416940..c7349db 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -507,7 +507,11 @@
   packet.GetHexByteStringTerminatedBy(path, ',');
   if (!path.empty()) {
     if (packet.GetChar() == ',') {
-      uint32_t flags = packet.GetHexMaxU32(false, 0);
+      // FIXME
+      // The flag values for OpenOptions do not match the values used by GDB
+      // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
+      // * rdar://problem/46788934
+      auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
       if (packet.GetChar() == ',') {
         mode_t mode = packet.GetHexMaxU32(false, 0600);
         FileSpec path_spec(path);
@@ -546,7 +550,7 @@
   int err = -1;
   int save_errno = 0;
   if (fd >= 0) {
-    NativeFile file(fd, 0, true);
+    NativeFile file(fd, File::OpenOptions(0), true);
     Status error = file.Close();
     err = 0;
     save_errno = error.GetError();
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 5346e3f..c3588f6 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -1090,8 +1090,12 @@
   // File object knows about that.
   PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
   auto options = File::GetOptionsFromMode(py_mode.GetString());
-  auto file = std::unique_ptr<File>(
-      new NativeFile(PyObject_AsFileDescriptor(m_py_obj), options, false));
+  if (!options) {
+    llvm::consumeError(options.takeError());
+    return nullptr;
+  }
+  auto file = std::unique_ptr<File>(new NativeFile(
+      PyObject_AsFileDescriptor(m_py_obj), options.get(), false));
   if (!file->IsValid())
     return nullptr;
   return file;
@@ -1165,9 +1169,10 @@
 
 char PythonException::ID = 0;
 
-llvm::Expected<uint32_t> GetOptionsForPyObject(const PythonObject &obj) {
-  uint32_t options = 0;
+llvm::Expected<File::OpenOptions>
+GetOptionsForPyObject(const PythonObject &obj) {
 #if PY_MAJOR_VERSION >= 3
+  auto options = File::OpenOptions(0);
   auto readable = As<bool>(obj.CallMethod("readable"));
   if (!readable)
     return readable.takeError();
@@ -1178,11 +1183,11 @@
     options |= File::eOpenOptionRead;
   if (writable.get())
     options |= File::eOpenOptionWrite;
+  return options;
 #else
   PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
-  options = File::GetOptionsFromMode(py_mode.GetString());
+  return File::GetOptionsFromMode(py_mode.GetString());
 #endif
-  return options;
 }
 
 // Base class template for python files.   All it knows how to do
@@ -1245,7 +1250,7 @@
 class SimplePythonFile : public OwnedPythonFile<NativeFile> {
 public:
   SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
-                   uint32_t options)
+                   File::OpenOptions options)
       : OwnedPythonFile(file, borrowed, fd, options, false) {}
 };
 } // namespace
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 00af754..1454f82 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -1220,7 +1220,7 @@
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
   LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n");
 
-  uint32_t source_open_options =
+  auto source_open_options =
       File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
   namespace fs = llvm::sys::fs;
   if (fs::is_symlink_file(source.GetPath()))
diff --git a/source/Target/RemoteAwarePlatform.cpp b/source/Target/RemoteAwarePlatform.cpp
index 1704e15..faa217a 100644
--- a/source/Target/RemoteAwarePlatform.cpp
+++ b/source/Target/RemoteAwarePlatform.cpp
@@ -61,8 +61,8 @@
 }
 
 lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec,
-                                              uint32_t flags, uint32_t mode,
-                                              Status &error) {
+                                              File::OpenOptions flags,
+                                              uint32_t mode, Status &error) {
   if (IsHost())
     return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
   if (m_remote_platform_sp)
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 85b0bf9..ca80e36 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -996,10 +996,9 @@
   }
 
   StreamFile out_file(path.c_str(),
-                      File::OpenOptions::eOpenOptionTruncate |
-                          File::OpenOptions::eOpenOptionWrite |
-                          File::OpenOptions::eOpenOptionCanCreate |
-                          File::OpenOptions::eOpenOptionCloseOnExec,
+                      File::eOpenOptionTruncate | File::eOpenOptionWrite |
+                          File::eOpenOptionCanCreate |
+                          File::eOpenOptionCloseOnExec,
                       lldb::eFilePermissionsFileDefault);
   if (!out_file.GetFile().IsValid()) {
     error.SetErrorStringWithFormat("Unable to open output file: %s.",