diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp
index dd0ecb4..9d70f40 100644
--- a/lldb/source/Commands/CommandCompletions.cpp
+++ b/lldb/source/Commands/CommandCompletions.cpp
@@ -37,447 +37,368 @@
 using namespace lldb_private;
 
 CommandCompletions::CommonCompletionElement
-CommandCompletions::g_common_completions[] =
-{
-    {eCustomCompletion,          nullptr},
-    {eSourceFileCompletion,      CommandCompletions::SourceFiles},
-    {eDiskFileCompletion,        CommandCompletions::DiskFiles},
-    {eDiskDirectoryCompletion,   CommandCompletions::DiskDirectories},
-    {eSymbolCompletion,          CommandCompletions::Symbols},
-    {eModuleCompletion,          CommandCompletions::Modules},
-    {eSettingsNameCompletion,    CommandCompletions::SettingsNames},
-    {ePlatformPluginCompletion,  CommandCompletions::PlatformPluginNames},
-    {eArchitectureCompletion,    CommandCompletions::ArchitectureNames},
-    {eVariablePathCompletion,    CommandCompletions::VariablePath},
-    {eNoCompletion,              nullptr}      // This one has to be last in the list.
+    CommandCompletions::g_common_completions[] = {
+        {eCustomCompletion, nullptr},
+        {eSourceFileCompletion, CommandCompletions::SourceFiles},
+        {eDiskFileCompletion, CommandCompletions::DiskFiles},
+        {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
+        {eSymbolCompletion, CommandCompletions::Symbols},
+        {eModuleCompletion, CommandCompletions::Modules},
+        {eSettingsNameCompletion, CommandCompletions::SettingsNames},
+        {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
+        {eArchitectureCompletion, CommandCompletions::ArchitectureNames},
+        {eVariablePathCompletion, CommandCompletions::VariablePath},
+        {eNoCompletion, nullptr} // This one has to be last in the list.
 };
 
-bool
-CommandCompletions::InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter,
-                                                    uint32_t completion_mask,
-                                                    const char *completion_str,
-                                                    int match_start_point,
-                                                    int max_return_elements,
-                                                    SearchFilter *searcher,
-                                                    bool &word_complete,
-                                                    StringList &matches)
-{
-    bool handled = false;
+bool CommandCompletions::InvokeCommonCompletionCallbacks(
+    CommandInterpreter &interpreter, uint32_t completion_mask,
+    const char *completion_str, int match_start_point, int max_return_elements,
+    SearchFilter *searcher, bool &word_complete, StringList &matches) {
+  bool handled = false;
 
-    if (completion_mask & eCustomCompletion)
-        return false;
+  if (completion_mask & eCustomCompletion)
+    return false;
 
-    for (int i = 0; ; i++)
-    {
-        if (g_common_completions[i].type == eNoCompletion)
-            break;
-         else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type
-                   && g_common_completions[i].callback != nullptr)
-         {
-            handled = true;
-            g_common_completions[i].callback (interpreter,
-                                              completion_str,
-                                              match_start_point,
-                                              max_return_elements,
-                                              searcher,
-                                              word_complete,
-                                              matches);
-        }
+  for (int i = 0;; i++) {
+    if (g_common_completions[i].type == eNoCompletion)
+      break;
+    else if ((g_common_completions[i].type & completion_mask) ==
+                 g_common_completions[i].type &&
+             g_common_completions[i].callback != nullptr) {
+      handled = true;
+      g_common_completions[i].callback(interpreter, completion_str,
+                                       match_start_point, max_return_elements,
+                                       searcher, word_complete, matches);
     }
-    return handled;
+  }
+  return handled;
 }
 
-int
-CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
-                                const char *partial_file_name,
-                                int match_start_point,
-                                int max_return_elements,
-                                SearchFilter *searcher,
-                                bool &word_complete,
-                                StringList &matches)
-{
-    word_complete = true;
-    // Find some way to switch "include support files..."
-    SourceFileCompleter completer (interpreter,
-                                   false, 
-                                   partial_file_name, 
-                                   match_start_point, 
-                                   max_return_elements,
-                                   matches);
-
-    if (searcher == nullptr)
-    {
-        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
-        SearchFilterForUnconstrainedSearches null_searcher (target_sp);
-        completer.DoCompletion (&null_searcher);
-    }
-    else
-    {
-        completer.DoCompletion (searcher);
-    }
-    return matches.GetSize();
-}
-
-typedef struct DiskFilesOrDirectoriesBaton
-{
-    const char *remainder;
-    char *partial_name_copy;
-    bool only_directories;
-    bool *saw_directory;
-    StringList *matches;
-    char *end_ptr;
-    size_t baselen;
-} DiskFilesOrDirectoriesBaton;
-
-FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type, const FileSpec &spec)
-{
-    const char *name = spec.GetFilename().AsCString();
-
-    const DiskFilesOrDirectoriesBaton *parameters = (DiskFilesOrDirectoriesBaton*)baton;
-    char *end_ptr = parameters->end_ptr;
-    char *partial_name_copy = parameters->partial_name_copy;
-    const char *remainder = parameters->remainder;
-
-    // Omit ".", ".." and any . files if the match string doesn't start with .
-    if (name[0] == '.')
-    {
-        if (name[1] == '\0')
-            return FileSpec::eEnumerateDirectoryResultNext;
-        else if (name[1] == '.' && name[2] == '\0')
-            return FileSpec::eEnumerateDirectoryResultNext;
-        else if (remainder[0] != '.')
-            return FileSpec::eEnumerateDirectoryResultNext;
-    }
-
-    // If we found a directory, we put a "/" at the end of the name.
-
-    if (remainder[0] == '\0' || strstr(name, remainder) == name)
-    {
-        if (strlen(name) + parameters->baselen >= PATH_MAX)
-            return FileSpec::eEnumerateDirectoryResultNext;
-
-        strcpy(end_ptr, name);
-
-        bool isa_directory = false;
-        if (file_type == FileSpec::eFileTypeDirectory)
-            isa_directory = true;
-        else if (file_type == FileSpec::eFileTypeSymbolicLink)
-        {
-            if (FileSpec(partial_name_copy, false).IsDirectory())
-                isa_directory = true;
-        }
-
-        if (isa_directory)
-        {
-            *parameters->saw_directory = true;
-            size_t len = strlen(parameters->partial_name_copy);
-            partial_name_copy[len] = '/';
-            partial_name_copy[len + 1] = '\0';
-        }
-        if (parameters->only_directories && !isa_directory)
-            return FileSpec::eEnumerateDirectoryResultNext;
-        parameters->matches->AppendString(partial_name_copy);
-    }
-
-    return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-static int
-DiskFilesOrDirectories(const char *partial_file_name,
-                       bool only_directories,
-                       bool &saw_directory,
-                       StringList &matches)
-{
-    // I'm going to  use the "glob" function with GLOB_TILDE for user directory expansion.  
-    // If it is not defined on your host system, you'll need to implement it yourself...
-    
-    size_t partial_name_len = strlen(partial_file_name);
-    
-    if (partial_name_len >= PATH_MAX)
-        return matches.GetSize();
-    
-    // This copy of the string will be cut up into the directory part, and the remainder.  end_ptr
-    // below will point to the place of the remainder in this string.  Then when we've resolved the
-    // containing directory, and opened it, we'll read the directory contents and overwrite the
-    // partial_name_copy starting from end_ptr with each of the matches.  Thus we will preserve
-    // the form the user originally typed.
-    
-    char partial_name_copy[PATH_MAX];
-    memcpy(partial_name_copy, partial_file_name, partial_name_len);
-    partial_name_copy[partial_name_len] = '\0';
-    
-    // We'll need to save a copy of the remainder for comparison, which we do here.
-    char remainder[PATH_MAX];
-    
-    // end_ptr will point past the last / in partial_name_copy, or if there is no slash to the beginning of the string.
-    char *end_ptr;
-    
-    end_ptr = strrchr(partial_name_copy, '/');
-    
-    // This will store the resolved form of the containing directory
-    llvm::SmallString<64> containing_part;
-    
-    if (end_ptr == nullptr)
-    {
-        // There's no directory.  If the thing begins with a "~" then this is a bare
-        // user name.
-        if (*partial_name_copy == '~')
-        {
-            // Nothing here but the user name.  We could just put a slash on the end, 
-            // but for completeness sake we'll resolve the user name and only put a slash
-            // on the end if it exists.
-            llvm::SmallString<64> resolved_username(partial_name_copy);
-            FileSpec::ResolveUsername (resolved_username);
-                                                          
-           // Not sure how this would happen, a username longer than PATH_MAX?  Still...
-            if (resolved_username.size() == 0)
-            {
-                // The user name didn't resolve, let's look in the password database for matches.
-                // The user name database contains duplicates, and is not in alphabetical order, so
-                // we'll use a set to manage that for us.
-                FileSpec::ResolvePartialUsername (partial_name_copy, matches);
-                if (matches.GetSize() > 0)
-                    saw_directory = true;
-                return matches.GetSize();
-            } 
-            else
-            {   
-                //The thing exists, put a '/' on the end, and return it...
-                // FIXME: complete user names here:
-                partial_name_copy[partial_name_len] = '/';
-                partial_name_copy[partial_name_len+1] = '\0';
-                matches.AppendString(partial_name_copy);
-                saw_directory = true;
-                return matches.GetSize();
-            }
-        }
-        else
-        {
-            // The containing part is the CWD, and the whole string is the remainder.
-            containing_part = ".";
-            strcpy(remainder, partial_name_copy);
-            end_ptr = partial_name_copy;
-        }
-    }
-    else
-    {
-        if (end_ptr == partial_name_copy)
-        {
-            // We're completing a file or directory in the root volume.
-            containing_part = "/";
-        }
-        else
-        {
-            containing_part.append(partial_name_copy, end_ptr);
-        }
-        // Push end_ptr past the final "/" and set remainder.
-        end_ptr++;
-        strcpy(remainder, end_ptr);
-    }
-    
-    // Look for a user name in the containing part, and if it's there, resolve it and stick the
-    // result back into the containing_part:
-
-    if (*partial_name_copy == '~')
-    {
-        FileSpec::ResolveUsername(containing_part);
-        // User name doesn't exist, we're not getting any further...
-        if (containing_part.empty())
-            return matches.GetSize();
-    }
-
-    // Okay, containing_part is now the directory we want to open and look for files:
-
-    size_t baselen = end_ptr - partial_name_copy;
-    
-    DiskFilesOrDirectoriesBaton parameters;
-    parameters.remainder = remainder;
-    parameters.partial_name_copy = partial_name_copy;
-    parameters.only_directories = only_directories;
-    parameters.saw_directory = &saw_directory;
-    parameters.matches = &matches;
-    parameters.end_ptr = end_ptr;
-    parameters.baselen = baselen;
-
-    FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true, DiskFilesOrDirectoriesCallback, &parameters);
-    
-    return matches.GetSize();
-}
-
-int
-CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
-                              const char *partial_file_name,
-                              int match_start_point,
-                              int max_return_elements,
-                              SearchFilter *searcher,
-                              bool &word_complete,
-                              StringList &matches)
-{
-    int ret_val = DiskFilesOrDirectories (partial_file_name,
-                                          false,
-                                          word_complete,
-                                          matches);
-    word_complete = !word_complete;
-    return ret_val;
-}
-
-int
-CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
+int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
                                     const char *partial_file_name,
                                     int match_start_point,
                                     int max_return_elements,
-                                    SearchFilter *searcher,
-                                    bool &word_complete,
-                                    StringList &matches)
-{
-    int ret_val =  DiskFilesOrDirectories (partial_file_name,
-                                           true,
-                                           word_complete,
-                                           matches); 
-    word_complete = false;
-    return ret_val;
+                                    SearchFilter *searcher, bool &word_complete,
+                                    StringList &matches) {
+  word_complete = true;
+  // Find some way to switch "include support files..."
+  SourceFileCompleter completer(interpreter, false, partial_file_name,
+                                match_start_point, max_return_elements,
+                                matches);
+
+  if (searcher == nullptr) {
+    lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+    SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+    completer.DoCompletion(&null_searcher);
+  } else {
+    completer.DoCompletion(searcher);
+  }
+  return matches.GetSize();
 }
 
-int
-CommandCompletions::Modules(CommandInterpreter &interpreter,
-                            const char *partial_file_name,
-                            int match_start_point,
-                            int max_return_elements,
-                            SearchFilter *searcher,
-                            bool &word_complete,
-                            StringList &matches)
-{
-    word_complete = true;
-    ModuleCompleter completer (interpreter,
-                               partial_file_name, 
-                               match_start_point, 
-                               max_return_elements, 
-                               matches);
-    
-    if (searcher == nullptr)
-    {
-        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
-        SearchFilterForUnconstrainedSearches null_searcher (target_sp);
-        completer.DoCompletion (&null_searcher);
+typedef struct DiskFilesOrDirectoriesBaton {
+  const char *remainder;
+  char *partial_name_copy;
+  bool only_directories;
+  bool *saw_directory;
+  StringList *matches;
+  char *end_ptr;
+  size_t baselen;
+} DiskFilesOrDirectoriesBaton;
+
+FileSpec::EnumerateDirectoryResult
+DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type,
+                               const FileSpec &spec) {
+  const char *name = spec.GetFilename().AsCString();
+
+  const DiskFilesOrDirectoriesBaton *parameters =
+      (DiskFilesOrDirectoriesBaton *)baton;
+  char *end_ptr = parameters->end_ptr;
+  char *partial_name_copy = parameters->partial_name_copy;
+  const char *remainder = parameters->remainder;
+
+  // Omit ".", ".." and any . files if the match string doesn't start with .
+  if (name[0] == '.') {
+    if (name[1] == '\0')
+      return FileSpec::eEnumerateDirectoryResultNext;
+    else if (name[1] == '.' && name[2] == '\0')
+      return FileSpec::eEnumerateDirectoryResultNext;
+    else if (remainder[0] != '.')
+      return FileSpec::eEnumerateDirectoryResultNext;
+  }
+
+  // If we found a directory, we put a "/" at the end of the name.
+
+  if (remainder[0] == '\0' || strstr(name, remainder) == name) {
+    if (strlen(name) + parameters->baselen >= PATH_MAX)
+      return FileSpec::eEnumerateDirectoryResultNext;
+
+    strcpy(end_ptr, name);
+
+    bool isa_directory = false;
+    if (file_type == FileSpec::eFileTypeDirectory)
+      isa_directory = true;
+    else if (file_type == FileSpec::eFileTypeSymbolicLink) {
+      if (FileSpec(partial_name_copy, false).IsDirectory())
+        isa_directory = true;
     }
-    else
-    {
-        completer.DoCompletion (searcher);
+
+    if (isa_directory) {
+      *parameters->saw_directory = true;
+      size_t len = strlen(parameters->partial_name_copy);
+      partial_name_copy[len] = '/';
+      partial_name_copy[len + 1] = '\0';
     }
+    if (parameters->only_directories && !isa_directory)
+      return FileSpec::eEnumerateDirectoryResultNext;
+    parameters->matches->AppendString(partial_name_copy);
+  }
+
+  return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+static int DiskFilesOrDirectories(const char *partial_file_name,
+                                  bool only_directories, bool &saw_directory,
+                                  StringList &matches) {
+  // I'm going to  use the "glob" function with GLOB_TILDE for user directory
+  // expansion.
+  // If it is not defined on your host system, you'll need to implement it
+  // yourself...
+
+  size_t partial_name_len = strlen(partial_file_name);
+
+  if (partial_name_len >= PATH_MAX)
     return matches.GetSize();
-}
 
-int
-CommandCompletions::Symbols(CommandInterpreter &interpreter,
-                            const char *partial_file_name,
-                            int match_start_point,
-                            int max_return_elements,
-                            SearchFilter *searcher,
-                            bool &word_complete,
-                            StringList &matches)
-{
-    word_complete = true;
-    SymbolCompleter completer (interpreter,
-                               partial_file_name, 
-                               match_start_point, 
-                               max_return_elements, 
-                               matches);
+  // This copy of the string will be cut up into the directory part, and the
+  // remainder.  end_ptr
+  // below will point to the place of the remainder in this string.  Then when
+  // we've resolved the
+  // containing directory, and opened it, we'll read the directory contents and
+  // overwrite the
+  // partial_name_copy starting from end_ptr with each of the matches.  Thus we
+  // will preserve
+  // the form the user originally typed.
 
-    if (searcher == nullptr)
-    {
-        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
-        SearchFilterForUnconstrainedSearches null_searcher (target_sp);
-        completer.DoCompletion (&null_searcher);
+  char partial_name_copy[PATH_MAX];
+  memcpy(partial_name_copy, partial_file_name, partial_name_len);
+  partial_name_copy[partial_name_len] = '\0';
+
+  // We'll need to save a copy of the remainder for comparison, which we do
+  // here.
+  char remainder[PATH_MAX];
+
+  // end_ptr will point past the last / in partial_name_copy, or if there is no
+  // slash to the beginning of the string.
+  char *end_ptr;
+
+  end_ptr = strrchr(partial_name_copy, '/');
+
+  // This will store the resolved form of the containing directory
+  llvm::SmallString<64> containing_part;
+
+  if (end_ptr == nullptr) {
+    // There's no directory.  If the thing begins with a "~" then this is a bare
+    // user name.
+    if (*partial_name_copy == '~') {
+      // Nothing here but the user name.  We could just put a slash on the end,
+      // but for completeness sake we'll resolve the user name and only put a
+      // slash
+      // on the end if it exists.
+      llvm::SmallString<64> resolved_username(partial_name_copy);
+      FileSpec::ResolveUsername(resolved_username);
+
+      // Not sure how this would happen, a username longer than PATH_MAX?
+      // Still...
+      if (resolved_username.size() == 0) {
+        // The user name didn't resolve, let's look in the password database for
+        // matches.
+        // The user name database contains duplicates, and is not in
+        // alphabetical order, so
+        // we'll use a set to manage that for us.
+        FileSpec::ResolvePartialUsername(partial_name_copy, matches);
+        if (matches.GetSize() > 0)
+          saw_directory = true;
+        return matches.GetSize();
+      } else {
+        // The thing exists, put a '/' on the end, and return it...
+        // FIXME: complete user names here:
+        partial_name_copy[partial_name_len] = '/';
+        partial_name_copy[partial_name_len + 1] = '\0';
+        matches.AppendString(partial_name_copy);
+        saw_directory = true;
+        return matches.GetSize();
+      }
+    } else {
+      // The containing part is the CWD, and the whole string is the remainder.
+      containing_part = ".";
+      strcpy(remainder, partial_name_copy);
+      end_ptr = partial_name_copy;
     }
-    else
-    {
-        completer.DoCompletion (searcher);
+  } else {
+    if (end_ptr == partial_name_copy) {
+      // We're completing a file or directory in the root volume.
+      containing_part = "/";
+    } else {
+      containing_part.append(partial_name_copy, end_ptr);
     }
-    return matches.GetSize();
+    // Push end_ptr past the final "/" and set remainder.
+    end_ptr++;
+    strcpy(remainder, end_ptr);
+  }
+
+  // Look for a user name in the containing part, and if it's there, resolve it
+  // and stick the
+  // result back into the containing_part:
+
+  if (*partial_name_copy == '~') {
+    FileSpec::ResolveUsername(containing_part);
+    // User name doesn't exist, we're not getting any further...
+    if (containing_part.empty())
+      return matches.GetSize();
+  }
+
+  // Okay, containing_part is now the directory we want to open and look for
+  // files:
+
+  size_t baselen = end_ptr - partial_name_copy;
+
+  DiskFilesOrDirectoriesBaton parameters;
+  parameters.remainder = remainder;
+  parameters.partial_name_copy = partial_name_copy;
+  parameters.only_directories = only_directories;
+  parameters.saw_directory = &saw_directory;
+  parameters.matches = &matches;
+  parameters.end_ptr = end_ptr;
+  parameters.baselen = baselen;
+
+  FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true,
+                               DiskFilesOrDirectoriesCallback, &parameters);
+
+  return matches.GetSize();
 }
 
-int
-CommandCompletions::SettingsNames (CommandInterpreter &interpreter,
-                                   const char *partial_setting_name,
-                                   int match_start_point,
-                                   int max_return_elements,
-                                   SearchFilter *searcher,
-                                   bool &word_complete,
-                                   StringList &matches)
-{
-    // Cache the full setting name list
-    static StringList g_property_names;
-    if (g_property_names.GetSize() == 0)
-    {
-        // Generate the full setting name list on demand
-        lldb::OptionValuePropertiesSP properties_sp (interpreter.GetDebugger().GetValueProperties());
-        if (properties_sp)
-        {
-            StreamString strm;
-            properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName);
-            const std::string &str = strm.GetString();
-            g_property_names.SplitIntoLines(str.c_str(), str.size());
-        }
-    }
-    
-    size_t exact_matches_idx = SIZE_MAX;
-    const size_t num_matches = g_property_names.AutoComplete (partial_setting_name, matches, exact_matches_idx);
-    word_complete = exact_matches_idx != SIZE_MAX;
-    return num_matches;
-}
-
-int
-CommandCompletions::PlatformPluginNames (CommandInterpreter &interpreter,
-                                         const char *partial_name,
-                                         int match_start_point,
-                                         int max_return_elements,
-                                         SearchFilter *searcher,
-                                         bool &word_complete,
-                                         lldb_private::StringList &matches)
-{
-    const uint32_t num_matches = PluginManager::AutoCompletePlatformName(partial_name, matches);
-    word_complete = num_matches == 1;
-    return num_matches;
-}
-
-int
-CommandCompletions::ArchitectureNames (CommandInterpreter &interpreter,
-                                       const char *partial_name,
-                                       int match_start_point,
-                                       int max_return_elements,
-                                       SearchFilter *searcher,
-                                       bool &word_complete,
-                                       lldb_private::StringList &matches)
-{
-    const uint32_t num_matches = ArchSpec::AutoComplete (partial_name, matches);
-    word_complete = num_matches == 1;
-    return num_matches;
-}
-
-int
-CommandCompletions::VariablePath (CommandInterpreter &interpreter,
-                                  const char *partial_name,
+int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
+                                  const char *partial_file_name,
                                   int match_start_point,
                                   int max_return_elements,
-                                  SearchFilter *searcher,
-                                  bool &word_complete,
-                                  lldb_private::StringList &matches)
-{
-    return Variable::AutoComplete (interpreter.GetExecutionContext(), partial_name, matches, word_complete);
+                                  SearchFilter *searcher, bool &word_complete,
+                                  StringList &matches) {
+  int ret_val =
+      DiskFilesOrDirectories(partial_file_name, false, word_complete, matches);
+  word_complete = !word_complete;
+  return ret_val;
+}
+
+int CommandCompletions::DiskDirectories(
+    CommandInterpreter &interpreter, const char *partial_file_name,
+    int match_start_point, int max_return_elements, SearchFilter *searcher,
+    bool &word_complete, StringList &matches) {
+  int ret_val =
+      DiskFilesOrDirectories(partial_file_name, true, word_complete, matches);
+  word_complete = false;
+  return ret_val;
+}
+
+int CommandCompletions::Modules(CommandInterpreter &interpreter,
+                                const char *partial_file_name,
+                                int match_start_point, int max_return_elements,
+                                SearchFilter *searcher, bool &word_complete,
+                                StringList &matches) {
+  word_complete = true;
+  ModuleCompleter completer(interpreter, partial_file_name, match_start_point,
+                            max_return_elements, matches);
+
+  if (searcher == nullptr) {
+    lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+    SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+    completer.DoCompletion(&null_searcher);
+  } else {
+    completer.DoCompletion(searcher);
+  }
+  return matches.GetSize();
+}
+
+int CommandCompletions::Symbols(CommandInterpreter &interpreter,
+                                const char *partial_file_name,
+                                int match_start_point, int max_return_elements,
+                                SearchFilter *searcher, bool &word_complete,
+                                StringList &matches) {
+  word_complete = true;
+  SymbolCompleter completer(interpreter, partial_file_name, match_start_point,
+                            max_return_elements, matches);
+
+  if (searcher == nullptr) {
+    lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+    SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+    completer.DoCompletion(&null_searcher);
+  } else {
+    completer.DoCompletion(searcher);
+  }
+  return matches.GetSize();
+}
+
+int CommandCompletions::SettingsNames(
+    CommandInterpreter &interpreter, const char *partial_setting_name,
+    int match_start_point, int max_return_elements, SearchFilter *searcher,
+    bool &word_complete, StringList &matches) {
+  // Cache the full setting name list
+  static StringList g_property_names;
+  if (g_property_names.GetSize() == 0) {
+    // Generate the full setting name list on demand
+    lldb::OptionValuePropertiesSP properties_sp(
+        interpreter.GetDebugger().GetValueProperties());
+    if (properties_sp) {
+      StreamString strm;
+      properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName);
+      const std::string &str = strm.GetString();
+      g_property_names.SplitIntoLines(str.c_str(), str.size());
+    }
+  }
+
+  size_t exact_matches_idx = SIZE_MAX;
+  const size_t num_matches = g_property_names.AutoComplete(
+      partial_setting_name, matches, exact_matches_idx);
+  word_complete = exact_matches_idx != SIZE_MAX;
+  return num_matches;
+}
+
+int CommandCompletions::PlatformPluginNames(
+    CommandInterpreter &interpreter, const char *partial_name,
+    int match_start_point, int max_return_elements, SearchFilter *searcher,
+    bool &word_complete, lldb_private::StringList &matches) {
+  const uint32_t num_matches =
+      PluginManager::AutoCompletePlatformName(partial_name, matches);
+  word_complete = num_matches == 1;
+  return num_matches;
+}
+
+int CommandCompletions::ArchitectureNames(
+    CommandInterpreter &interpreter, const char *partial_name,
+    int match_start_point, int max_return_elements, SearchFilter *searcher,
+    bool &word_complete, lldb_private::StringList &matches) {
+  const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches);
+  word_complete = num_matches == 1;
+  return num_matches;
+}
+
+int CommandCompletions::VariablePath(
+    CommandInterpreter &interpreter, const char *partial_name,
+    int match_start_point, int max_return_elements, SearchFilter *searcher,
+    bool &word_complete, lldb_private::StringList &matches) {
+  return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name,
+                                matches, word_complete);
 }
 
 CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
                                          const char *completion_str,
                                          int match_start_point,
                                          int max_return_elements,
-                                         StringList &matches) :
-    m_interpreter (interpreter),
-    m_completion_str (completion_str),
-    m_match_start_point (match_start_point),
-    m_max_return_elements (max_return_elements),
-    m_matches (matches)
-{
-}
+                                         StringList &matches)
+    : m_interpreter(interpreter), m_completion_str(completion_str),
+      m_match_start_point(match_start_point),
+      m_max_return_elements(max_return_elements), m_matches(matches) {}
 
 CommandCompletions::Completer::~Completer() = default;
 
@@ -485,237 +406,195 @@
 // SourceFileCompleter
 //----------------------------------------------------------------------
 
-CommandCompletions::SourceFileCompleter::SourceFileCompleter(CommandInterpreter &interpreter,
-                                                             bool include_support_files,
-                                                             const char *completion_str,
-                                                             int match_start_point,
-                                                             int max_return_elements,
-                                                             StringList &matches) :
-    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches),
-    m_include_support_files (include_support_files),
-    m_matching_files()
-{
-    FileSpec partial_spec (m_completion_str.c_str(), false);
-    m_file_name = partial_spec.GetFilename().GetCString();
-    m_dir_name = partial_spec.GetDirectory().GetCString();
+CommandCompletions::SourceFileCompleter::SourceFileCompleter(
+    CommandInterpreter &interpreter, bool include_support_files,
+    const char *completion_str, int match_start_point, int max_return_elements,
+    StringList &matches)
+    : CommandCompletions::Completer(interpreter, completion_str,
+                                    match_start_point, max_return_elements,
+                                    matches),
+      m_include_support_files(include_support_files), m_matching_files() {
+  FileSpec partial_spec(m_completion_str.c_str(), false);
+  m_file_name = partial_spec.GetFilename().GetCString();
+  m_dir_name = partial_spec.GetDirectory().GetCString();
 }
 
-Searcher::Depth
-CommandCompletions::SourceFileCompleter::GetDepth()
-{
-    return eDepthCompUnit;
+Searcher::Depth CommandCompletions::SourceFileCompleter::GetDepth() {
+  return eDepthCompUnit;
 }
 
 Searcher::CallbackReturn
 CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
                                                         SymbolContext &context,
                                                         Address *addr,
-                                                        bool complete)
-{
-    if (context.comp_unit != nullptr)
-    {
-        if (m_include_support_files)
-        {
-            FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
-            for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++)
-            {
-                const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles);
-                const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
-                const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
-                bool match = false;
-                if (m_file_name && sfile_file_name
-                    && strstr (sfile_file_name, m_file_name) == sfile_file_name)
-                    match = true;
-                if (match && m_dir_name && sfile_dir_name
-                    && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name)
-                    match = false;
+                                                        bool complete) {
+  if (context.comp_unit != nullptr) {
+    if (m_include_support_files) {
+      FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
+      for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) {
+        const FileSpec &sfile_spec =
+            supporting_files.GetFileSpecAtIndex(sfiles);
+        const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
+        const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
+        bool match = false;
+        if (m_file_name && sfile_file_name &&
+            strstr(sfile_file_name, m_file_name) == sfile_file_name)
+          match = true;
+        if (match && m_dir_name && sfile_dir_name &&
+            strstr(sfile_dir_name, m_dir_name) != sfile_dir_name)
+          match = false;
 
-                if (match)
-                {
-                    m_matching_files.AppendIfUnique(sfile_spec);
-                }
-            }
+        if (match) {
+          m_matching_files.AppendIfUnique(sfile_spec);
         }
-        else
-        {
-            const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
-            const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();
+      }
+    } else {
+      const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
+      const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();
 
-            bool match = false;
-            if (m_file_name && cur_file_name
-                && strstr (cur_file_name, m_file_name) == cur_file_name)
-                match = true;
+      bool match = false;
+      if (m_file_name && cur_file_name &&
+          strstr(cur_file_name, m_file_name) == cur_file_name)
+        match = true;
 
-            if (match && m_dir_name && cur_dir_name
-                && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
-                match = false;
+      if (match && m_dir_name && cur_dir_name &&
+          strstr(cur_dir_name, m_dir_name) != cur_dir_name)
+        match = false;
 
-            if (match)
-            {
-                m_matching_files.AppendIfUnique(context.comp_unit);
-            }
-        }
+      if (match) {
+        m_matching_files.AppendIfUnique(context.comp_unit);
+      }
     }
-    return Searcher::eCallbackReturnContinue;
+  }
+  return Searcher::eCallbackReturnContinue;
 }
 
 size_t
-CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
-{
-    filter->Search (*this);
-    // Now convert the filelist to completions:
-    for (size_t i = 0; i < m_matching_files.GetSize(); i++)
-    {
-        m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
-    }
-    return m_matches.GetSize();
+CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) {
+  filter->Search(*this);
+  // Now convert the filelist to completions:
+  for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
+    m_matches.AppendString(
+        m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
+  }
+  return m_matches.GetSize();
 }
 
 //----------------------------------------------------------------------
 // SymbolCompleter
 //----------------------------------------------------------------------
 
-static bool
-regex_chars (const char comp)
-{
-    return (comp == '[' || comp == ']' ||
-            comp == '(' || comp == ')' ||
-            comp == '{' || comp == '}' ||
-            comp == '+' ||
-            comp == '.' ||
-            comp == '*' ||
-            comp == '|' ||
-            comp == '^' ||
-            comp == '$' ||
-            comp == '\\' ||
-            comp == '?');
+static bool regex_chars(const char comp) {
+  return (comp == '[' || comp == ']' || comp == '(' || comp == ')' ||
+          comp == '{' || comp == '}' || comp == '+' || comp == '.' ||
+          comp == '*' || comp == '|' || comp == '^' || comp == '$' ||
+          comp == '\\' || comp == '?');
 }
 
-CommandCompletions::SymbolCompleter::SymbolCompleter(CommandInterpreter &interpreter,
-                                                     const char *completion_str,
-                                                     int match_start_point,
-                                                     int max_return_elements,
-                                                     StringList &matches) :
-    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
-{
-    std::string regex_str;
-    if (completion_str && completion_str[0])
-    {
-        regex_str.append("^");
-        regex_str.append(completion_str);
-    }
-    else
-    {
-        // Match anything since the completion string is empty
-        regex_str.append(".");
-    }
-    std::string::iterator pos = find_if(regex_str.begin() + 1, regex_str.end(), regex_chars);
-    while (pos < regex_str.end())
-    {
-        pos = regex_str.insert(pos, '\\');
-        pos = find_if(pos + 2, regex_str.end(), regex_chars);
-    }
-    m_regex.Compile(regex_str.c_str());
+CommandCompletions::SymbolCompleter::SymbolCompleter(
+    CommandInterpreter &interpreter, const char *completion_str,
+    int match_start_point, int max_return_elements, StringList &matches)
+    : CommandCompletions::Completer(interpreter, completion_str,
+                                    match_start_point, max_return_elements,
+                                    matches) {
+  std::string regex_str;
+  if (completion_str && completion_str[0]) {
+    regex_str.append("^");
+    regex_str.append(completion_str);
+  } else {
+    // Match anything since the completion string is empty
+    regex_str.append(".");
+  }
+  std::string::iterator pos =
+      find_if(regex_str.begin() + 1, regex_str.end(), regex_chars);
+  while (pos < regex_str.end()) {
+    pos = regex_str.insert(pos, '\\');
+    pos = find_if(pos + 2, regex_str.end(), regex_chars);
+  }
+  m_regex.Compile(regex_str.c_str());
 }
 
-Searcher::Depth
-CommandCompletions::SymbolCompleter::GetDepth()
-{
-    return eDepthModule;
+Searcher::Depth CommandCompletions::SymbolCompleter::GetDepth() {
+  return eDepthModule;
 }
 
-Searcher::CallbackReturn
-CommandCompletions::SymbolCompleter::SearchCallback(SearchFilter &filter,
-                                                    SymbolContext &context,
-                                                    Address *addr,
-                                                    bool complete)
-{
-    if (context.module_sp)
-    {
-        SymbolContextList sc_list;        
-        const bool include_symbols = true;
-        const bool include_inlines = true;
-        const bool append = true;
-        context.module_sp->FindFunctions (m_regex, include_symbols, include_inlines, append, sc_list);
+Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback(
+    SearchFilter &filter, SymbolContext &context, Address *addr,
+    bool complete) {
+  if (context.module_sp) {
+    SymbolContextList sc_list;
+    const bool include_symbols = true;
+    const bool include_inlines = true;
+    const bool append = true;
+    context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines,
+                                     append, sc_list);
 
-        SymbolContext sc;
-        // Now add the functions & symbols to the list - only add if unique:
-        for (uint32_t i = 0; i < sc_list.GetSize(); i++)
-        {
-            if (sc_list.GetContextAtIndex(i, sc))
-            {
-                ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
-                if (!func_name.IsEmpty())
-                    m_match_set.insert (func_name);
-            }
-        }
+    SymbolContext sc;
+    // Now add the functions & symbols to the list - only add if unique:
+    for (uint32_t i = 0; i < sc_list.GetSize(); i++) {
+      if (sc_list.GetContextAtIndex(i, sc)) {
+        ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
+        if (!func_name.IsEmpty())
+          m_match_set.insert(func_name);
+      }
     }
-    return Searcher::eCallbackReturnContinue;
+  }
+  return Searcher::eCallbackReturnContinue;
 }
 
-size_t
-CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter)
-{
-    filter->Search (*this);
-    collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
-    for (pos = m_match_set.begin(); pos != end; pos++)
-        m_matches.AppendString((*pos).GetCString());
+size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
+  filter->Search(*this);
+  collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
+  for (pos = m_match_set.begin(); pos != end; pos++)
+    m_matches.AppendString((*pos).GetCString());
 
-    return m_matches.GetSize();
+  return m_matches.GetSize();
 }
 
 //----------------------------------------------------------------------
 // ModuleCompleter
 //----------------------------------------------------------------------
-CommandCompletions::ModuleCompleter::ModuleCompleter(CommandInterpreter &interpreter,
-                                                     const char *completion_str,
-                                                     int match_start_point,
-                                                     int max_return_elements,
-                                                     StringList &matches) :
-    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
-{
-    FileSpec partial_spec (m_completion_str.c_str(), false);
-    m_file_name = partial_spec.GetFilename().GetCString();
-    m_dir_name = partial_spec.GetDirectory().GetCString();
+CommandCompletions::ModuleCompleter::ModuleCompleter(
+    CommandInterpreter &interpreter, const char *completion_str,
+    int match_start_point, int max_return_elements, StringList &matches)
+    : CommandCompletions::Completer(interpreter, completion_str,
+                                    match_start_point, max_return_elements,
+                                    matches) {
+  FileSpec partial_spec(m_completion_str.c_str(), false);
+  m_file_name = partial_spec.GetFilename().GetCString();
+  m_dir_name = partial_spec.GetDirectory().GetCString();
 }
 
-Searcher::Depth
-CommandCompletions::ModuleCompleter::GetDepth()
-{
-    return eDepthModule;
+Searcher::Depth CommandCompletions::ModuleCompleter::GetDepth() {
+  return eDepthModule;
 }
 
-Searcher::CallbackReturn
-CommandCompletions::ModuleCompleter::SearchCallback(SearchFilter &filter,
-                                                    SymbolContext &context,
-                                                    Address *addr,
-                                                    bool complete)
-{
-    if (context.module_sp)
-    {
-        const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString();
-        const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString();
+Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
+    SearchFilter &filter, SymbolContext &context, Address *addr,
+    bool complete) {
+  if (context.module_sp) {
+    const char *cur_file_name =
+        context.module_sp->GetFileSpec().GetFilename().GetCString();
+    const char *cur_dir_name =
+        context.module_sp->GetFileSpec().GetDirectory().GetCString();
 
-        bool match = false;
-        if (m_file_name && cur_file_name
-            && strstr (cur_file_name, m_file_name) == cur_file_name)
-            match = true;
+    bool match = false;
+    if (m_file_name && cur_file_name &&
+        strstr(cur_file_name, m_file_name) == cur_file_name)
+      match = true;
 
-        if (match && m_dir_name && cur_dir_name
-            && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
-            match = false;
+    if (match && m_dir_name && cur_dir_name &&
+        strstr(cur_dir_name, m_dir_name) != cur_dir_name)
+      match = false;
 
-        if (match)
-        {
-            m_matches.AppendString (cur_file_name);
-        }
+    if (match) {
+      m_matches.AppendString(cur_file_name);
     }
-    return Searcher::eCallbackReturnContinue;
+  }
+  return Searcher::eCallbackReturnContinue;
 }
 
-size_t
-CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter)
-{
-    filter->Search (*this);
-    return m_matches.GetSize();
+size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
+  filter->Search(*this);
+  return m_matches.GetSize();
 }
