[NFC] Improve FileSpec internal APIs and usage in preparation for adding caching of resolved/absolute.

Resubmission of https://reviews.llvm.org/D130309 with the 2 patches that fixed the linux buildbot, and new windows fixes.

The FileSpec APIs allow users to modify instance variables directly by getting a non const reference to the directory and filename instance variables. This makes it impossible to control all of the times the FileSpec object is modified so we can clear cached member variables like m_resolved and with an upcoming patch caching if the file is relative or absolute. This patch modifies the APIs of FileSpec so no one can modify the directory or filename instance variables directly by adding set accessors and by removing the get accessors that are non const.

Many clients were using FileSpec::GetCString(...) which returned a unique C string from a ConstString'ified version of the result of GetPath() which returned a std::string. This caused many locations to use this convenient function incorrectly and could cause many strings to be added to the constant string pool that didn't need to. Most clients were converted to using FileSpec::GetPath().c_str() when possible. Other clients were modified to use the newly renamed version of this function which returns an actualy ConstString:

ConstString FileSpec::GetPathAsConstString(bool denormalize = true) const;

This avoids the issue where people were getting an already uniqued "const char *" that came from a ConstString only to put the "const char *" back into a "ConstString" object. By returning the ConstString instead of a "const char *" clients can be more efficient with the result.

The patch:
- Removes the non const GetDirectory() and GetFilename() get accessors
- Adds set accessors to replace the above functions: SetDirectory() and SetFilename().
- Adds ClearDirectory() and ClearFilename() to replace usage of the FileSpec::GetDirectory().Clear()/FileSpec::GetFilename().Clear() call sites
- Fixed all incorrect usage of FileSpec::GetCString() to use FileSpec::GetPath().c_str() where appropriate, and updated other call sites that wanted a ConstString to use the newly returned ConstString appropriately and efficiently.

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

GitOrigin-RevId: 529a3d87a799a2cba29bc1d0f426a00d5bb4c88f
diff --git a/include/lldb/Utility/FileSpec.h b/include/lldb/Utility/FileSpec.h
index ec473a2..a0b01fb 100644
--- a/include/lldb/Utility/FileSpec.h
+++ b/include/lldb/Utility/FileSpec.h
@@ -216,29 +216,38 @@
 
   Style GetPathStyle() const;
 
-  /// Directory string get accessor.
-  ///
-  /// \return
-  ///     A reference to the directory string object.
-  ConstString &GetDirectory();
-
   /// Directory string const get accessor.
   ///
   /// \return
   ///     A const reference to the directory string object.
-  ConstString GetDirectory() const;
+  const ConstString &GetDirectory() const { return m_directory; }
 
-  /// Filename string get accessor.
+  /// Directory string set accessor.
   ///
-  /// \return
-  ///     A reference to the filename string object.
-  ConstString &GetFilename();
+  /// \param[in] directory
+  ///     The value to replace the directory with.
+  void SetDirectory(ConstString directory);
+  void SetDirectory(llvm::StringRef directory);
+
+  /// Clear the directory in this object.
+  void ClearDirectory();
+
 
   /// Filename string const get accessor.
   ///
   /// \return
   ///     A const reference to the filename string object.
-  ConstString GetFilename() const;
+  const ConstString &GetFilename() const { return m_filename; }
+
+  /// Filename string set accessor.
+  ///
+  /// \param[in] filename
+  ///     The const string to replace the directory with.
+  void SetFilename(ConstString filename);
+  void SetFilename(llvm::StringRef filename);
+
+  /// Clear the filename in this object.
+  void ClearFilename();
 
   /// Returns true if the filespec represents an implementation source file
   /// (files with a ".c", ".cpp", ".m", ".mm" (many more) extension).
@@ -299,7 +308,13 @@
   ///     concatenated.
   std::string GetPath(bool denormalize = true) const;
 
-  const char *GetCString(bool denormalize = true) const;
+  /// Get the full path as a ConstString.
+  ///
+  /// This method should only be used when you need a ConstString or the
+  /// const char * from a ConstString to ensure permanent lifetime of C string.
+  /// Anyone needing the path temporarily should use the GetPath() method that
+  /// returns a std:string.
+  ConstString GetPathAsConstString(bool denormalize = true) const;
 
   /// Extract the full path to the file.
   ///
diff --git a/source/API/SBFileSpec.cpp b/source/API/SBFileSpec.cpp
index 2bec9a7..a7df9af 100644
--- a/source/API/SBFileSpec.cpp
+++ b/source/API/SBFileSpec.cpp
@@ -115,26 +115,26 @@
   LLDB_INSTRUMENT_VA(this);
 
   FileSpec directory{*m_opaque_up};
-  directory.GetFilename().Clear();
-  return directory.GetCString();
+  directory.ClearFilename();
+  return directory.GetPathAsConstString().GetCString();
 }
 
 void SBFileSpec::SetFilename(const char *filename) {
   LLDB_INSTRUMENT_VA(this, filename);
 
   if (filename && filename[0])
-    m_opaque_up->GetFilename().SetCString(filename);
+    m_opaque_up->SetFilename(filename);
   else
-    m_opaque_up->GetFilename().Clear();
+    m_opaque_up->ClearFilename();
 }
 
 void SBFileSpec::SetDirectory(const char *directory) {
   LLDB_INSTRUMENT_VA(this, directory);
 
   if (directory && directory[0])
-    m_opaque_up->GetDirectory().SetCString(directory);
+    m_opaque_up->SetDirectory(directory);
   else
-    m_opaque_up->GetDirectory().Clear();
+    m_opaque_up->ClearDirectory();
 }
 
 uint32_t SBFileSpec::GetPath(char *dst_path, size_t dst_len) const {
diff --git a/source/API/SBLaunchInfo.cpp b/source/API/SBLaunchInfo.cpp
index 5149feb..ae19191 100644
--- a/source/API/SBLaunchInfo.cpp
+++ b/source/API/SBLaunchInfo.cpp
@@ -207,7 +207,7 @@
 const char *SBLaunchInfo::GetWorkingDirectory() const {
   LLDB_INSTRUMENT_VA(this);
 
-  return m_opaque_sp->GetWorkingDirectory().GetCString();
+  return m_opaque_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
 }
 
 void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) {
diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp
index ba18ba6..2a8e963 100644
--- a/source/API/SBPlatform.cpp
+++ b/source/API/SBPlatform.cpp
@@ -354,7 +354,7 @@
 
   PlatformSP platform_sp(GetSP());
   if (platform_sp)
-    return platform_sp->GetWorkingDirectory().GetCString();
+    return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
   return nullptr;
 }
 
@@ -547,14 +547,15 @@
         if (!command)
           return Status("invalid shell command (empty)");
 
-        const char *working_dir = shell_command.GetWorkingDirectory();
-        if (working_dir == nullptr) {
-          working_dir = platform_sp->GetWorkingDirectory().GetCString();
-          if (working_dir)
-            shell_command.SetWorkingDirectory(working_dir);
+        if (shell_command.GetWorkingDirectory() == nullptr) {
+          std::string platform_working_dir =
+              platform_sp->GetWorkingDirectory().GetPath();
+          if (!platform_working_dir.empty())
+            shell_command.SetWorkingDirectory(platform_working_dir.c_str());
         }
         return platform_sp->RunShellCommand(
-            shell_command.m_opaque_ptr->m_shell, command, FileSpec(working_dir),
+            shell_command.m_opaque_ptr->m_shell, command,
+            FileSpec(shell_command.GetWorkingDirectory()),
             &shell_command.m_opaque_ptr->m_status,
             &shell_command.m_opaque_ptr->m_signo,
             &shell_command.m_opaque_ptr->m_output,
diff --git a/source/API/SBReproducer.cpp b/source/API/SBReproducer.cpp
index 7431b49..4a69e2c 100644
--- a/source/API/SBReproducer.cpp
+++ b/source/API/SBReproducer.cpp
@@ -136,9 +136,8 @@
 const char *SBReproducer::GetPath() {
   LLDB_INSTRUMENT()
   ConstString path;
-  auto &r = Reproducer::Instance();
   if (FileSpec reproducer_path = Reproducer::Instance().GetReproducerPath())
-    path = ConstString(r.GetReproducerPath().GetCString());
+    path = ConstString(reproducer_path.GetPathAsConstString());
   return path.GetCString();
 }
 
diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp
index ff04452..449ff12 100644
--- a/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -236,7 +236,7 @@
   FileSpec search_file_spec = m_location_spec.GetFileSpec();
   const bool is_relative = search_file_spec.IsRelative();
   if (is_relative)
-    search_file_spec.GetDirectory().Clear();
+    search_file_spec.ClearDirectory();
   SourceLocationSpec search_location_spec(
       search_file_spec, m_location_spec.GetLine().value_or(0),
       m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(),
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index 89bc3e0..1b630e1 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -401,7 +401,7 @@
           m_options.log_file, flags, lldb::eFilePermissionsFileDefault, false);
       if (!file) {
         result.AppendErrorWithFormat("Unable to open log file '%s': %s",
-                                     m_options.log_file.GetCString(),
+                                     m_options.log_file.GetPath().c_str(),
                                      llvm::toString(file.takeError()).c_str());
         return false;
       }
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 3dcb355..f72d4c7 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -406,7 +406,7 @@
 
       if (core_file) {
         FileSpec core_file_dir;
-        core_file_dir.GetDirectory() = core_file.GetDirectory();
+        core_file_dir.SetDirectory(core_file.GetDirectory());
         target_sp->AppendExecutableSearchPaths(core_file_dir);
 
         ProcessSP process_sp(target_sp->CreateProcess(
@@ -4072,7 +4072,7 @@
 
     if (!module_spec.GetUUID().IsValid()) {
       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
-        module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
+        module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
     }
 
     // Now module_spec represents a symbol file for a module that might exist
@@ -4136,7 +4136,7 @@
         break;
 
       // Replace basename with one fewer extension
-      module_spec.GetFileSpec().GetFilename() = filename_no_extension;
+      module_spec.GetFileSpec().SetFilename(filename_no_extension);
       target->GetImages().FindModules(module_spec, matching_modules);
     }
 
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index d034905..5d8db6b 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -302,7 +302,7 @@
 
 llvm::StringRef Debugger::GetReproducerPath() const {
   auto &r = repro::Reproducer::Instance();
-  return r.GetReproducerPath().GetCString();
+  return r.GetReproducerPath().GetPathAsConstString().AsCString();
 }
 
 const FormatEntity::Entry *Debugger::GetThreadFormat() const {
diff --git a/source/Core/IOHandlerCursesGUI.cpp b/source/Core/IOHandlerCursesGUI.cpp
index e9073c8..f96073a 100644
--- a/source/Core/IOHandlerCursesGUI.cpp
+++ b/source/Core/IOHandlerCursesGUI.cpp
@@ -3171,7 +3171,7 @@
     FileSpec core_file_spec = m_core_file_field->GetResolvedFileSpec();
 
     FileSpec core_file_directory_spec;
-    core_file_directory_spec.GetDirectory() = core_file_spec.GetDirectory();
+    core_file_directory_spec.SetDirectory(core_file_spec.GetDirectory());
     target_sp->AppendExecutableSearchPaths(core_file_directory_spec);
 
     ProcessSP process_sp(target_sp->CreateProcess(
diff --git a/source/Expression/FunctionCaller.cpp b/source/Expression/FunctionCaller.cpp
index fdbaa91..58c9d56 100644
--- a/source/Expression/FunctionCaller.cpp
+++ b/source/Expression/FunctionCaller.cpp
@@ -99,10 +99,10 @@
     if (jit_module_sp) {
       ConstString const_func_name(FunctionName());
       FileSpec jit_file;
-      jit_file.GetFilename() = const_func_name;
+      jit_file.SetFilename(const_func_name);
       jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
       m_jit_module_wp = jit_module_sp;
-      process->GetTarget().GetImages().Append(jit_module_sp, 
+      process->GetTarget().GetImages().Append(jit_module_sp,
                                               true /* notify */);
     }
   }
diff --git a/source/Expression/REPL.cpp b/source/Expression/REPL.cpp
index d7582af..36a21de 100644
--- a/source/Expression/REPL.cpp
+++ b/source/Expression/REPL.cpp
@@ -58,7 +58,7 @@
   ConstString file_basename = GetSourceFileBasename();
   FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
   if (tmpdir_file_spec) {
-    tmpdir_file_spec.GetFilename() = file_basename;
+    tmpdir_file_spec.SetFilename(file_basename);
     m_repl_source_path = tmpdir_file_spec.GetPath();
   } else {
     tmpdir_file_spec = FileSpec("/tmp");
diff --git a/source/Host/common/FileAction.cpp b/source/Host/common/FileAction.cpp
index e399c7e..f980d32 100644
--- a/source/Host/common/FileAction.cpp
+++ b/source/Host/common/FileAction.cpp
@@ -25,7 +25,9 @@
   m_file_spec.Clear();
 }
 
-llvm::StringRef FileAction::GetPath() const { return m_file_spec.GetCString(); }
+llvm::StringRef FileAction::GetPath() const {
+  return m_file_spec.GetPathAsConstString().AsCString();
+}
 
 const FileSpec &FileAction::GetFileSpec() const { return m_file_spec; }
 
@@ -81,7 +83,7 @@
     break;
   case eFileActionOpen:
     stream.Printf("open fd %d with '%s', OFLAGS = 0x%x", m_fd,
-                  m_file_spec.GetCString(), m_arg);
+                  m_file_spec.GetPath().c_str(), m_arg);
     break;
   }
 }
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index 501062f..23cf3c4 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -267,7 +267,7 @@
 
   // Update the FileSpec with the resolved path.
   if (file_spec.GetFilename().IsEmpty())
-    file_spec.GetDirectory().SetString(path);
+    file_spec.SetDirectory(path);
   else
     file_spec.SetPath(path);
   file_spec.SetIsResolved(true);
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index 22c0403..caed8a3 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -242,7 +242,7 @@
   raw_path = (parent_path + dir).str();
   LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__,
             raw_path.c_str());
-  file_spec.GetDirectory().SetString(raw_path);
+  file_spec.SetDirectory(raw_path);
   return (bool)file_spec.GetDirectory();
 }
 
@@ -258,7 +258,7 @@
     g_shlib_dir_helper(lldb_file_spec);
 
   // Remove the filename so that this FileSpec only represents the directory.
-  file_spec.GetDirectory() = lldb_file_spec.GetDirectory();
+  file_spec.SetDirectory(lldb_file_spec.GetDirectory());
 
   return (bool)file_spec.GetDirectory();
 }
@@ -278,7 +278,7 @@
   if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
     return false;
 
-  file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
+  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
   return true;
 }
 
@@ -301,7 +301,7 @@
   if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
     return false;
 
-  file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
+  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
   return true;
 }
 
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 1ed2037..0af7a47 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -171,14 +171,14 @@
   if (HostInfoPosix::ComputeSupportExeDirectory(file_spec) &&
       file_spec.IsAbsolute() && FileSystem::Instance().Exists(file_spec))
     return true;
-  file_spec.GetDirectory() = GetProgramFileSpec().GetDirectory();
+  file_spec.SetDirectory(GetProgramFileSpec().GetDirectory());
   return !file_spec.GetDirectory().IsEmpty();
 }
 
 bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
   FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins");
   FileSystem::Instance().Resolve(temp_file);
-  file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
+  file_spec.SetDirectory(temp_file.GetPath());
   return true;
 }
 
@@ -190,9 +190,9 @@
   if (xdg_data_home && xdg_data_home[0]) {
     std::string user_plugin_dir(xdg_data_home);
     user_plugin_dir += "/lldb";
-    file_spec.GetDirectory().SetCString(user_plugin_dir.c_str());
+    file_spec.SetDirectory(user_plugin_dir.c_str());
   } else
-    file_spec.GetDirectory().SetCString("~/.local/share/lldb");
+    file_spec.SetDirectory("~/.local/share/lldb");
   return true;
 }
 
diff --git a/source/Host/macosx/objcxx/Host.mm b/source/Host/macosx/objcxx/Host.mm
index 1c990c8..5a3098d 100644
--- a/source/Host/macosx/objcxx/Host.mm
+++ b/source/Host/macosx/objcxx/Host.mm
@@ -211,7 +211,7 @@
     return error;
   }
 
-  darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
+  darwin_debug_file_spec.SetFilename("darwin-debug");
 
   if (!FileSystem::Instance().Exists(darwin_debug_file_spec)) {
     error.SetErrorStringWithFormat(
@@ -236,7 +236,7 @@
 
   FileSpec working_dir{launch_info.GetWorkingDirectory()};
   if (working_dir)
-    command.Printf(R"( --working-dir \"%s\")", working_dir.GetCString());
+    command.Printf(R"( --working-dir \"%s\")", working_dir.GetPath().c_str());
   else {
     char cwd[PATH_MAX];
     if (getcwd(cwd, PATH_MAX))
@@ -1200,13 +1200,14 @@
   FileSpec working_dir{launch_info.GetWorkingDirectory()};
   if (working_dir) {
     // Set the working directory on this thread only
-    if (__pthread_chdir(working_dir.GetCString()) < 0) {
+    std::string working_dir_path = working_dir.GetPath();
+    if (__pthread_chdir(working_dir_path.c_str()) < 0) {
       if (errno == ENOENT) {
         error.SetErrorStringWithFormat("No such file or directory: %s",
-                                       working_dir.GetCString());
+                                       working_dir_path.c_str());
       } else if (errno == ENOTDIR) {
         error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
-                                       working_dir.GetCString());
+                                       working_dir_path.c_str());
       } else {
         error.SetErrorStringWithFormat("An unknown error occurred when "
                                        "changing directory for process "
diff --git a/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index e038b7a..74a4fb2 100644
--- a/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -167,8 +167,7 @@
     }
   }
 
-  file_spec.GetDirectory().SetString(
-      llvm::StringRef(raw_path.c_str(), raw_path.size()));
+  file_spec.SetDirectory(raw_path);
   return (bool)file_spec.GetDirectory();
 }
 
@@ -185,8 +184,7 @@
     raw_path.resize(framework_pos);
     raw_path.append("/Headers");
   }
-  file_spec.GetDirectory().SetString(
-      llvm::StringRef(raw_path.c_str(), raw_path.size()));
+  file_spec.SetDirectory(raw_path);
   return true;
 }
 
@@ -204,15 +202,14 @@
   framework_pos += strlen("LLDB.framework");
   raw_path.resize(framework_pos);
   raw_path.append("/Resources/PlugIns");
-  file_spec.GetDirectory().SetString(
-      llvm::StringRef(raw_path.c_str(), raw_path.size()));
+  file_spec.SetDirectory(raw_path);
   return true;
 }
 
 bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
   FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
   FileSystem::Instance().Resolve(temp_file);
-  file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
+  file_spec.SetDirectory(temp_file.GetPathAsConstString());
   return true;
 }
 
@@ -262,8 +259,8 @@
       arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK),
                               cpusubtype32);
 
-      if (cputype == CPU_TYPE_ARM || 
-          cputype == CPU_TYPE_ARM64 || 
+      if (cputype == CPU_TYPE_ARM ||
+          cputype == CPU_TYPE_ARM64 ||
           cputype == CPU_TYPE_ARM64_32) {
 // When running on a watch or tv, report the host os correctly
 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
diff --git a/source/Host/posix/FileSystemPosix.cpp b/source/Host/posix/FileSystemPosix.cpp
index 3660f67..26a266e 100644
--- a/source/Host/posix/FileSystemPosix.cpp
+++ b/source/Host/posix/FileSystemPosix.cpp
@@ -35,7 +35,7 @@
 
 Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
   Status error;
-  if (::symlink(dst.GetCString(), src.GetCString()) == -1)
+  if (::symlink(dst.GetPath().c_str(), src.GetPath().c_str()) == -1)
     error.SetErrorToErrno();
   return error;
 }
@@ -56,7 +56,8 @@
 Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
   char resolved_path[PATH_MAX];
   if (!src.GetPath(resolved_path, sizeof(resolved_path))) {
-    return Status("Couldn't get the canonical path for %s", src.GetCString());
+    return Status("Couldn't get the canonical path for %s",
+                  src.GetPath().c_str());
   }
 
   char real_path[PATH_MAX + 1];
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index 6355359..8718e90 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -144,7 +144,7 @@
 
 bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) {
   FileSpec temp_file("/opt/local/include/lldb");
-  file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
+  file_spec.SetDirectory(temp_file.GetPath());
   return true;
 }
 
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index cbd1915..b919d9b 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -30,8 +30,8 @@
 Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
   Status error;
   std::wstring wsrc, wdst;
-  if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
-      !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+  if (!llvm::ConvertUTF8toWide(src.GetPath(), wsrc) ||
+      !llvm::ConvertUTF8toWide(dst.GetPath(), wdst))
     error.SetErrorString(PATH_CONVERSION_ERROR);
   if (error.Fail())
     return error;
@@ -51,7 +51,7 @@
 Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
   Status error;
   std::wstring wsrc;
-  if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) {
+  if (!llvm::ConvertUTF8toWide(src.GetPath(), wsrc)) {
     error.SetErrorString(PATH_CONVERSION_ERROR);
     return error;
   }
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
index 7ef546e..baa422c 100644
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/source/Host/windows/ProcessLauncherWindows.cpp
@@ -106,7 +106,7 @@
 
   std::wstring wexecutable, wworkingDirectory;
   llvm::ConvertUTF8toWide(executable, wexecutable);
-  llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(),
+  llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetPath(),
                           wworkingDirectory);
   // If the command line is empty, it's best to pass a null pointer to tell
   // CreateProcessW to use the executable name as the command line.  If the
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 0063760..3f185fa 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -276,7 +276,7 @@
 
               changed = m_process->GetTarget().SetSectionLoadAddress(
                   section_sp, new_section_load_addr, warn_multiple);
-            } 
+            }
           }
         }
 
@@ -541,8 +541,8 @@
   const size_t image_infos_size = image_infos.size();
   for (size_t i = 0; i < image_infos_size; i++) {
     if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) {
-      // In a "simulator" process we will have two dyld modules -- 
-      // a "dyld" that we want to keep track of, and a "dyld_sim" which 
+      // In a "simulator" process we will have two dyld modules --
+      // a "dyld" that we want to keep track of, and a "dyld_sim" which
       // we don't need to keep track of here.  dyld_sim will have a non-macosx
       // OS.
       if (target_arch.GetTriple().getEnvironment() == llvm::Triple::Simulator &&
@@ -551,7 +551,7 @@
       }
 
       dyld_idx = i;
-    } 
+    }
     if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) {
       exe_idx = i;
     }
@@ -652,7 +652,7 @@
               module_spec.SetObjectOffset(objfile->GetFileOffset() +
                                           commpage_section->GetFileOffset());
               module_spec.SetObjectSize(objfile->GetByteSize());
-              commpage_image_module_sp = target.GetOrCreateModule(module_spec, 
+              commpage_image_module_sp = target.GetOrCreateModule(module_spec,
                                                                true /* notify */);
               if (!commpage_image_module_sp ||
                   commpage_image_module_sp->GetObjectFile() == nullptr) {
@@ -1023,8 +1023,7 @@
   if (!module_sp) {
     SymbolContextList sc_list;
     ModuleSpec module_spec;
-    module_spec.GetFileSpec().GetFilename().SetCString(
-        "libsystem_pthread.dylib");
+    module_spec.GetFileSpec().SetFilename("libsystem_pthread.dylib");
     ModuleList module_list;
     m_process->GetTarget().GetImages().FindModules(module_spec, module_list);
     if (!module_list.IsEmpty()) {
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 4869cf0..fd9ecc9 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -119,7 +119,7 @@
     if (exe_mod) {
       m_exe_file_spec = exe_mod->GetPlatformFileSpec();
       LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'",
-                __FUNCTION__, m_exe_file_spec.GetCString());
+                __FUNCTION__, m_exe_file_spec.GetPath().c_str());
     } else {
       LLDB_LOGF(log,
                 "DYLDRendezvous::%s cannot cache exe module path: null "
@@ -658,7 +658,7 @@
     log->PutCString("DYLDRendezvous SOEntries:");
 
   for (int i = 1; I != E; ++I, ++i) {
-    LLDB_LOGF(log, "\n   SOEntry [%d] %s", i, I->file_spec.GetCString());
+    LLDB_LOGF(log, "\n   SOEntry [%d] %s", i, I->file_spec.GetPath().c_str());
     LLDB_LOGF(log, "      Base : %" PRIx64, I->base_addr);
     LLDB_LOGF(log, "      Path : %" PRIx64, I->path_addr);
     LLDB_LOGF(log, "      Dyn  : %" PRIx64, I->dyn_addr);
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 8a708c1..4652e1d 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -650,7 +650,7 @@
       LLDB_LOGF(
           log,
           "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
-          __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
+          __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr);
     }
   }
 
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 6ba03da..d143686 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -568,7 +568,7 @@
           reexport_module_sp =
               target.GetImages().FindFirstModule(reexport_module_spec);
           if (!reexport_module_sp) {
-            reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
+            reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
             reexport_module_sp =
                 target.GetImages().FindFirstModule(reexport_module_spec);
           }
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 2099cfa..1b8ea9a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -72,7 +72,7 @@
                "DefaultComputeClangResourceDir: Setting ClangResourceDir "
                "to \"{0}\", verify = {1}",
                clang_dir.str(), verify ? "true" : "false");
-      file_spec.GetDirectory().SetString(clang_dir);
+      file_spec.SetDirectory(clang_dir);
       FileSystem::Instance().Resolve(file_spec);
       return true;
     }
@@ -119,7 +119,7 @@
                             "Developer/Toolchains/XcodeDefault.xctoolchain",
                             swift_clang_resource_dir);
     if (!verify || VerifyClangPath(clang_path)) {
-      file_spec.GetDirectory().SetString(clang_path.c_str());
+      file_spec.SetDirectory(clang_path);
       FileSystem::Instance().Resolve(file_spec);
       return true;
     }
@@ -134,7 +134,7 @@
       raw_path.resize(parent - r_end);
       llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir);
       if (!verify || VerifyClangPath(clang_path)) {
-        file_spec.GetDirectory().SetString(clang_path.c_str());
+        file_spec.SetDirectory(clang_path);
         FileSystem::Instance().Resolve(file_spec);
         return true;
       }
@@ -145,7 +145,7 @@
   raw_path = lldb_shlib_spec.GetPath();
   raw_path.resize(rev_it - r_end);
   raw_path.append("LLDB.framework/Resources/Clang");
-  file_spec.GetDirectory().SetString(raw_path.c_str());
+  file_spec.SetDirectory(raw_path);
   FileSystem::Instance().Resolve(file_spec);
   return true;
 #endif // __APPLE__
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 7145e78..3399f42 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -753,7 +753,7 @@
     if (jit_module_sp) {
       ConstString const_func_name(FunctionName());
       FileSpec jit_file;
-      jit_file.GetFilename() = const_func_name;
+      jit_file.SetFilename(const_func_name);
       jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
       m_jit_module_wp = jit_module_sp;
       target->GetImages().Append(jit_module_sp);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 3db3fce..f9956e1 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -144,7 +144,7 @@
       if (jit_module_sp) {
         ConstString const_func_name(FunctionName());
         FileSpec jit_file;
-        jit_file.GetFilename() = const_func_name;
+        jit_file.SetFilename(const_func_name);
         jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
         m_jit_module_wp = jit_module_sp;
         target->GetImages().Append(jit_module_sp);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 0c032f8..06cb1b6 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -577,7 +577,7 @@
       array_size;        // Number of items in array, only needed for structs
   ConstString type_name; // Name of type, only needed for structs
 
-  static ConstString 
+  static ConstString
   GetFallbackStructName(); // Print this as the type name of a struct Element
                            // If we can't resolve the actual struct name
 
@@ -879,7 +879,7 @@
           LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s",
                     __FUNCTION__, new_bp ? "new" : "existing",
                     kernel_name.GetCString(),
-                    address.GetModule()->GetFileSpec().GetCString());
+                    address.GetModule()->GetFileSpec().GetPath().c_str());
         }
       }
     }
@@ -2984,7 +2984,8 @@
     const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes());
     raw_rs_info.split(info_lines, '\n');
     LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s",
-              m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str());
+              m_module->GetFileSpec().GetPath().c_str(),
+              raw_rs_info.str().c_str());
   }
 
   enum {
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 4323f83..5dc71fc 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2282,7 +2282,7 @@
         // Strip the path if there is @rpath, @executable, etc so we just use
         // the basename
         if (path[0] == '@')
-          file_spec.GetDirectory().Clear();
+          file_spec.ClearDirectory();
 
         if (lc.cmd == LC_REEXPORT_DYLIB) {
           m_reexported_dylibs.AppendIfUnique(file_spec);
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 800bd9d..2c16609 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1084,7 +1084,7 @@
     // with the help of the object file's directory.
     llvm::SmallString<128> dll_fullpath;
     FileSpec dll_specs(dll_name);
-    dll_specs.GetDirectory().SetString(m_file.GetDirectory().GetCString());
+    dll_specs.SetDirectory(m_file.GetDirectory());
 
     if (!llvm::sys::fs::real_path(dll_specs.GetPath(), dll_fullpath))
       m_deps_filespec->EmplaceBack(dll_fullpath);
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
index 500af93..e5cb369 100644
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
@@ -28,7 +28,7 @@
 #ifdef _WIN32
   HANDLE process_handle = ::OpenProcess(
       PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID());
-  const std::string file_name = outfile.GetCString();
+  const std::string file_name = outfile.GetPath();
   std::wstring wide_name;
   wide_name.resize(file_name.size() + 1);
   char *result_ptr = reinterpret_cast<char *>(&wide_name[0]);
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index c75138f..327a6f4 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -174,7 +174,7 @@
   FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix);
   if (source_spec.IsRelative())
     source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
-        source_spec.GetCString(false));
+        source_spec.GetPathAsConstString(false).GetStringRef());
 
   Status error;
   auto sync_service = GetSyncService(error);
@@ -189,13 +189,13 @@
   if (mode != 0)
     return sync_service->PullFile(source_spec, destination);
 
-  auto source_file = source_spec.GetCString(false);
+  std::string source_file = source_spec.GetPath(false);
 
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOGF(log, "Got mode == 0 on '%s': try to get file via 'shell cat'",
-            source_file);
+            source_file.c_str());
 
-  if (strchr(source_file, '\'') != nullptr)
+  if (strchr(source_file.c_str(), '\'') != nullptr)
     return Status("Doesn't support single-quotes in filenames");
 
   // mode == 0 can signify that adbd cannot access the file due security
@@ -203,7 +203,7 @@
   AdbClient adb(m_device_id);
 
   char cmd[PATH_MAX];
-  snprintf(cmd, sizeof(cmd), "cat '%s'", source_file);
+  snprintf(cmd, sizeof(cmd), "cat '%s'", source_file.c_str());
 
   return adb.ShellToFile(cmd, minutes(1), destination);
 }
@@ -217,7 +217,7 @@
   FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix);
   if (destination_spec.IsRelative())
     destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
-        destination_spec.GetCString(false));
+        destination_spec.GetPath(false));
 
   // TODO: Set correct uid and gid on remote file.
   Status error;
@@ -325,8 +325,8 @@
   // Execute oatdump on the remote device to generate a file with symtab
   StreamString command;
   command.Printf("oatdump --symbolize=%s --output=%s",
-                 module_sp->GetPlatformFileSpec().GetCString(false),
-                 symfile_platform_filespec.GetCString(false));
+                 module_sp->GetPlatformFileSpec().GetPath(false).c_str(),
+                 symfile_platform_filespec.GetPath(false).c_str());
   error = adb.Shell(command.GetData(), minutes(1), nullptr);
   if (error.Fail())
     return Status("Oatdump failed: %s", error.AsCString());
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index f7f0104..83ee9c3 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -63,7 +63,7 @@
           || candidate == "EXC_ARITHMETIC"
           || candidate == "EXC_RESOURCE"
           || candidate == "EXC_GUARD")) {
-      error.SetErrorStringWithFormat("invalid exception type: '%s'", 
+      error.SetErrorStringWithFormat("invalid exception type: '%s'",
           candidate.str().c_str());
       return error;
     }
@@ -140,7 +140,7 @@
     assert(option_value);
     return option_value->GetCurrentValue();
   }
-    
+
   OptionValueString *GetIgnoredExceptionValue() {
     const uint32_t idx = ePropertyIgnoredExceptions;
     OptionValueString *option_value =
@@ -172,7 +172,7 @@
 
 Args
 PlatformDarwin::GetExtraStartupCommands() {
-  std::string ignored_exceptions 
+  std::string ignored_exceptions
       = GetGlobalProperties().GetIgnoredExceptions();
   if (ignored_exceptions.empty())
     return {};
@@ -308,7 +308,7 @@
               if (module_spec.GetFilename() == filename_no_extension)
                 break;
 
-              module_spec.GetFilename() = filename_no_extension;
+              module_spec.SetFilename(filename_no_extension);
             }
           }
         }
@@ -1138,7 +1138,7 @@
       xcode_lldb_resources.AppendPathComponent("Resources");
       if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
         FileSpec dir;
-        dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
+        dir.SetDirectory(xcode_lldb_resources.GetPathAsConstString());
         g_executable_dirs.push_back(dir);
       }
     }
@@ -1151,8 +1151,7 @@
       cmd_line_lldb_resources.AppendPathComponent("Resources");
       if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {
         FileSpec dir;
-        dir.GetDirectory().SetCString(
-            cmd_line_lldb_resources.GetPath().c_str());
+        dir.SetDirectory(cmd_line_lldb_resources.GetPathAsConstString());
         g_executable_dirs.push_back(dir);
       }
     }
@@ -1162,8 +1161,8 @@
   // are looking for
   for (const auto &executable_dir : g_executable_dirs) {
     FileSpec executable_file;
-    executable_file.GetDirectory() = executable_dir.GetDirectory();
-    executable_file.GetFilename().SetCString(basename);
+    executable_file.SetDirectory(executable_dir.GetDirectory());
+    executable_file.SetFilename(basename);
     if (FileSystem::Instance().Exists(executable_file))
       return executable_file;
   }
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index b3eafec..337e3bb 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -615,7 +615,7 @@
   FileSpec dsym_fspec = kext_bundle_filepath;
   std::string filename = dsym_fspec.GetFilename().AsCString();
   filename += ".dSYM";
-  dsym_fspec.GetFilename() = ConstString(filename);
+  dsym_fspec.SetFilename(filename);
   if (FileSystem::Instance().IsDirectory(dsym_fspec)) {
     return true;
   }
@@ -652,7 +652,7 @@
   FileSpec kernel_dsym = kernel_binary;
   std::string filename = kernel_binary.GetFilename().AsCString();
   filename += ".dSYM";
-  kernel_dsym.GetFilename() = ConstString(filename);
+  kernel_dsym.SetFilename(filename);
   return FileSystem::Instance().IsDirectory(kernel_dsym);
 }
 
@@ -670,8 +670,7 @@
 
   FileSpec binary_filespec = kernel_dsym;
   // Chop off the '.dSYM' extension on the filename
-  binary_filespec.GetFilename() =
-      binary_filespec.GetFileNameStrippingExtension();
+  binary_filespec.SetFilename(binary_filespec.GetFileNameStrippingExtension());
 
   // Is there a binary next to this this?  Then return false.
   if (FileSystem::Instance().Exists(binary_filespec))
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 2438661..aa03583 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -177,7 +177,7 @@
     if (m_gdb_client_up->GetWorkingDir(working_dir) && log)
       LLDB_LOGF(log,
                 "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
-                working_dir.GetCString());
+                working_dir.GetPath().c_str());
     return working_dir;
   } else {
     return Platform::GetRemoteWorkingDirectory();
@@ -191,7 +191,7 @@
     // will for use to re-read it
     Log *log = GetLog(LLDBLog::Platform);
     LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
-              working_dir.GetCString());
+              working_dir.GetPath().c_str());
     return m_gdb_client_up->SetWorkingDir(working_dir) == 0;
   } else
     return Platform::SetRemoteWorkingDirectory(working_dir);
@@ -546,7 +546,8 @@
   LLDB_LOGF(log,
             "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
             "error = %u (%s)",
-            file_spec.GetCString(), mode, error.GetError(), error.AsCString());
+            file_spec.GetPath().c_str(), mode, error.GetError(),
+            error.AsCString());
   return error;
 }
 
@@ -560,7 +561,7 @@
   LLDB_LOGF(log,
             "PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
             "file_permissions=%o) error = %u (%s)",
-            file_spec.GetCString(), file_permissions, error.GetError(),
+            file_spec.GetPath().c_str(), file_permissions, error.GetError(),
             error.AsCString());
   return error;
 }
@@ -575,7 +576,7 @@
   LLDB_LOGF(log,
             "PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
             "file_permissions=%o) error = %u (%s)",
-            file_spec.GetCString(), file_permissions, error.GetError(),
+            file_spec.GetPath().c_str(), file_permissions, error.GetError(),
             error.AsCString());
   return error;
 }
@@ -644,7 +645,7 @@
   LLDB_LOGF(log,
             "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
             "error = %u (%s)",
-            src.GetCString(), dst.GetCString(), error.GetError(),
+            src.GetPath().c_str(), dst.GetPath().c_str(), error.GetError(),
             error.AsCString());
   return error;
 }
@@ -655,7 +656,7 @@
   Status error = m_gdb_client_up->Unlink(file_spec);
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
-            file_spec.GetCString(), error.GetError(), error.AsCString());
+            file_spec.GetPath().c_str(), error.GetError(), error.AsCString());
   return error;
 }
 
diff --git a/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index a6d7500..2abb09c 100644
--- a/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -378,7 +378,7 @@
     }
   }
   return Status("Module (%s) not found in process %" PRIu64 "!",
-                module_file_spec.GetCString(), GetID());
+                module_file_spec.GetPath().c_str(), GetID());
 }
 
 Status
@@ -398,7 +398,7 @@
     }
   }
   return Status("Can't get loaded address of file (%s) in process %" PRIu64 "!",
-                file_spec.GetCString(), GetID());
+                file_spec.GetPath().c_str(), GetID());
 }
 
 void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
diff --git a/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp b/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index 2aa7de6..dea1cea 100644
--- a/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -117,7 +117,7 @@
     FileSystem::Instance().Resolve(working_dir);
     if (!FileSystem::Instance().IsDirectory(working_dir)) {
       result.SetErrorStringWithFormat("No such file or directory: %s",
-                                      working_dir.GetCString());
+                                      working_dir.GetPath().c_str());
       return result;
     }
   }
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 2a58f20..f750ad9 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1138,7 +1138,8 @@
   response.PutChar(';');
 
   response.PutCString("file_path:");
-  response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
+  response.PutStringAsRawHex8(
+        matched_module_spec.GetFileSpec().GetPath().c_str());
   response.PutChar(';');
   response.PutCString("file_offset:");
   response.PutHex64(file_offset);
@@ -1213,7 +1214,7 @@
       proc_info.GetUserID(), proc_info.GetGroupID(),
       proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
   response.PutCString("name:");
-  response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+  response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());
 
   response.PutChar(';');
   response.PutCString("args:");
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 5804c13..20650b5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1503,7 +1503,7 @@
   FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
   if (working_dir) {
     StreamString response;
-    response.PutStringAsRawHex8(working_dir.GetCString());
+    response.PutStringAsRawHex8(working_dir.GetPath().c_str());
     return SendPacketNoLock(response.GetString());
   }
 
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 6f137d0..bc1119f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -587,7 +587,8 @@
   FileSpec socket_path_spec(GetDomainSocketDir());
   socket_path_spec.AppendPathComponent(socket_name.c_str());
 
-  llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
+  llvm::sys::fs::createUniqueFile(socket_path_spec.GetPath().c_str(),
+                                  socket_path);
   return FileSpec(socket_path.c_str());
 }
 
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3e1a6fb..b7de05d 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -745,9 +745,9 @@
                 "ProcessGDBRemote::%s provided with STDIO paths via "
                 "launch_info: stdin=%s, stdout=%s, stderr=%s",
                 __FUNCTION__,
-                stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
-                stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-                stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+                stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",
+                stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",
+                stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");
     else
       LLDB_LOGF(log,
                 "ProcessGDBRemote::%s no STDIO paths given via launch_info",
@@ -810,18 +810,18 @@
           "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
           "stderr=%s",
           __FUNCTION__,
-          stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
-          stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-          stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+          stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",
+          stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",
+          stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");
     }
 
     LLDB_LOGF(log,
               "ProcessGDBRemote::%s final STDIO paths after all "
               "adjustments: stdin=%s, stdout=%s, stderr=%s",
               __FUNCTION__,
-              stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
-              stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-              stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+              stdin_file_spec ? stdin_file_spec.GetPath().c_str() : "<null>",
+              stdout_file_spec ? stdout_file_spec.GetPath().c_str() : "<null>",
+              stderr_file_spec ? stderr_file_spec.GetPath().c_str() : "<null>");
 
     if (stdin_file_spec)
       m_gdb_comm.SetSTDIN(stdin_file_spec);
@@ -962,12 +962,12 @@
           entry.c_str(), response);
     }
   };
-  
+
   PlatformSP platform_sp = GetTarget().GetPlatform();
   if (platform_sp) {
     handle_cmds(platform_sp->GetExtraStartupCommands());
   }
-  
+
   // Then dispatch any process commands:
   handle_cmds(GetExtraStartupCommands());
 
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 64219e1..5c56f03 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -568,7 +568,7 @@
       partial_module_spec.GetUUID().Clear();
       module_sp = GetOrCreateModule(uuid, name, partial_module_spec);
       if (!module_sp) {
-        partial_module_spec.GetFileSpec().GetDirectory().Clear();
+        partial_module_spec.GetFileSpec().ClearDirectory();
         module_sp = GetOrCreateModule(uuid, name, partial_module_spec);
       }
     }
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index a21adcfb..6558993 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -241,7 +241,7 @@
   llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
 
 #if defined(_WIN32)
-  // This will be injected directly through FileSpec.GetDirectory().SetString(),
+  // This will be injected directly through FileSpec.SetDirectory(),
   // so we need to normalize manually.
   std::replace(path.begin(), path.end(), '\\', '/');
 #endif
@@ -260,7 +260,7 @@
 #else
     ComputePythonDir(path);
 #endif
-    spec.GetDirectory().SetString(path);
+    spec.SetDirectory(path);
     return spec;
   }();
   return g_spec;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8ee709d..9d68cb1 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -993,10 +993,9 @@
                                   dwarf_cu.GetOffset()))
     return false;
 
+  std::string comp_dir = dwarf_cu.GetCompilationDirectory().GetPath();
   support_files = ParseSupportFilesFromPrologue(
-      module, prologue, dwarf_cu.GetPathStyle(),
-      dwarf_cu.GetCompilationDirectory().GetCString());
-
+      module, prologue, dwarf_cu.GetPathStyle(), comp_dir);
   return true;
 }
 
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 7e10e31..fbaea33 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -120,7 +120,7 @@
   if (!FileSystem::Instance().Exists(pdb_file)) {
     const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent();
     const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString();
-    pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetCString();
+    pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetPathAsConstString().GetStringRef();
   }
 
   // If the file is not a PDB or if it doesn't have a matching GUID, fail.
diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp
index 668276a..09a5fc9 100644
--- a/source/Symbol/Symbol.cpp
+++ b/source/Symbol/Symbol.cpp
@@ -425,7 +425,7 @@
       // Next try and find the module by basename in case environment variables
       // or other runtime trickery causes shared libraries to be loaded from
       // alternate paths
-      module_spec.GetFileSpec().GetDirectory().Clear();
+      module_spec.GetFileSpec().ClearDirectory();
       module_sp = target.GetImages().FindFirstModule(module_spec);
     }
   }
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index a10db07..2ccc248 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -812,9 +812,7 @@
                 reexport_module_sp =
                     target.GetImages().FindFirstModule(reexport_module_spec);
                 if (!reexport_module_sp) {
-                  reexport_module_spec.GetPlatformFileSpec()
-                      .GetDirectory()
-                      .Clear();
+                  reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
                   reexport_module_sp =
                       target.GetImages().FindFirstModule(reexport_module_spec);
                 }
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 559f766..61c4cba 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -317,7 +317,7 @@
     strm.Format("   Sysroot: {0}\n", GetSDKRootDirectory());
   }
   if (GetWorkingDirectory()) {
-    strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
+    strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetPath().c_str());
   }
   if (!IsConnected())
     return;
@@ -434,12 +434,13 @@
     // make the new directory and get in there
     FileSpec dst_dir = rc_baton->dst;
     if (!dst_dir.GetFilename())
-      dst_dir.GetFilename() = src.GetLastPathComponent();
+      dst_dir.SetFilename(src.GetLastPathComponent());
     Status error = rc_baton->platform_ptr->MakeDirectory(
         dst_dir, lldb::eFilePermissionsDirectoryDefault);
     if (error.Fail()) {
       rc_baton->error.SetErrorStringWithFormat(
-          "unable to setup directory %s on remote end", dst_dir.GetCString());
+          "unable to setup directory %s on remote end",
+          dst_dir.GetPath().c_str());
       return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out
     }
 
@@ -449,7 +450,7 @@
     // Make a filespec that only fills in the directory of a FileSpec so when
     // we enumerate we can quickly fill in the filename for dst copies
     FileSpec recurse_dst;
-    recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
+    recurse_dst.SetDirectory(dst_dir.GetPathAsConstString());
     RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr,
                                   Status()};
     FileSystem::Instance().EnumerateDirectory(src_dir_path, true, true, true,
@@ -465,7 +466,7 @@
     // copy the file and keep going
     FileSpec dst_file = rc_baton->dst;
     if (!dst_file.GetFilename())
-      dst_file.GetFilename() = src.GetFilename();
+      dst_file.SetFilename(src.GetFilename());
 
     FileSpec src_resolved;
 
@@ -487,7 +488,7 @@
     // copy the file and keep going
     FileSpec dst_file = rc_baton->dst;
     if (!dst_file.GetFilename())
-      dst_file.GetFilename() = src.GetFilename();
+      dst_file.SetFilename(src.GetFilename());
     Status err = rc_baton->platform_ptr->PutFile(src, dst_file);
     if (err.Fail()) {
       rc_baton->error.SetErrorString(err.AsCString());
@@ -514,7 +515,7 @@
   FileSpec fixed_dst(dst);
 
   if (!fixed_dst.GetFilename())
-    fixed_dst.GetFilename() = src.GetFilename();
+    fixed_dst.SetFilename(src.GetFilename());
 
   FileSpec working_dir = GetWorkingDirectory();
 
@@ -522,7 +523,7 @@
     if (dst.GetDirectory()) {
       const char first_dst_dir_char = dst.GetDirectory().GetCString()[0];
       if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') {
-        fixed_dst.GetDirectory() = dst.GetDirectory();
+        fixed_dst.SetDirectory(dst.GetDirectory());
       }
       // If the fixed destination file doesn't have a directory yet, then we
       // must have a relative path. We will resolve this relative path against
@@ -533,7 +534,7 @@
         if (working_dir) {
           relative_spec = working_dir;
           relative_spec.AppendPathComponent(dst.GetPath());
-          fixed_dst.GetDirectory() = relative_spec.GetDirectory();
+          fixed_dst.SetDirectory(relative_spec.GetDirectory());
         } else {
           error.SetErrorStringWithFormat(
               "platform working directory must be valid for relative path '%s'",
@@ -543,7 +544,7 @@
       }
     } else {
       if (working_dir) {
-        fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
+        fixed_dst.SetDirectory(working_dir.GetPathAsConstString());
       } else {
         error.SetErrorStringWithFormat(
             "platform working directory must be valid for relative path '%s'",
@@ -553,7 +554,7 @@
     }
   } else {
     if (working_dir) {
-      fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
+      fixed_dst.SetDirectory(working_dir.GetPathAsConstString());
     } else {
       error.SetErrorStringWithFormat("platform working directory must be valid "
                                      "when destination directory is empty");
@@ -580,7 +581,7 @@
         // Make a filespec that only fills in the directory of a FileSpec so
         // when we enumerate we can quickly fill in the filename for dst copies
         FileSpec recurse_dst;
-        recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString());
+        recurse_dst.SetDirectory(fixed_dst.GetPathAsConstString());
         std::string src_dir_path(src.GetPath());
         RecurseCopyBaton baton = {recurse_dst, this, Status()};
         FileSystem::Instance().EnumerateDirectory(
@@ -737,7 +738,7 @@
 bool Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir) {
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOGF(log, "Platform::SetRemoteWorkingDirectory('%s')",
-            working_dir.GetCString());
+            working_dir.GetPath().c_str());
   m_working_dir = working_dir;
   return true;
 }
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index ab6f231..af511d6 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -107,7 +107,7 @@
   SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
   SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
   SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
-  
+
   CheckInWithManager();
 
   LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()",
@@ -2086,11 +2086,12 @@
     // a suitable image.
     if (m_image_search_paths.GetSize()) {
       ModuleSpec transformed_spec(module_spec);
+      ConstString transformed_dir;
       if (m_image_search_paths.RemapPath(
-              module_spec.GetFileSpec().GetDirectory(),
-              transformed_spec.GetFileSpec().GetDirectory())) {
-        transformed_spec.GetFileSpec().GetFilename() =
-            module_spec.GetFileSpec().GetFilename();
+              module_spec.GetFileSpec().GetDirectory(), transformed_dir)) {
+        transformed_spec.GetFileSpec().SetDirectory(transformed_dir);
+        transformed_spec.GetFileSpec().SetFilename(
+              module_spec.GetFileSpec().GetFilename());
         error = ModuleList::GetSharedModule(transformed_spec, module_sp,
                                             &search_paths, &old_modules,
                                             &did_create_module);
@@ -3220,8 +3221,8 @@
   // the process to attach to by default
   if (!attach_info.ProcessInfoSpecified()) {
     if (old_exec_module_sp)
-      attach_info.GetExecutableFile().GetFilename() =
-          old_exec_module_sp->GetPlatformFileSpec().GetFilename();
+      attach_info.GetExecutableFile().SetFilename(
+            old_exec_module_sp->GetPlatformFileSpec().GetFilename());
 
     if (!attach_info.ProcessInfoSpecified()) {
       return Status("no process specified, create a target with a file, or "
@@ -3363,7 +3364,7 @@
   }
 }
 
-void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify, 
+void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify,
                             LazyBool stop) {
     if (name.empty())
       return;
@@ -3378,38 +3379,38 @@
     elem.stop = stop;
 }
 
-bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp, 
+bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp,
                                           const DummySignalElement &elem) {
   if (!signals_sp)
     return false;
 
-  int32_t signo 
+  int32_t signo
       = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());
   if (signo == LLDB_INVALID_SIGNAL_NUMBER)
     return false;
-    
+
   if (elem.second.pass == eLazyBoolYes)
     signals_sp->SetShouldSuppress(signo, false);
   else if (elem.second.pass == eLazyBoolNo)
     signals_sp->SetShouldSuppress(signo, true);
-  
+
   if (elem.second.notify == eLazyBoolYes)
     signals_sp->SetShouldNotify(signo, true);
   else if (elem.second.notify == eLazyBoolNo)
     signals_sp->SetShouldNotify(signo, false);
-  
+
   if (elem.second.stop == eLazyBoolYes)
     signals_sp->SetShouldStop(signo, true);
   else if (elem.second.stop == eLazyBoolNo)
     signals_sp->SetShouldStop(signo, false);
-  return true;  
+  return true;
 }
 
-bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp, 
+bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp,
                                           const DummySignalElement &elem) {
   if (!signals_sp)
     return false;
-  int32_t signo 
+  int32_t signo
       = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());
   if (signo == LLDB_INVALID_SIGNAL_NUMBER)
     return false;
@@ -3420,14 +3421,14 @@
   return true;
 }
 
-void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp, 
+void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp,
                                     StreamSP warning_stream_sp) {
   if (!signals_sp)
     return;
 
   for (const auto &elem : m_dummy_signals) {
     if (!UpdateSignalFromDummy(signals_sp, elem))
-      warning_stream_sp->Printf("Target signal '%s' not found in process\n", 
+      warning_stream_sp->Printf("Target signal '%s' not found in process\n",
           elem.first().str().c_str());
   }
 }
@@ -3460,7 +3461,7 @@
 void Target::PrintDummySignals(Stream &strm, Args &signal_args) {
   strm.Printf("NAME         PASS     STOP     NOTIFY\n");
   strm.Printf("===========  =======  =======  =======\n");
-  
+
   auto str_for_lazy = [] (LazyBool lazy) -> const char * {
     switch (lazy) {
       case eLazyBoolCalculate: return "not set";
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index 8290369..5d60c1e 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -354,7 +354,7 @@
   }
   if (file.GetDirectory()) {
     FileSpec file_dir;
-    file_dir.GetDirectory() = file.GetDirectory();
+    file_dir.SetDirectory(file.GetDirectory());
     target_sp->AppendExecutableSearchPaths(file_dir);
   }
 
diff --git a/source/Target/Trace.cpp b/source/Target/Trace.cpp
index ac83273..6822025 100644
--- a/source/Target/Trace.cpp
+++ b/source/Target/Trace.cpp
@@ -437,7 +437,7 @@
   if (std::error_code err = trace_or_error.getError())
     return createStringError(
         inconvertibleErrorCode(), "Failed fetching trace-related file %s. %s",
-        file.GetCString(), toString(errorCodeToError(err)).c_str());
+        file.GetPath().c_str(), toString(errorCodeToError(err)).c_str());
 
   MemoryBuffer &data = **trace_or_error;
   ArrayRef<uint8_t> array_ref(
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index c0dbc29..7646d33 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -330,17 +330,29 @@
 
 FileSpec::Style FileSpec::GetPathStyle() const { return m_style; }
 
-// Directory string get accessor.
-ConstString &FileSpec::GetDirectory() { return m_directory; }
+void FileSpec::SetDirectory(ConstString directory) {
+  m_directory = directory;
+}
 
-// Directory string const get accessor.
-ConstString FileSpec::GetDirectory() const { return m_directory; }
+void FileSpec::SetDirectory(llvm::StringRef directory) {
+  m_directory = ConstString(directory);
+}
 
-// Filename string get accessor.
-ConstString &FileSpec::GetFilename() { return m_filename; }
+void FileSpec::SetFilename(ConstString filename) {
+  m_filename = filename;
+}
 
-// Filename string const get accessor.
-ConstString FileSpec::GetFilename() const { return m_filename; }
+void FileSpec::SetFilename(llvm::StringRef filename) {
+  m_filename = ConstString(filename);
+}
+
+void FileSpec::ClearFilename() {
+  m_filename.Clear();
+}
+
+void FileSpec::ClearDirectory() {
+  m_directory.Clear();
+}
 
 // Extract the directory and path into a fixed buffer. This is needed as the
 // directory and path are stored in separate string values.
@@ -360,8 +372,8 @@
   return static_cast<std::string>(result);
 }
 
-const char *FileSpec::GetCString(bool denormalize) const {
-  return ConstString{GetPath(denormalize)}.AsCString(nullptr);
+ConstString FileSpec::GetPathAsConstString(bool denormalize) const {
+  return ConstString{GetPath(denormalize)};
 }
 
 void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
@@ -476,7 +488,7 @@
 }
 
 bool FileSpec::IsAbsolute() const {
-  llvm::SmallString<64> current_path;
+llvm::SmallString<64> current_path;
   GetPath(current_path, false);
 
   // Early return if the path is empty.
diff --git a/tools/lldb-server/lldb-platform.cpp b/tools/lldb-server/lldb-platform.cpp
index 1a969ee..9f8b4c7 100644
--- a/tools/lldb-server/lldb-platform.cpp
+++ b/tools/lldb-server/lldb-platform.cpp
@@ -100,7 +100,7 @@
   Status error(llvm::sys::fs::create_directory(temp_file_spec.GetPath()));
   if (error.Fail())
     return Status("Failed to create directory %s: %s",
-                  temp_file_spec.GetCString(), error.AsCString());
+                  temp_file_spec.GetPath().c_str(), error.AsCString());
 
   llvm::SmallString<64> temp_file_path;
   temp_file_spec.AppendPathComponent("port-file.%%%%%%");
diff --git a/tools/lldb-test/lldb-test.cpp b/tools/lldb-test/lldb-test.cpp
index bc3d536..8c52648 100644
--- a/tools/lldb-test/lldb-test.cpp
+++ b/tools/lldb-test/lldb-test.cpp
@@ -925,7 +925,7 @@
       for (size_t I = 0; I < Files.GetSize(); ++I) {
         AutoIndent Indent(Printer, 2);
         Printer.formatLine("Name: {0}",
-                           Files.GetFileSpecAtIndex(I).GetCString());
+                           Files.GetFileSpecAtIndex(I).GetPath());
       }
       Printer.NewLine();
     }
diff --git a/unittests/Target/FindFileTest.cpp b/unittests/Target/FindFileTest.cpp
index 9e99160..b74d557 100644
--- a/unittests/Target/FindFileTest.cpp
+++ b/unittests/Target/FindFileTest.cpp
@@ -47,7 +47,7 @@
                              llvm::ArrayRef<Matches> matches,
                              llvm::ArrayRef<FileSpec> fails) {
   for (const auto &fail : fails) {
-    SCOPED_TRACE(fail.GetCString());
+    SCOPED_TRACE(fail.GetPath().c_str());
     EXPECT_FALSE(map.FindFile(fail));
   }
 
diff --git a/unittests/Target/ModuleCacheTest.cpp b/unittests/Target/ModuleCacheTest.cpp
index 273338c..d5a7b8d 100644
--- a/unittests/Target/ModuleCacheTest.cpp
+++ b/unittests/Target/ModuleCacheTest.cpp
@@ -72,12 +72,12 @@
 static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
   FileSpec uuid_view = GetUuidView(cache_dir);
   EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view))
-      << "uuid_view is: " << uuid_view.GetCString();
+      << "uuid_view is: " << uuid_view.GetPath();
   EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view));
 
   FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
   EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view))
-      << "sysroot_view is: " << sysroot_view.GetCString();
+      << "sysroot_view is: " << sysroot_view.GetPath();
   EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view));
 }
 
@@ -97,10 +97,10 @@
       [&download_called, this](const ModuleSpec &module_spec,
                                const FileSpec &tmp_download_file_spec) {
         download_called = true;
-        EXPECT_STREQ(GetDummyRemotePath().GetCString(),
-                     module_spec.GetFileSpec().GetCString());
+        EXPECT_STREQ(GetDummyRemotePath().GetPath().c_str(),
+                     module_spec.GetFileSpec().GetPath().c_str());
         std::error_code ec = llvm::sys::fs::copy_file(
-            s_test_executable, tmp_download_file_spec.GetCString());
+            s_test_executable, tmp_download_file_spec.GetPath());
         EXPECT_FALSE(ec);
         return Status();
       },
@@ -118,8 +118,8 @@
   module_sp->FindFunctionSymbols(ConstString("boom"), eFunctionNameTypeFull,
                                  sc_list);
   EXPECT_EQ(1u, sc_list.GetSize());
-  EXPECT_STREQ(GetDummyRemotePath().GetCString(),
-               module_sp->GetPlatformFileSpec().GetCString());
+  EXPECT_STREQ(GetDummyRemotePath().GetPath().c_str(),
+               module_sp->GetPlatformFileSpec().GetPath().c_str());
   EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
 }
 
@@ -140,7 +140,7 @@
   std::error_code ec =
       llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
   ASSERT_FALSE(ec);
-  ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
+  ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetPath().c_str());
   ASSERT_FALSE(ec);
 
   const bool expect_download = false;
diff --git a/unittests/Utility/FileSpecTest.cpp b/unittests/Utility/FileSpecTest.cpp
index f92be63..9260262 100644
--- a/unittests/Utility/FileSpecTest.cpp
+++ b/unittests/Utility/FileSpecTest.cpp
@@ -22,92 +22,92 @@
 
 TEST(FileSpecTest, FileAndDirectoryComponents) {
   FileSpec fs_posix("/foo/bar", FileSpec::Style::posix);
-  EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
+  EXPECT_STREQ("/foo/bar", fs_posix.GetPath().c_str());
   EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
   EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
 
   FileSpec fs_windows("F:\\bar", FileSpec::Style::windows);
-  EXPECT_STREQ("F:\\bar", fs_windows.GetCString());
-  // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetCString()); // It returns
+  EXPECT_STREQ("F:\\bar", fs_windows.GetPath().c_str());
+  // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetPath().c_str()); // It returns
   // "F:/"
   EXPECT_STREQ("bar", fs_windows.GetFilename().GetCString());
 
   FileSpec fs_posix_root("/", FileSpec::Style::posix);
-  EXPECT_STREQ("/", fs_posix_root.GetCString());
+  EXPECT_STREQ("/", fs_posix_root.GetPath().c_str());
   EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString());
   EXPECT_STREQ("/", fs_posix_root.GetFilename().GetCString());
 
   FileSpec fs_net_drive("//net", FileSpec::Style::posix);
-  EXPECT_STREQ("//net", fs_net_drive.GetCString());
+  EXPECT_STREQ("//net", fs_net_drive.GetPath().c_str());
   EXPECT_EQ(nullptr, fs_net_drive.GetDirectory().GetCString());
   EXPECT_STREQ("//net", fs_net_drive.GetFilename().GetCString());
 
   FileSpec fs_net_root("//net/", FileSpec::Style::posix);
-  EXPECT_STREQ("//net/", fs_net_root.GetCString());
+  EXPECT_STREQ("//net/", fs_net_root.GetPath().c_str());
   EXPECT_STREQ("//net", fs_net_root.GetDirectory().GetCString());
   EXPECT_STREQ("/", fs_net_root.GetFilename().GetCString());
 
   FileSpec fs_windows_drive("F:", FileSpec::Style::windows);
-  EXPECT_STREQ("F:", fs_windows_drive.GetCString());
+  EXPECT_STREQ("F:", fs_windows_drive.GetPath().c_str());
   EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString());
   EXPECT_STREQ("F:", fs_windows_drive.GetFilename().GetCString());
 
   FileSpec fs_windows_root("F:\\", FileSpec::Style::windows);
-  EXPECT_STREQ("F:\\", fs_windows_root.GetCString());
+  EXPECT_STREQ("F:\\", fs_windows_root.GetPath().c_str());
   EXPECT_STREQ("F:", fs_windows_root.GetDirectory().GetCString());
   // EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It
   // returns "/"
 
   FileSpec fs_posix_long("/foo/bar/baz", FileSpec::Style::posix);
-  EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetCString());
+  EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetPath().c_str());
   EXPECT_STREQ("/foo/bar", fs_posix_long.GetDirectory().GetCString());
   EXPECT_STREQ("baz", fs_posix_long.GetFilename().GetCString());
 
   FileSpec fs_windows_long("F:\\bar\\baz", FileSpec::Style::windows);
-  EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetCString());
+  EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetPath().c_str());
   // EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It
   // returns "F:/bar"
   EXPECT_STREQ("baz", fs_windows_long.GetFilename().GetCString());
 
   FileSpec fs_posix_trailing_slash("/foo/bar/", FileSpec::Style::posix);
-  EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetCString());
+  EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetPath().c_str());
   EXPECT_STREQ("/foo", fs_posix_trailing_slash.GetDirectory().GetCString());
   EXPECT_STREQ("bar", fs_posix_trailing_slash.GetFilename().GetCString());
 
   FileSpec fs_windows_trailing_slash("F:\\bar\\", FileSpec::Style::windows);
-  EXPECT_STREQ("F:\\bar", fs_windows_trailing_slash.GetCString());
+  EXPECT_STREQ("F:\\bar", fs_windows_trailing_slash.GetPath().c_str());
   EXPECT_STREQ("bar", fs_windows_trailing_slash.GetFilename().GetCString());
 }
 
 TEST(FileSpecTest, AppendPathComponent) {
   FileSpec fs_posix("/foo", FileSpec::Style::posix);
   fs_posix.AppendPathComponent("bar");
-  EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
+  EXPECT_STREQ("/foo/bar", fs_posix.GetPath().c_str());
   EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
   EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
 
   FileSpec fs_posix_2("/foo", FileSpec::Style::posix);
   fs_posix_2.AppendPathComponent("//bar/baz");
-  EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetCString());
+  EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetPath().c_str());
   EXPECT_STREQ("/foo/bar", fs_posix_2.GetDirectory().GetCString());
   EXPECT_STREQ("baz", fs_posix_2.GetFilename().GetCString());
 
   FileSpec fs_windows("F:\\bar", FileSpec::Style::windows);
   fs_windows.AppendPathComponent("baz");
-  EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
+  EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetPath().c_str());
   // EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It
   // returns "F:/bar"
   EXPECT_STREQ("baz", fs_windows.GetFilename().GetCString());
 
   FileSpec fs_posix_root("/", FileSpec::Style::posix);
   fs_posix_root.AppendPathComponent("bar");
-  EXPECT_STREQ("/bar", fs_posix_root.GetCString());
+  EXPECT_STREQ("/bar", fs_posix_root.GetPath().c_str());
   EXPECT_STREQ("/", fs_posix_root.GetDirectory().GetCString());
   EXPECT_STREQ("bar", fs_posix_root.GetFilename().GetCString());
 
   FileSpec fs_windows_root("F:\\", FileSpec::Style::windows);
   fs_windows_root.AppendPathComponent("bar");
-  EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
+  EXPECT_STREQ("F:\\bar", fs_windows_root.GetPath().c_str());
   // EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It
   // returns "F:/"
   EXPECT_STREQ("bar", fs_windows_root.GetFilename().GetCString());
@@ -115,7 +115,7 @@
 
 TEST(FileSpecTest, CopyByAppendingPathComponent) {
   FileSpec fs = PosixSpec("/foo").CopyByAppendingPathComponent("bar");
-  EXPECT_STREQ("/foo/bar", fs.GetCString());
+  EXPECT_STREQ("/foo/bar", fs.GetPath().c_str());
   EXPECT_STREQ("/foo", fs.GetDirectory().GetCString());
   EXPECT_STREQ("bar", fs.GetFilename().GetCString());
 }
@@ -123,23 +123,23 @@
 TEST(FileSpecTest, PrependPathComponent) {
   FileSpec fs_posix("foo", FileSpec::Style::posix);
   fs_posix.PrependPathComponent("/bar");
-  EXPECT_STREQ("/bar/foo", fs_posix.GetCString());
+  EXPECT_STREQ("/bar/foo", fs_posix.GetPath().c_str());
 
   FileSpec fs_posix_2("foo/bar", FileSpec::Style::posix);
   fs_posix_2.PrependPathComponent("/baz");
-  EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetCString());
+  EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetPath().c_str());
 
   FileSpec fs_windows("baz", FileSpec::Style::windows);
   fs_windows.PrependPathComponent("F:\\bar");
-  EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
+  EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetPath().c_str());
 
   FileSpec fs_posix_root("bar", FileSpec::Style::posix);
   fs_posix_root.PrependPathComponent("/");
-  EXPECT_STREQ("/bar", fs_posix_root.GetCString());
+  EXPECT_STREQ("/bar", fs_posix_root.GetPath().c_str());
 
   FileSpec fs_windows_root("bar", FileSpec::Style::windows);
   fs_windows_root.PrependPathComponent("F:\\");
-  EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
+  EXPECT_STREQ("F:\\bar", fs_windows_root.GetPath().c_str());
 }
 
 TEST(FileSpecTest, EqualSeparator) {
@@ -343,44 +343,44 @@
 
 TEST(FileSpecTest, RemoveLastPathComponent) {
   FileSpec fs_posix("/foo/bar/baz", FileSpec::Style::posix);
-  EXPECT_STREQ("/foo/bar/baz", fs_posix.GetCString());
+  EXPECT_STREQ("/foo/bar/baz", fs_posix.GetPath().c_str());
   EXPECT_TRUE(fs_posix.RemoveLastPathComponent());
-  EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
+  EXPECT_STREQ("/foo/bar", fs_posix.GetPath().c_str());
   EXPECT_TRUE(fs_posix.RemoveLastPathComponent());
-  EXPECT_STREQ("/foo", fs_posix.GetCString());
+  EXPECT_STREQ("/foo", fs_posix.GetPath().c_str());
   EXPECT_TRUE(fs_posix.RemoveLastPathComponent());
-  EXPECT_STREQ("/", fs_posix.GetCString());
+  EXPECT_STREQ("/", fs_posix.GetPath().c_str());
   EXPECT_FALSE(fs_posix.RemoveLastPathComponent());
-  EXPECT_STREQ("/", fs_posix.GetCString());
+  EXPECT_STREQ("/", fs_posix.GetPath().c_str());
 
   FileSpec fs_posix_relative("./foo/bar/baz", FileSpec::Style::posix);
-  EXPECT_STREQ("foo/bar/baz", fs_posix_relative.GetCString());
+  EXPECT_STREQ("foo/bar/baz", fs_posix_relative.GetPath().c_str());
   EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent());
-  EXPECT_STREQ("foo/bar", fs_posix_relative.GetCString());
+  EXPECT_STREQ("foo/bar", fs_posix_relative.GetPath().c_str());
   EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent());
-  EXPECT_STREQ("foo", fs_posix_relative.GetCString());
+  EXPECT_STREQ("foo", fs_posix_relative.GetPath().c_str());
   EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent());
-  EXPECT_STREQ("foo", fs_posix_relative.GetCString());
+  EXPECT_STREQ("foo", fs_posix_relative.GetPath().c_str());
 
   FileSpec fs_posix_relative2("./", FileSpec::Style::posix);
-  EXPECT_STREQ(".", fs_posix_relative2.GetCString());
+  EXPECT_STREQ(".", fs_posix_relative2.GetPath().c_str());
   EXPECT_FALSE(fs_posix_relative2.RemoveLastPathComponent());
-  EXPECT_STREQ(".", fs_posix_relative2.GetCString());
+  EXPECT_STREQ(".", fs_posix_relative2.GetPath().c_str());
   EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent());
-  EXPECT_STREQ(".", fs_posix_relative2.GetCString());
+  EXPECT_STREQ(".", fs_posix_relative2.GetPath().c_str());
 
   FileSpec fs_windows("C:\\foo\\bar\\baz", FileSpec::Style::windows);
-  EXPECT_STREQ("C:\\foo\\bar\\baz", fs_windows.GetCString());
+  EXPECT_STREQ("C:\\foo\\bar\\baz", fs_windows.GetPath().c_str());
   EXPECT_TRUE(fs_windows.RemoveLastPathComponent());
-  EXPECT_STREQ("C:\\foo\\bar", fs_windows.GetCString());
+  EXPECT_STREQ("C:\\foo\\bar", fs_windows.GetPath().c_str());
   EXPECT_TRUE(fs_windows.RemoveLastPathComponent());
-  EXPECT_STREQ("C:\\foo", fs_windows.GetCString());
+  EXPECT_STREQ("C:\\foo", fs_windows.GetPath().c_str());
   EXPECT_TRUE(fs_windows.RemoveLastPathComponent());
-  EXPECT_STREQ("C:\\", fs_windows.GetCString());
+  EXPECT_STREQ("C:\\", fs_windows.GetPath().c_str());
   EXPECT_TRUE(fs_windows.RemoveLastPathComponent());
-  EXPECT_STREQ("C:", fs_windows.GetCString());
+  EXPECT_STREQ("C:", fs_windows.GetPath().c_str());
   EXPECT_FALSE(fs_windows.RemoveLastPathComponent());
-  EXPECT_STREQ("C:", fs_windows.GetCString());
+  EXPECT_STREQ("C:", fs_windows.GetPath().c_str());
 }
 
 TEST(FileSpecTest, Equal) {