diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index ead555a..bd8ae56 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -12,7 +12,9 @@
 #include <mutex>
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Target/Target.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
 #include "lldb/Breakpoint/BreakpointResolver.h"
 #include "lldb/Breakpoint/BreakpointResolverAddress.h"
 #include "lldb/Breakpoint/BreakpointResolverFileLine.h"
@@ -33,9 +35,6 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Expression/REPL.h"
 #include "lldb/Expression/UserExpression.h"
-#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
-#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
@@ -44,8 +43,8 @@
 #include "lldb/Interpreter/OptionValues.h"
 #include "lldb/Interpreter/Property.h"
 #include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
@@ -54,6 +53,7 @@
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/SystemRuntime.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadSpec.h"
 #include "lldb/Utility/LLDBAssert.h"
@@ -61,862 +61,737 @@
 using namespace lldb;
 using namespace lldb_private;
 
-ConstString &
-Target::GetStaticBroadcasterClass ()
-{
-    static ConstString class_name ("lldb.target");
-    return class_name;
+ConstString &Target::GetStaticBroadcasterClass() {
+  static ConstString class_name("lldb.target");
+  return class_name;
 }
 
-Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp,
-               bool is_dummy_target)
+Target::Target(Debugger &debugger, const ArchSpec &target_arch,
+               const lldb::PlatformSP &platform_sp, bool is_dummy_target)
     : TargetProperties(this),
-      Broadcaster(debugger.GetBroadcasterManager(), Target::GetStaticBroadcasterClass().AsCString()),
-      ExecutionContextScope(),
-      m_debugger(debugger),
-      m_platform_sp(platform_sp),
-      m_mutex(),
-      m_arch(target_arch),
-      m_images(this),
-      m_section_load_history(),
-      m_breakpoint_list(false),
-      m_internal_breakpoint_list(true),
-      m_watchpoint_list(),
-      m_process_sp(),
-      m_search_filter_sp(),
-      m_image_search_paths(ImageSearchPathsChanged, this),
-      m_ast_importer_sp(),
-      m_source_manager_ap(),
-      m_stop_hooks(),
-      m_stop_hook_next_id(0),
-      m_valid(true),
-      m_suppress_stop_hooks(false),
+      Broadcaster(debugger.GetBroadcasterManager(),
+                  Target::GetStaticBroadcasterClass().AsCString()),
+      ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),
+      m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),
+      m_breakpoint_list(false), m_internal_breakpoint_list(true),
+      m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),
+      m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(),
+      m_source_manager_ap(), m_stop_hooks(), m_stop_hook_next_id(0),
+      m_valid(true), m_suppress_stop_hooks(false),
       m_is_dummy_target(is_dummy_target)
 
 {
-    SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
-    SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");
-    SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
-    SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
-    SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
+  SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
+  SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");
+  SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
+  SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
+  SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
 
-    CheckInWithManager();
+  CheckInWithManager();
 
-    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
-    if (log)
-        log->Printf("%p Target::Target()", static_cast<void *>(this));
-    if (m_arch.IsValid())
-    {
-        LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)",
-                              m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
-    }
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+  if (log)
+    log->Printf("%p Target::Target()", static_cast<void *>(this));
+  if (m_arch.IsValid()) {
+    LogIfAnyCategoriesSet(
+        LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)",
+        m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+  }
 }
 
-Target::~Target()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
-    if (log)
-        log->Printf ("%p Target::~Target()", static_cast<void*>(this));
-    DeleteCurrentProcess ();
+Target::~Target() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+  if (log)
+    log->Printf("%p Target::~Target()", static_cast<void *>(this));
+  DeleteCurrentProcess();
 }
 
-void
-Target::PrimeFromDummyTarget(Target *target)
-{
-    if (!target)
-        return;
+void Target::PrimeFromDummyTarget(Target *target) {
+  if (!target)
+    return;
 
-    m_stop_hooks = target->m_stop_hooks;
-    
-    for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints())
-    {
-        if (breakpoint_sp->IsInternal())
-            continue;
-            
-        BreakpointSP new_bp (new Breakpoint (*this, *breakpoint_sp.get()));
-        AddBreakpoint (new_bp, false);
-    }
+  m_stop_hooks = target->m_stop_hooks;
+
+  for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints()) {
+    if (breakpoint_sp->IsInternal())
+      continue;
+
+    BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
+    AddBreakpoint(new_bp, false);
+  }
 }
 
-void
-Target::Dump (Stream *s, lldb::DescriptionLevel description_level)
-{
-//    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
-    if (description_level != lldb::eDescriptionLevelBrief)
-    {
-        s->Indent();
-        s->PutCString("Target\n");
-        s->IndentMore();
-            m_images.Dump(s);
-            m_breakpoint_list.Dump(s);
-            m_internal_breakpoint_list.Dump(s);
-        s->IndentLess();
-    }
+void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
+  //    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+  if (description_level != lldb::eDescriptionLevelBrief) {
+    s->Indent();
+    s->PutCString("Target\n");
+    s->IndentMore();
+    m_images.Dump(s);
+    m_breakpoint_list.Dump(s);
+    m_internal_breakpoint_list.Dump(s);
+    s->IndentLess();
+  } else {
+    Module *exe_module = GetExecutableModulePointer();
+    if (exe_module)
+      s->PutCString(exe_module->GetFileSpec().GetFilename().GetCString());
     else
-    {
-        Module *exe_module = GetExecutableModulePointer();
-        if (exe_module)
-            s->PutCString (exe_module->GetFileSpec().GetFilename().GetCString());
-        else
-            s->PutCString ("No executable module.");
-    }
+      s->PutCString("No executable module.");
+  }
 }
 
-void
-Target::CleanupProcess ()
-{
-    // Do any cleanup of the target we need to do between process instances.
-    // NB It is better to do this before destroying the process in case the
-    // clean up needs some help from the process.
-    m_breakpoint_list.ClearAllBreakpointSites();
-    m_internal_breakpoint_list.ClearAllBreakpointSites();
-    // Disable watchpoints just on the debugger side.
-    std::unique_lock<std::recursive_mutex> lock;
-    this->GetWatchpointList().GetListMutex(lock);
-    DisableAllWatchpoints(false);
-    ClearAllWatchpointHitCounts();
-    ClearAllWatchpointHistoricValues();
+void Target::CleanupProcess() {
+  // Do any cleanup of the target we need to do between process instances.
+  // NB It is better to do this before destroying the process in case the
+  // clean up needs some help from the process.
+  m_breakpoint_list.ClearAllBreakpointSites();
+  m_internal_breakpoint_list.ClearAllBreakpointSites();
+  // Disable watchpoints just on the debugger side.
+  std::unique_lock<std::recursive_mutex> lock;
+  this->GetWatchpointList().GetListMutex(lock);
+  DisableAllWatchpoints(false);
+  ClearAllWatchpointHitCounts();
+  ClearAllWatchpointHistoricValues();
 }
 
-void
-Target::DeleteCurrentProcess ()
-{
-    if (m_process_sp)
-    {
-        m_section_load_history.Clear();
-        if (m_process_sp->IsAlive())
-            m_process_sp->Destroy(false);
-        
-        m_process_sp->Finalize();
-
-        CleanupProcess ();
-
-        m_process_sp.reset();
-    }
-}
-
-const lldb::ProcessSP &
-Target::CreateProcess (ListenerSP listener_sp, const char *plugin_name, const FileSpec *crash_file)
-{
-    DeleteCurrentProcess ();
-    m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file);
-    return m_process_sp;
-}
-
-const lldb::ProcessSP &
-Target::GetProcessSP () const
-{
-    return m_process_sp;
-}
-
-lldb::REPLSP
-Target::GetREPL (Error &err, lldb::LanguageType language, const char *repl_options, bool can_create)
-{
-    if (language == eLanguageTypeUnknown)
-    {
-        std::set<LanguageType> repl_languages;
-        
-        Language::GetLanguagesSupportingREPLs(repl_languages);
-        
-        if (repl_languages.size() == 1)
-        {
-            language = *repl_languages.begin();
-        }
-        else if (repl_languages.size() == 0)
-        {
-            err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages.");
-            return REPLSP();
-        }
-        else
-        {
-            err.SetErrorStringWithFormat("Multiple possible REPL languages.  Please specify a language.");
-            return REPLSP();
-        }
-    }
-    
-    REPLMap::iterator pos = m_repl_map.find(language);
-    
-    if (pos != m_repl_map.end())
-    {
-        return pos->second;
-    }
-    
-    if (!can_create)
-    {
-        err.SetErrorStringWithFormat("Couldn't find an existing REPL for %s, and can't create a new one", Language::GetNameForLanguageType(language));
-        return lldb::REPLSP();
-    }
-    
-    Debugger *const debugger = nullptr;
-    lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options);
-    
-    if (ret)
-    {
-        m_repl_map[language] = ret;
-        return m_repl_map[language];
-    }
-    
-    if (err.Success())
-    {
-        err.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(language));
-    }
-    
-    return lldb::REPLSP();
-}
-
-void
-Target::SetREPL (lldb::LanguageType language, lldb::REPLSP repl_sp)
-{
-    lldbassert(!m_repl_map.count(language));
-    
-    m_repl_map[language] = repl_sp;
-}
-
-void
-Target::Destroy()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    m_valid = false;
-    DeleteCurrentProcess ();
-    m_platform_sp.reset();
-    m_arch.Clear();
-    ClearModules(true);
+void Target::DeleteCurrentProcess() {
+  if (m_process_sp) {
     m_section_load_history.Clear();
-    const bool notify = false;
-    m_breakpoint_list.RemoveAll(notify);
-    m_internal_breakpoint_list.RemoveAll(notify);
-    m_last_created_breakpoint.reset();
-    m_last_created_watchpoint.reset();
-    m_search_filter_sp.reset();
-    m_image_search_paths.Clear(notify);
-    m_stop_hooks.clear();
-    m_stop_hook_next_id = 0;
-    m_suppress_stop_hooks = false;
+    if (m_process_sp->IsAlive())
+      m_process_sp->Destroy(false);
+
+    m_process_sp->Finalize();
+
+    CleanupProcess();
+
+    m_process_sp.reset();
+  }
 }
 
-BreakpointList &
-Target::GetBreakpointList(bool internal)
-{
-    if (internal)
-        return m_internal_breakpoint_list;
-    else
-        return m_breakpoint_list;
+const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,
+                                             const char *plugin_name,
+                                             const FileSpec *crash_file) {
+  DeleteCurrentProcess();
+  m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name,
+                                     listener_sp, crash_file);
+  return m_process_sp;
 }
 
-const BreakpointList &
-Target::GetBreakpointList(bool internal) const
-{
-    if (internal)
-        return m_internal_breakpoint_list;
-    else
-        return m_breakpoint_list;
+const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }
+
+lldb::REPLSP Target::GetREPL(Error &err, lldb::LanguageType language,
+                             const char *repl_options, bool can_create) {
+  if (language == eLanguageTypeUnknown) {
+    std::set<LanguageType> repl_languages;
+
+    Language::GetLanguagesSupportingREPLs(repl_languages);
+
+    if (repl_languages.size() == 1) {
+      language = *repl_languages.begin();
+    } else if (repl_languages.size() == 0) {
+      err.SetErrorStringWithFormat(
+          "LLDB isn't configured with REPL support for any languages.");
+      return REPLSP();
+    } else {
+      err.SetErrorStringWithFormat(
+          "Multiple possible REPL languages.  Please specify a language.");
+      return REPLSP();
+    }
+  }
+
+  REPLMap::iterator pos = m_repl_map.find(language);
+
+  if (pos != m_repl_map.end()) {
+    return pos->second;
+  }
+
+  if (!can_create) {
+    err.SetErrorStringWithFormat(
+        "Couldn't find an existing REPL for %s, and can't create a new one",
+        Language::GetNameForLanguageType(language));
+    return lldb::REPLSP();
+  }
+
+  Debugger *const debugger = nullptr;
+  lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options);
+
+  if (ret) {
+    m_repl_map[language] = ret;
+    return m_repl_map[language];
+  }
+
+  if (err.Success()) {
+    err.SetErrorStringWithFormat("Couldn't create a REPL for %s",
+                                 Language::GetNameForLanguageType(language));
+  }
+
+  return lldb::REPLSP();
+}
+
+void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {
+  lldbassert(!m_repl_map.count(language));
+
+  m_repl_map[language] = repl_sp;
+}
+
+void Target::Destroy() {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  m_valid = false;
+  DeleteCurrentProcess();
+  m_platform_sp.reset();
+  m_arch.Clear();
+  ClearModules(true);
+  m_section_load_history.Clear();
+  const bool notify = false;
+  m_breakpoint_list.RemoveAll(notify);
+  m_internal_breakpoint_list.RemoveAll(notify);
+  m_last_created_breakpoint.reset();
+  m_last_created_watchpoint.reset();
+  m_search_filter_sp.reset();
+  m_image_search_paths.Clear(notify);
+  m_stop_hooks.clear();
+  m_stop_hook_next_id = 0;
+  m_suppress_stop_hooks = false;
+}
+
+BreakpointList &Target::GetBreakpointList(bool internal) {
+  if (internal)
+    return m_internal_breakpoint_list;
+  else
+    return m_breakpoint_list;
+}
+
+const BreakpointList &Target::GetBreakpointList(bool internal) const {
+  if (internal)
+    return m_internal_breakpoint_list;
+  else
+    return m_breakpoint_list;
+}
+
+BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {
+  BreakpointSP bp_sp;
+
+  if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
+    bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
+  else
+    bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
+
+  return bp_sp;
+}
+
+BreakpointSP Target::CreateSourceRegexBreakpoint(
+    const FileSpecList *containingModules,
+    const FileSpecList *source_file_spec_list,
+    const std::unordered_set<std::string> &function_names,
+    RegularExpression &source_regex, bool internal, bool hardware,
+    LazyBool move_to_nearest_code) {
+  SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
+      containingModules, source_file_spec_list));
+  if (move_to_nearest_code == eLazyBoolCalculate)
+    move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
+  BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(
+      nullptr, source_regex, function_names,
+      !static_cast<bool>(move_to_nearest_code)));
+
+  return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
+}
+
+BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,
+                                      const FileSpec &file, uint32_t line_no,
+                                      lldb::addr_t offset,
+                                      LazyBool check_inlines,
+                                      LazyBool skip_prologue, bool internal,
+                                      bool hardware,
+                                      LazyBool move_to_nearest_code) {
+  FileSpec remapped_file;
+  ConstString remapped_path;
+  if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()),
+                                          remapped_path))
+    remapped_file.SetFile(remapped_path.AsCString(), true);
+  else
+    remapped_file = file;
+
+  if (check_inlines == eLazyBoolCalculate) {
+    const InlineStrategy inline_strategy = GetInlineStrategy();
+    switch (inline_strategy) {
+    case eInlineBreakpointsNever:
+      check_inlines = eLazyBoolNo;
+      break;
+
+    case eInlineBreakpointsHeaders:
+      if (remapped_file.IsSourceImplementationFile())
+        check_inlines = eLazyBoolNo;
+      else
+        check_inlines = eLazyBoolYes;
+      break;
+
+    case eInlineBreakpointsAlways:
+      check_inlines = eLazyBoolYes;
+      break;
+    }
+  }
+  SearchFilterSP filter_sp;
+  if (check_inlines == eLazyBoolNo) {
+    // Not checking for inlines, we are looking only for matching compile units
+    FileSpecList compile_unit_list;
+    compile_unit_list.Append(remapped_file);
+    filter_sp = GetSearchFilterForModuleAndCUList(containingModules,
+                                                  &compile_unit_list);
+  } else {
+    filter_sp = GetSearchFilterForModuleList(containingModules);
+  }
+  if (skip_prologue == eLazyBoolCalculate)
+    skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+  if (move_to_nearest_code == eLazyBoolCalculate)
+    move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
+
+  BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(
+      nullptr, remapped_file, line_no, offset, check_inlines, skip_prologue,
+      !static_cast<bool>(move_to_nearest_code)));
+  return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
+}
+
+BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,
+                                      bool hardware) {
+  Address so_addr;
+
+  // Check for any reason we want to move this breakpoint to other address.
+  addr = GetBreakableLoadAddress(addr);
+
+  // Attempt to resolve our load address if possible, though it is ok if
+  // it doesn't resolve to section/offset.
+
+  // Try and resolve as a load address if possible
+  GetSectionLoadList().ResolveLoadAddress(addr, so_addr);
+  if (!so_addr.IsValid()) {
+    // The address didn't resolve, so just set this as an absolute address
+    so_addr.SetOffset(addr);
+  }
+  BreakpointSP bp_sp(CreateBreakpoint(so_addr, internal, hardware));
+  return bp_sp;
+}
+
+BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal,
+                                      bool hardware) {
+  SearchFilterSP filter_sp(
+      new SearchFilterForUnconstrainedSearches(shared_from_this()));
+  BreakpointResolverSP resolver_sp(
+      new BreakpointResolverAddress(nullptr, addr));
+  return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false);
+}
+
+lldb::BreakpointSP
+Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,
+                                        const FileSpec *file_spec,
+                                        bool request_hardware) {
+  SearchFilterSP filter_sp(
+      new SearchFilterForUnconstrainedSearches(shared_from_this()));
+  BreakpointResolverSP resolver_sp(
+      new BreakpointResolverAddress(nullptr, file_addr, file_spec));
+  return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,
+                          false);
 }
 
 BreakpointSP
-Target::GetBreakpointByID (break_id_t break_id)
-{
-    BreakpointSP bp_sp;
+Target::CreateBreakpoint(const FileSpecList *containingModules,
+                         const FileSpecList *containingSourceFiles,
+                         const char *func_name, uint32_t func_name_type_mask,
+                         LanguageType language, lldb::addr_t offset,
+                         LazyBool skip_prologue, bool internal, bool hardware) {
+  BreakpointSP bp_sp;
+  if (func_name) {
+    SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
+        containingModules, containingSourceFiles));
 
-    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
-        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
-    else
-        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
-
-    return bp_sp;
-}
-
-BreakpointSP
-Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
-                                     const FileSpecList *source_file_spec_list,
-                                     const std::unordered_set<std::string> &function_names,
-                                     RegularExpression &source_regex,
-                                     bool internal,
-                                     bool hardware,
-                                     LazyBool move_to_nearest_code)
-{
-    SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
-    if (move_to_nearest_code == eLazyBoolCalculate)
-        move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
-    BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr,
-                                                                     source_regex,
-                                                                     function_names,
-                                                                     !static_cast<bool>(move_to_nearest_code)));
-    
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
-}
-
-BreakpointSP
-Target::CreateBreakpoint (const FileSpecList *containingModules,
-                          const FileSpec &file,
-                          uint32_t line_no,
-                          lldb::addr_t offset,
-                          LazyBool check_inlines,
-                          LazyBool skip_prologue,
-                          bool internal,
-                          bool hardware,
-                          LazyBool move_to_nearest_code)
-{
-    FileSpec remapped_file;
-    ConstString remapped_path;
-    if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()), remapped_path))
-        remapped_file.SetFile(remapped_path.AsCString(), true);
-    else
-        remapped_file = file;
-
-    if (check_inlines == eLazyBoolCalculate)
-    {
-        const InlineStrategy inline_strategy = GetInlineStrategy();
-        switch (inline_strategy)
-        {
-            case eInlineBreakpointsNever:
-                check_inlines = eLazyBoolNo;
-                break;
-                
-            case eInlineBreakpointsHeaders:
-                if (remapped_file.IsSourceImplementationFile())
-                    check_inlines = eLazyBoolNo;
-                else
-                    check_inlines = eLazyBoolYes;
-                break;
-
-            case eInlineBreakpointsAlways:
-                check_inlines = eLazyBoolYes;
-                break;
-        }
-    }
-    SearchFilterSP filter_sp;
-    if (check_inlines == eLazyBoolNo)
-    {
-        // Not checking for inlines, we are looking only for matching compile units
-        FileSpecList compile_unit_list;
-        compile_unit_list.Append (remapped_file);
-        filter_sp = GetSearchFilterForModuleAndCUList (containingModules, &compile_unit_list);
-    }
-    else
-    {
-        filter_sp = GetSearchFilterForModuleList (containingModules);
-    }
     if (skip_prologue == eLazyBoolCalculate)
+      skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+    if (language == lldb::eLanguageTypeUnknown)
+      language = GetLanguage();
+
+    BreakpointResolverSP resolver_sp(new BreakpointResolverName(
+        nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,
+        offset, skip_prologue));
+    bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
+  }
+  return bp_sp;
+}
+
+lldb::BreakpointSP
+Target::CreateBreakpoint(const FileSpecList *containingModules,
+                         const FileSpecList *containingSourceFiles,
+                         const std::vector<std::string> &func_names,
+                         uint32_t func_name_type_mask, LanguageType language,
+                         lldb::addr_t offset, LazyBool skip_prologue,
+                         bool internal, bool hardware) {
+  BreakpointSP bp_sp;
+  size_t num_names = func_names.size();
+  if (num_names > 0) {
+    SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
+        containingModules, containingSourceFiles));
+
+    if (skip_prologue == eLazyBoolCalculate)
+      skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+    if (language == lldb::eLanguageTypeUnknown)
+      language = GetLanguage();
+
+    BreakpointResolverSP resolver_sp(
+        new BreakpointResolverName(nullptr, func_names, func_name_type_mask,
+                                   language, offset, skip_prologue));
+    bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
+  }
+  return bp_sp;
+}
+
+BreakpointSP Target::CreateBreakpoint(
+    const FileSpecList *containingModules,
+    const FileSpecList *containingSourceFiles, const char *func_names[],
+    size_t num_names, uint32_t func_name_type_mask, LanguageType language,
+    lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) {
+  BreakpointSP bp_sp;
+  if (num_names > 0) {
+    SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
+        containingModules, containingSourceFiles));
+
+    if (skip_prologue == eLazyBoolCalculate) {
+      if (offset == 0)
         skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
-    if (move_to_nearest_code == eLazyBoolCalculate)
-        move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
-
-    BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (nullptr,
-                                                                     remapped_file,
-                                                                     line_no,
-                                                                     offset,
-                                                                     check_inlines,
-                                                                     skip_prologue,
-                                                                     !static_cast<bool>(move_to_nearest_code)));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
-}
-
-BreakpointSP
-Target::CreateBreakpoint (lldb::addr_t addr, bool internal, bool hardware)
-{
-    Address so_addr;
-    
-    // Check for any reason we want to move this breakpoint to other address.
-    addr = GetBreakableLoadAddress(addr);
-
-    // Attempt to resolve our load address if possible, though it is ok if
-    // it doesn't resolve to section/offset.
-
-    // Try and resolve as a load address if possible
-    GetSectionLoadList().ResolveLoadAddress(addr, so_addr);
-    if (!so_addr.IsValid())
-    {
-        // The address didn't resolve, so just set this as an absolute address
-        so_addr.SetOffset (addr);
+      else
+        skip_prologue = eLazyBoolNo;
     }
-    BreakpointSP bp_sp (CreateBreakpoint(so_addr, internal, hardware));
-    return bp_sp;
-}
+    if (language == lldb::eLanguageTypeUnknown)
+      language = GetLanguage();
 
-BreakpointSP
-Target::CreateBreakpoint (const Address &addr, bool internal, bool hardware)
-{
-    SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches (shared_from_this()));
-    BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(nullptr, addr));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, false);
-}
-
-lldb::BreakpointSP
-Target::CreateAddressInModuleBreakpoint (lldb::addr_t file_addr,
-                                         bool internal,
-                                         const FileSpec *file_spec,
-                                         bool request_hardware)
-{
-    SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches (shared_from_this()));
-    BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(nullptr, file_addr, file_spec));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, request_hardware, false);
-}
-
-BreakpointSP
-Target::CreateBreakpoint (const FileSpecList *containingModules,
-                          const FileSpecList *containingSourceFiles,
-                          const char *func_name, 
-                          uint32_t func_name_type_mask,
-                          LanguageType language,
-                          lldb::addr_t offset,
-                          LazyBool skip_prologue,
-                          bool internal,
-                          bool hardware)
-{
-    BreakpointSP bp_sp;
-    if (func_name)
-    {
-        SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-
-        if (skip_prologue == eLazyBoolCalculate)
-            skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
-        if (language == lldb::eLanguageTypeUnknown)
-            language = GetLanguage();
-
-        BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr, 
-                                                                      func_name, 
-                                                                      func_name_type_mask, 
-                                                                      language,
-                                                                      Breakpoint::Exact, 
-                                                                      offset,
-                                                                      skip_prologue));
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
-    }
-    return bp_sp;
-}
-
-lldb::BreakpointSP
-Target::CreateBreakpoint (const FileSpecList *containingModules,
-                          const FileSpecList *containingSourceFiles,
-                          const std::vector<std::string> &func_names,
-                          uint32_t func_name_type_mask,
-                          LanguageType language,
-                          lldb::addr_t offset,
-                          LazyBool skip_prologue,
-                          bool internal,
-                          bool hardware)
-{
-    BreakpointSP bp_sp;
-    size_t num_names = func_names.size();
-    if (num_names > 0)
-    {
-        SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-
-        if (skip_prologue == eLazyBoolCalculate)
-            skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
-        if (language == lldb::eLanguageTypeUnknown)
-            language = GetLanguage();
-
-
-        BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr,
-                                                                      func_names,
-                                                                      func_name_type_mask,
-                                                                      language,
-                                                                      offset,
-                                                                      skip_prologue));
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
-    }
-    return bp_sp;
-}
-
-BreakpointSP
-Target::CreateBreakpoint (const FileSpecList *containingModules,
-                          const FileSpecList *containingSourceFiles,
-                          const char *func_names[],
-                          size_t num_names, 
-                          uint32_t func_name_type_mask,
-                          LanguageType language,
-                          lldb::addr_t offset,
-                          LazyBool skip_prologue,
-                          bool internal,
-                          bool hardware)
-{
-    BreakpointSP bp_sp;
-    if (num_names > 0)
-    {
-        SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-        
-        if (skip_prologue == eLazyBoolCalculate)
-        {
-            if (offset == 0)
-                skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
-            else
-                skip_prologue = eLazyBoolNo;
-        }
-        if (language == lldb::eLanguageTypeUnknown)
-            language = GetLanguage();
-
-        BreakpointResolverSP resolver_sp (new BreakpointResolverName (nullptr,
-                                                                      func_names,
-                                                                      num_names, 
-                                                                      func_name_type_mask,
-                                                                      language,
-                                                                      offset,
-                                                                      skip_prologue));
-        resolver_sp->SetOffset(offset);
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
-    }
-    return bp_sp;
+    BreakpointResolverSP resolver_sp(new BreakpointResolverName(
+        nullptr, func_names, num_names, func_name_type_mask, language, offset,
+        skip_prologue));
+    resolver_sp->SetOffset(offset);
+    bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
+  }
+  return bp_sp;
 }
 
 SearchFilterSP
-Target::GetSearchFilterForModule (const FileSpec *containingModule)
-{
-    SearchFilterSP filter_sp;
-    if (containingModule != nullptr)
-    {
-        // TODO: We should look into sharing module based search filters
-        // across many breakpoints like we do for the simple target based one
-        filter_sp.reset (new SearchFilterByModule (shared_from_this(), *containingModule));
-    }
-    else
-    {
-        if (!m_search_filter_sp)
-            m_search_filter_sp.reset (new SearchFilterForUnconstrainedSearches (shared_from_this()));
-        filter_sp = m_search_filter_sp;
-    }
-    return filter_sp;
+Target::GetSearchFilterForModule(const FileSpec *containingModule) {
+  SearchFilterSP filter_sp;
+  if (containingModule != nullptr) {
+    // TODO: We should look into sharing module based search filters
+    // across many breakpoints like we do for the simple target based one
+    filter_sp.reset(
+        new SearchFilterByModule(shared_from_this(), *containingModule));
+  } else {
+    if (!m_search_filter_sp)
+      m_search_filter_sp.reset(
+          new SearchFilterForUnconstrainedSearches(shared_from_this()));
+    filter_sp = m_search_filter_sp;
+  }
+  return filter_sp;
 }
 
 SearchFilterSP
-Target::GetSearchFilterForModuleList (const FileSpecList *containingModules)
-{
-    SearchFilterSP filter_sp;
-    if (containingModules && containingModules->GetSize() != 0)
-    {
-        // TODO: We should look into sharing module based search filters
-        // across many breakpoints like we do for the simple target based one
-        filter_sp.reset (new SearchFilterByModuleList (shared_from_this(), *containingModules));
-    }
-    else
-    {
-        if (!m_search_filter_sp)
-            m_search_filter_sp.reset (new SearchFilterForUnconstrainedSearches (shared_from_this()));
-        filter_sp = m_search_filter_sp;
-    }
-    return filter_sp;
+Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) {
+  SearchFilterSP filter_sp;
+  if (containingModules && containingModules->GetSize() != 0) {
+    // TODO: We should look into sharing module based search filters
+    // across many breakpoints like we do for the simple target based one
+    filter_sp.reset(
+        new SearchFilterByModuleList(shared_from_this(), *containingModules));
+  } else {
+    if (!m_search_filter_sp)
+      m_search_filter_sp.reset(
+          new SearchFilterForUnconstrainedSearches(shared_from_this()));
+    filter_sp = m_search_filter_sp;
+  }
+  return filter_sp;
 }
 
-SearchFilterSP
-Target::GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules,
-                                           const FileSpecList *containingSourceFiles)
-{
-    if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)
-        return GetSearchFilterForModuleList(containingModules);
-        
-    SearchFilterSP filter_sp;
-    if (containingModules == nullptr)
-    {
-        // We could make a special "CU List only SearchFilter".  Better yet was if these could be composable, 
-        // but that will take a little reworking.
-        
-        filter_sp.reset (new SearchFilterByModuleListAndCU (shared_from_this(), FileSpecList(), *containingSourceFiles));
-    }
-    else
-    {
-        filter_sp.reset (new SearchFilterByModuleListAndCU (shared_from_this(), *containingModules, *containingSourceFiles));
-    }
-    return filter_sp;
+SearchFilterSP Target::GetSearchFilterForModuleAndCUList(
+    const FileSpecList *containingModules,
+    const FileSpecList *containingSourceFiles) {
+  if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)
+    return GetSearchFilterForModuleList(containingModules);
+
+  SearchFilterSP filter_sp;
+  if (containingModules == nullptr) {
+    // We could make a special "CU List only SearchFilter".  Better yet was if
+    // these could be composable,
+    // but that will take a little reworking.
+
+    filter_sp.reset(new SearchFilterByModuleListAndCU(
+        shared_from_this(), FileSpecList(), *containingSourceFiles));
+  } else {
+    filter_sp.reset(new SearchFilterByModuleListAndCU(
+        shared_from_this(), *containingModules, *containingSourceFiles));
+  }
+  return filter_sp;
 }
 
-BreakpointSP
-Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules, 
-                                   const FileSpecList *containingSourceFiles,
-                                   RegularExpression &func_regex, 
-                                   lldb::LanguageType requested_language,
-                                   LazyBool skip_prologue,
-                                   bool internal,
-                                   bool hardware)
-{
-    SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
-    bool skip =
-      (skip_prologue == eLazyBoolCalculate) ? GetSkipPrologue()
-                                            : static_cast<bool>(skip_prologue);
-    BreakpointResolverSP resolver_sp(new BreakpointResolverName (nullptr, 
-                                                                 func_regex,
-                                                                 requested_language,
-                                                                 0,
-                                                                 skip));
+BreakpointSP Target::CreateFuncRegexBreakpoint(
+    const FileSpecList *containingModules,
+    const FileSpecList *containingSourceFiles, RegularExpression &func_regex,
+    lldb::LanguageType requested_language, LazyBool skip_prologue,
+    bool internal, bool hardware) {
+  SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
+      containingModules, containingSourceFiles));
+  bool skip = (skip_prologue == eLazyBoolCalculate)
+                  ? GetSkipPrologue()
+                  : static_cast<bool>(skip_prologue);
+  BreakpointResolverSP resolver_sp(new BreakpointResolverName(
+      nullptr, func_regex, requested_language, 0, skip));
 
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
+  return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
 }
 
 lldb::BreakpointSP
-Target::CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal, Args *additional_args, Error *error)
-{
-    BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint (*this, language, catch_bp, throw_bp, internal);
-    if (exc_bkpt_sp && additional_args)
-    {
-        Breakpoint::BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();
-        if (precondition_sp && additional_args)
-        {
-            if (error)
-                *error = precondition_sp->ConfigurePrecondition(*additional_args);
-            else
-                precondition_sp->ConfigurePrecondition(*additional_args);
-        }
+Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
+                                  bool catch_bp, bool throw_bp, bool internal,
+                                  Args *additional_args, Error *error) {
+  BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(
+      *this, language, catch_bp, throw_bp, internal);
+  if (exc_bkpt_sp && additional_args) {
+    Breakpoint::BreakpointPreconditionSP precondition_sp =
+        exc_bkpt_sp->GetPrecondition();
+    if (precondition_sp && additional_args) {
+      if (error)
+        *error = precondition_sp->ConfigurePrecondition(*additional_args);
+      else
+        precondition_sp->ConfigurePrecondition(*additional_args);
     }
-    return exc_bkpt_sp;
+  }
+  return exc_bkpt_sp;
 }
 
-BreakpointSP
-Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols)
-{
-    BreakpointSP bp_sp;
-    if (filter_sp && resolver_sp)
-    {
-        bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp, request_hardware, resolve_indirect_symbols));
-        resolver_sp->SetBreakpoint (bp_sp.get());
-        AddBreakpoint (bp_sp, internal);
-    }
-    return bp_sp;
+BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,
+                                      BreakpointResolverSP &resolver_sp,
+                                      bool internal, bool request_hardware,
+                                      bool resolve_indirect_symbols) {
+  BreakpointSP bp_sp;
+  if (filter_sp && resolver_sp) {
+    bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, request_hardware,
+                               resolve_indirect_symbols));
+    resolver_sp->SetBreakpoint(bp_sp.get());
+    AddBreakpoint(bp_sp, internal);
+  }
+  return bp_sp;
 }
 
-void
-Target::AddBreakpoint (lldb::BreakpointSP bp_sp, bool internal)
-{
-    if (!bp_sp)
-        return;
-    if (internal)
-        m_internal_breakpoint_list.Add (bp_sp, false);
-    else
-        m_breakpoint_list.Add (bp_sp, true);
+void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
+  if (!bp_sp)
+    return;
+  if (internal)
+    m_internal_breakpoint_list.Add(bp_sp, false);
+  else
+    m_breakpoint_list.Add(bp_sp, true);
 
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-    {
-        StreamString s;
-        bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
-        log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData());
-    }
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log) {
+    StreamString s;
+    bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
+    log->Printf("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__,
+                bp_sp->IsInternal() ? "yes" : "no", s.GetData());
+  }
 
-    bp_sp->ResolveBreakpoint();
+  bp_sp->ResolveBreakpoint();
 
-    if (!internal)
-    {
-        m_last_created_breakpoint = bp_sp;
-    }
+  if (!internal) {
+    m_last_created_breakpoint = bp_sp;
+  }
 }
 
-bool
-Target::ProcessIsValid()
-{
-    return (m_process_sp && m_process_sp->IsAlive());
+bool Target::ProcessIsValid() {
+  return (m_process_sp && m_process_sp->IsAlive());
 }
 
-static bool
-CheckIfWatchpointsExhausted(Target *target, Error &error)
-{
-    uint32_t num_supported_hardware_watchpoints;
-    Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
-    if (num_supported_hardware_watchpoints == 0)
-    {
-        error.SetErrorStringWithFormat ("Target supports (%u) hardware watchpoint slots.\n",
-                    num_supported_hardware_watchpoints);
-        return false;
-    }
-    return true;
+static bool CheckIfWatchpointsExhausted(Target *target, Error &error) {
+  uint32_t num_supported_hardware_watchpoints;
+  Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(
+      num_supported_hardware_watchpoints);
+  if (num_supported_hardware_watchpoints == 0) {
+    error.SetErrorStringWithFormat(
+        "Target supports (%u) hardware watchpoint slots.\n",
+        num_supported_hardware_watchpoints);
+    return false;
+  }
+  return true;
 }
 
 // See also Watchpoint::SetWatchpointType(uint32_t type) and
 // the OptionGroupWatchpoint::WatchType enum type.
-WatchpointSP
-Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *type, uint32_t kind, Error &error)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 " type = %u)\n",
-                    __FUNCTION__, addr, (uint64_t)size, kind);
+WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
+                                      const CompilerType *type, uint32_t kind,
+                                      Error &error) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
+                " type = %u)\n",
+                __FUNCTION__, addr, (uint64_t)size, kind);
 
-    WatchpointSP wp_sp;
-    if (!ProcessIsValid())
-    {
-        error.SetErrorString("process is not alive");
-        return wp_sp;
-    }
-    
-    if (addr == LLDB_INVALID_ADDRESS || size == 0)
-    {
-        if (size == 0)
-            error.SetErrorString("cannot set a watchpoint with watch_size of 0");
-        else
-            error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
-        return wp_sp;
-    }
-    
-    if (!LLDB_WATCH_TYPE_IS_VALID(kind))
-    {
-        error.SetErrorStringWithFormat ("invalid watchpoint type: %d", kind);
-    }
-
-    if (!CheckIfWatchpointsExhausted (this, error))
-        return wp_sp;
-
-    // Currently we only support one watchpoint per address, with total number
-    // of watchpoints limited by the hardware which the inferior is running on.
-
-    // Grab the list mutex while doing operations.
-    const bool notify = false;   // Don't notify about all the state changes we do on creating the watchpoint.
-    std::unique_lock<std::recursive_mutex> lock;
-    this->GetWatchpointList().GetListMutex(lock);
-    WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
-    if (matched_sp)
-    {
-        size_t old_size = matched_sp->GetByteSize();
-        uint32_t old_type =
-            (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
-            (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0);
-        // Return the existing watchpoint if both size and type match.
-        if (size == old_size && kind == old_type)
-        {
-            wp_sp = matched_sp;
-            wp_sp->SetEnabled(false, notify);
-        }
-        else
-        {
-            // Nil the matched watchpoint; we will be creating a new one.
-            m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
-            m_watchpoint_list.Remove(matched_sp->GetID(), true);
-        }
-    }
-
-    if (!wp_sp) 
-    {
-        wp_sp.reset(new Watchpoint(*this, addr, size, type));
-        wp_sp->SetWatchpointType(kind, notify);
-        m_watchpoint_list.Add (wp_sp, true);
-    }
-
-    error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
-    if (log)
-        log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
-                    __FUNCTION__,
-                    error.Success() ? "succeeded" : "failed",
-                    wp_sp->GetID());
-
-    if (error.Fail()) 
-    {
-        // Enabling the watchpoint on the device side failed.
-        // Remove the said watchpoint from the list maintained by the target instance.
-        m_watchpoint_list.Remove (wp_sp->GetID(), true);
-        // See if we could provide more helpful error message.
-        if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
-            error.SetErrorStringWithFormat("watch size of %" PRIu64 " is not supported", (uint64_t)size);
-
-        wp_sp.reset();
-    }
-    else
-        m_last_created_watchpoint = wp_sp;
+  WatchpointSP wp_sp;
+  if (!ProcessIsValid()) {
+    error.SetErrorString("process is not alive");
     return wp_sp;
-}
+  }
 
-void
-Target::RemoveAllBreakpoints (bool internal_also)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
-
-    m_breakpoint_list.RemoveAll (true);
-    if (internal_also)
-        m_internal_breakpoint_list.RemoveAll (false);
-        
-    m_last_created_breakpoint.reset();
-}
-
-void
-Target::DisableAllBreakpoints (bool internal_also)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
-
-    m_breakpoint_list.SetEnabledAll (false);
-    if (internal_also)
-        m_internal_breakpoint_list.SetEnabledAll (false);
-}
-
-void
-Target::EnableAllBreakpoints (bool internal_also)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
-
-    m_breakpoint_list.SetEnabledAll (true);
-    if (internal_also)
-        m_internal_breakpoint_list.SetEnabledAll (true);
-}
-
-bool
-Target::RemoveBreakpointByID (break_id_t break_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
-
-    if (DisableBreakpointByID (break_id))
-    {
-        if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
-            m_internal_breakpoint_list.Remove(break_id, false);
-        else
-        {
-            if (m_last_created_breakpoint)
-            {
-                if (m_last_created_breakpoint->GetID() == break_id)
-                    m_last_created_breakpoint.reset();
-            }
-            m_breakpoint_list.Remove(break_id, true);
-        }
-        return true;
-    }
-    return false;
-}
-
-bool
-Target::DisableBreakpointByID (break_id_t break_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
-
-    BreakpointSP bp_sp;
-
-    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
-        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
+  if (addr == LLDB_INVALID_ADDRESS || size == 0) {
+    if (size == 0)
+      error.SetErrorString("cannot set a watchpoint with watch_size of 0");
     else
-        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
-    if (bp_sp)
-    {
-        bp_sp->SetEnabled (false);
-        return true;
+      error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
+    return wp_sp;
+  }
+
+  if (!LLDB_WATCH_TYPE_IS_VALID(kind)) {
+    error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind);
+  }
+
+  if (!CheckIfWatchpointsExhausted(this, error))
+    return wp_sp;
+
+  // Currently we only support one watchpoint per address, with total number
+  // of watchpoints limited by the hardware which the inferior is running on.
+
+  // Grab the list mutex while doing operations.
+  const bool notify = false; // Don't notify about all the state changes we do
+                             // on creating the watchpoint.
+  std::unique_lock<std::recursive_mutex> lock;
+  this->GetWatchpointList().GetListMutex(lock);
+  WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
+  if (matched_sp) {
+    size_t old_size = matched_sp->GetByteSize();
+    uint32_t old_type =
+        (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
+        (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0);
+    // Return the existing watchpoint if both size and type match.
+    if (size == old_size && kind == old_type) {
+      wp_sp = matched_sp;
+      wp_sp->SetEnabled(false, notify);
+    } else {
+      // Nil the matched watchpoint; we will be creating a new one.
+      m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
+      m_watchpoint_list.Remove(matched_sp->GetID(), true);
     }
-    return false;
+  }
+
+  if (!wp_sp) {
+    wp_sp.reset(new Watchpoint(*this, addr, size, type));
+    wp_sp->SetWatchpointType(kind, notify);
+    m_watchpoint_list.Add(wp_sp, true);
+  }
+
+  error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
+  if (log)
+    log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
+                __FUNCTION__, error.Success() ? "succeeded" : "failed",
+                wp_sp->GetID());
+
+  if (error.Fail()) {
+    // Enabling the watchpoint on the device side failed.
+    // Remove the said watchpoint from the list maintained by the target
+    // instance.
+    m_watchpoint_list.Remove(wp_sp->GetID(), true);
+    // See if we could provide more helpful error message.
+    if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
+      error.SetErrorStringWithFormat(
+          "watch size of %" PRIu64 " is not supported", (uint64_t)size);
+
+    wp_sp.reset();
+  } else
+    m_last_created_watchpoint = wp_sp;
+  return wp_sp;
 }
 
-bool
-Target::EnableBreakpointByID (break_id_t break_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("Target::%s (break_id = %i, internal = %s)\n",
-                     __FUNCTION__,
-                     break_id,
-                     LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
+void Target::RemoveAllBreakpoints(bool internal_also) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
+                internal_also ? "yes" : "no");
 
-    BreakpointSP bp_sp;
+  m_breakpoint_list.RemoveAll(true);
+  if (internal_also)
+    m_internal_breakpoint_list.RemoveAll(false);
 
-    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
-        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
-    else
-        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
+  m_last_created_breakpoint.reset();
+}
 
-    if (bp_sp)
-    {
-        bp_sp->SetEnabled (true);
-        return true;
+void Target::DisableAllBreakpoints(bool internal_also) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
+                internal_also ? "yes" : "no");
+
+  m_breakpoint_list.SetEnabledAll(false);
+  if (internal_also)
+    m_internal_breakpoint_list.SetEnabledAll(false);
+}
+
+void Target::EnableAllBreakpoints(bool internal_also) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
+                internal_also ? "yes" : "no");
+
+  m_breakpoint_list.SetEnabledAll(true);
+  if (internal_also)
+    m_internal_breakpoint_list.SetEnabledAll(true);
+}
+
+bool Target::RemoveBreakpointByID(break_id_t break_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+                break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+
+  if (DisableBreakpointByID(break_id)) {
+    if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
+      m_internal_breakpoint_list.Remove(break_id, false);
+    else {
+      if (m_last_created_breakpoint) {
+        if (m_last_created_breakpoint->GetID() == break_id)
+          m_last_created_breakpoint.reset();
+      }
+      m_breakpoint_list.Remove(break_id, true);
     }
-    return false;
+    return true;
+  }
+  return false;
+}
+
+bool Target::DisableBreakpointByID(break_id_t break_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+                break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+
+  BreakpointSP bp_sp;
+
+  if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
+    bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
+  else
+    bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
+  if (bp_sp) {
+    bp_sp->SetEnabled(false);
+    return true;
+  }
+  return false;
+}
+
+bool Target::EnableBreakpointByID(break_id_t break_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+                break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+
+  BreakpointSP bp_sp;
+
+  if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
+    bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
+  else
+    bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
+
+  if (bp_sp) {
+    bp_sp->SetEnabled(true);
+    return true;
+  }
+  return false;
 }
 
 // The flag 'end_to_end', default to true, signifies that the operation is
@@ -924,3404 +799,3162 @@
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
 // to end operations.
-bool
-Target::RemoveAllWatchpoints (bool end_to_end)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
+bool Target::RemoveAllWatchpoints(bool end_to_end) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
 
-    if (!end_to_end) {
-        m_watchpoint_list.RemoveAll(true);
-        return true;
-    }
+  if (!end_to_end) {
+    m_watchpoint_list.RemoveAll(true);
+    return true;
+  }
 
-    // Otherwise, it's an end to end operation.
+  // Otherwise, it's an end to end operation.
 
-    if (!ProcessIsValid())
-        return false;
+  if (!ProcessIsValid())
+    return false;
 
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
 
-        Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
-        if (rc.Fail())
-            return false;
-    }
-    m_watchpoint_list.RemoveAll (true);
-    m_last_created_watchpoint.reset();
-    return true; // Success!
+    Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+    if (rc.Fail())
+      return false;
+  }
+  m_watchpoint_list.RemoveAll(true);
+  m_last_created_watchpoint.reset();
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
 // end operations.
-bool
-Target::DisableAllWatchpoints (bool end_to_end)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
+bool Target::DisableAllWatchpoints(bool end_to_end) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
 
-    if (!end_to_end) {
-        m_watchpoint_list.SetEnabledAll(false);
-        return true;
-    }
+  if (!end_to_end) {
+    m_watchpoint_list.SetEnabledAll(false);
+    return true;
+  }
 
-    // Otherwise, it's an end to end operation.
+  // Otherwise, it's an end to end operation.
 
-    if (!ProcessIsValid())
-        return false;
+  if (!ProcessIsValid())
+    return false;
 
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
 
-        Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
-        if (rc.Fail())
-            return false;
-    }
-    return true; // Success!
+    Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+    if (rc.Fail())
+      return false;
+  }
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
 // end operations.
-bool
-Target::EnableAllWatchpoints (bool end_to_end)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
+bool Target::EnableAllWatchpoints(bool end_to_end) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
 
-    if (!end_to_end) {
-        m_watchpoint_list.SetEnabledAll(true);
-        return true;
-    }
+  if (!end_to_end) {
+    m_watchpoint_list.SetEnabledAll(true);
+    return true;
+  }
 
-    // Otherwise, it's an end to end operation.
+  // Otherwise, it's an end to end operation.
 
-    if (!ProcessIsValid())
-        return false;
+  if (!ProcessIsValid())
+    return false;
 
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
 
-        Error rc = m_process_sp->EnableWatchpoint(wp_sp.get());
-        if (rc.Fail())
-            return false;
-    }
-    return true; // Success!
+    Error rc = m_process_sp->EnableWatchpoint(wp_sp.get());
+    if (rc.Fail())
+      return false;
+  }
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::ClearAllWatchpointHitCounts ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
+bool Target::ClearAllWatchpointHitCounts() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
 
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
 
-        wp_sp->ResetHitCount();
-    }
-    return true; // Success!
+    wp_sp->ResetHitCount();
+  }
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::ClearAllWatchpointHistoricValues ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
-    
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
-        
-        wp_sp->ResetHistoricValues();
-    }
-    return true; // Success!
+bool Target::ClearAllWatchpointHistoricValues() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
+
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
+
+    wp_sp->ResetHistoricValues();
+  }
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list
 // during these operations.
-bool
-Target::IgnoreAllWatchpoints (uint32_t ignore_count)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s\n", __FUNCTION__);
+bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s\n", __FUNCTION__);
 
-    if (!ProcessIsValid())
-        return false;
+  if (!ProcessIsValid())
+    return false;
 
-    size_t num_watchpoints = m_watchpoint_list.GetSize();
-    for (size_t i = 0; i < num_watchpoints; ++i)
-    {
-        WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
-        if (!wp_sp)
-            return false;
+  size_t num_watchpoints = m_watchpoint_list.GetSize();
+  for (size_t i = 0; i < num_watchpoints; ++i) {
+    WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+    if (!wp_sp)
+      return false;
 
-        wp_sp->SetIgnoreCount(ignore_count);
-    }
-    return true; // Success!
+    wp_sp->SetIgnoreCount(ignore_count);
+  }
+  return true; // Success!
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::DisableWatchpointByID (lldb::watch_id_t watch_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
-    if (!ProcessIsValid())
-        return false;
-
-    WatchpointSP wp_sp = m_watchpoint_list.FindByID (watch_id);
-    if (wp_sp)
-    {
-        Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
-        if (rc.Success())
-            return true;
-
-        // Else, fallthrough.
-    }
+  if (!ProcessIsValid())
     return false;
+
+  WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
+  if (wp_sp) {
+    Error rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+    if (rc.Success())
+      return true;
+
+    // Else, fallthrough.
+  }
+  return false;
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::EnableWatchpointByID (lldb::watch_id_t watch_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
-    if (!ProcessIsValid())
-        return false;
-
-    WatchpointSP wp_sp = m_watchpoint_list.FindByID (watch_id);
-    if (wp_sp)
-    {
-        Error rc = m_process_sp->EnableWatchpoint(wp_sp.get());
-        if (rc.Success())
-            return true;
-
-        // Else, fallthrough.
-    }
+  if (!ProcessIsValid())
     return false;
+
+  WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
+  if (wp_sp) {
+    Error rc = m_process_sp->EnableWatchpoint(wp_sp.get());
+    if (rc.Success())
+      return true;
+
+    // Else, fallthrough.
+  }
+  return false;
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::RemoveWatchpointByID (lldb::watch_id_t watch_id)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
-    WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);
-    if (watch_to_remove_sp == m_last_created_watchpoint)
-        m_last_created_watchpoint.reset();
-        
-    if (DisableWatchpointByID (watch_id))
-    {
-        m_watchpoint_list.Remove(watch_id, true);
-        return true;
-    }
-    return false;
+  WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);
+  if (watch_to_remove_sp == m_last_created_watchpoint)
+    m_last_created_watchpoint.reset();
+
+  if (DisableWatchpointByID(watch_id)) {
+    m_watchpoint_list.Remove(watch_id, true);
+    return true;
+  }
+  return false;
 }
 
 // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
-bool
-Target::IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-    if (log)
-        log->Printf ("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,
+                                  uint32_t ignore_count) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  if (log)
+    log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
 
-    if (!ProcessIsValid())
-        return false;
-
-    WatchpointSP wp_sp = m_watchpoint_list.FindByID (watch_id);
-    if (wp_sp)
-    {
-        wp_sp->SetIgnoreCount(ignore_count);
-        return true;
-    }
+  if (!ProcessIsValid())
     return false;
+
+  WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
+  if (wp_sp) {
+    wp_sp->SetIgnoreCount(ignore_count);
+    return true;
+  }
+  return false;
 }
 
-ModuleSP
-Target::GetExecutableModule ()
-{
-    // search for the first executable in the module list
-    for (size_t i = 0; i < m_images.GetSize(); ++i)
-    {
-        ModuleSP module_sp = m_images.GetModuleAtIndex (i);
-        lldb_private::ObjectFile * obj = module_sp->GetObjectFile();
-        if (obj == nullptr)
-            continue;
-        if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
-            return module_sp;
-    }
-    // as fall back return the first module loaded
-    return m_images.GetModuleAtIndex (0);
+ModuleSP Target::GetExecutableModule() {
+  // search for the first executable in the module list
+  for (size_t i = 0; i < m_images.GetSize(); ++i) {
+    ModuleSP module_sp = m_images.GetModuleAtIndex(i);
+    lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
+    if (obj == nullptr)
+      continue;
+    if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
+      return module_sp;
+  }
+  // as fall back return the first module loaded
+  return m_images.GetModuleAtIndex(0);
 }
 
-Module*
-Target::GetExecutableModulePointer ()
-{
-    return GetExecutableModule().get();
+Module *Target::GetExecutableModulePointer() {
+  return GetExecutableModule().get();
 }
 
-static void
-LoadScriptingResourceForModule (const ModuleSP &module_sp, Target *target)
-{
-    Error error;
-    StreamString feedback_stream;
-    if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, &feedback_stream))
-    {
-        if (error.AsCString())
-            target->GetDebugger().GetErrorFile()->Printf("unable to load scripting data for module %s - error reported was %s\n",
-                                                           module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
-                                                           error.AsCString());
-    }
-    if (feedback_stream.GetSize())
-        target->GetDebugger().GetErrorFile()->Printf("%s\n",
-                                                     feedback_stream.GetData());
+static void LoadScriptingResourceForModule(const ModuleSP &module_sp,
+                                           Target *target) {
+  Error error;
+  StreamString feedback_stream;
+  if (module_sp &&
+      !module_sp->LoadScriptingResourceInTarget(target, error,
+                                                &feedback_stream)) {
+    if (error.AsCString())
+      target->GetDebugger().GetErrorFile()->Printf(
+          "unable to load scripting data for module %s - error reported was "
+          "%s\n",
+          module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
+          error.AsCString());
+  }
+  if (feedback_stream.GetSize())
+    target->GetDebugger().GetErrorFile()->Printf("%s\n",
+                                                 feedback_stream.GetData());
 }
 
-void
-Target::ClearModules(bool delete_locations)
-{
-    ModulesDidUnload (m_images, delete_locations);
-    m_section_load_history.Clear();
-    m_images.Clear();
-    m_scratch_type_system_map.Clear();
-    m_ast_importer_sp.reset();
+void Target::ClearModules(bool delete_locations) {
+  ModulesDidUnload(m_images, delete_locations);
+  m_section_load_history.Clear();
+  m_images.Clear();
+  m_scratch_type_system_map.Clear();
+  m_ast_importer_sp.reset();
 }
 
-void
-Target::DidExec ()
-{
-    // When a process exec's we need to know about it so we can do some cleanup. 
-    m_breakpoint_list.RemoveInvalidLocations(m_arch);
-    m_internal_breakpoint_list.RemoveInvalidLocations(m_arch);
+void Target::DidExec() {
+  // When a process exec's we need to know about it so we can do some cleanup.
+  m_breakpoint_list.RemoveInvalidLocations(m_arch);
+  m_internal_breakpoint_list.RemoveInvalidLocations(m_arch);
 }
 
-void
-Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
-    ClearModules(false);
-    
-    if (executable_sp)
-    {
-        Timer scoped_timer (LLVM_PRETTY_FUNCTION,
-                            "Target::SetExecutableModule (executable = '%s')",
-                            executable_sp->GetFileSpec().GetPath().c_str());
+void Target::SetExecutableModule(ModuleSP &executable_sp,
+                                 bool get_dependent_files) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+  ClearModules(false);
 
-        m_images.Append(executable_sp); // The first image is our executable file
+  if (executable_sp) {
+    Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+                       "Target::SetExecutableModule (executable = '%s')",
+                       executable_sp->GetFileSpec().GetPath().c_str());
 
-        // If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
-        if (!m_arch.IsValid())
-        {
-            m_arch = executable_sp->GetArchitecture();
-            if (log)
-              log->Printf ("Target::SetExecutableModule setting architecture to %s (%s) based on executable file", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
-        }
+    m_images.Append(executable_sp); // The first image is our executable file
 
-        FileSpecList dependent_files;
-        ObjectFile *executable_objfile = executable_sp->GetObjectFile();
-
-        if (executable_objfile && get_dependent_files)
-        {
-            executable_objfile->GetDependentModules(dependent_files);
-            for (uint32_t i=0; i<dependent_files.GetSize(); i++)
-            {
-                FileSpec dependent_file_spec (dependent_files.GetFileSpecPointerAtIndex(i));
-                FileSpec platform_dependent_file_spec;
-                if (m_platform_sp)
-                    m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr, platform_dependent_file_spec);
-                else
-                    platform_dependent_file_spec = dependent_file_spec;
-
-                ModuleSpec module_spec (platform_dependent_file_spec, m_arch);
-                ModuleSP image_module_sp(GetSharedModule (module_spec));
-                if (image_module_sp)
-                {
-                    ObjectFile *objfile = image_module_sp->GetObjectFile();
-                    if (objfile)
-                        objfile->GetDependentModules(dependent_files);
-                }
-            }
-        }
-    }
-}
-
-bool
-Target::SetArchitecture (const ArchSpec &arch_spec)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
-    bool missing_local_arch = !m_arch.IsValid();
-    bool replace_local_arch = true;
-    bool compatible_local_arch = false;
-    ArchSpec other(arch_spec);
-
-    if (!missing_local_arch)
-    {
-        if (m_arch.IsCompatibleMatch(arch_spec))
-        {
-            other.MergeFrom(m_arch);
-            
-            if (m_arch.IsCompatibleMatch(other))
-            {
-                compatible_local_arch = true;
-                bool arch_changed, vendor_changed, os_changed, os_ver_changed, env_changed;
-                
-                m_arch.PiecewiseTripleCompare(other,
-                                              arch_changed,
-                                              vendor_changed,
-                                              os_changed,
-                                              os_ver_changed,
-                                              env_changed);
-                
-                if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
-                    replace_local_arch = false;
-            }
-        }
+    // If we haven't set an architecture yet, reset our architecture based on
+    // what we found in the executable module.
+    if (!m_arch.IsValid()) {
+      m_arch = executable_sp->GetArchitecture();
+      if (log)
+        log->Printf("Target::SetExecutableModule setting architecture to %s "
+                    "(%s) based on executable file",
+                    m_arch.GetArchitectureName(),
+                    m_arch.GetTriple().getTriple().c_str());
     }
 
-    if (compatible_local_arch || missing_local_arch)
-    {
-        // If we haven't got a valid arch spec, or the architectures are compatible
-        // update the architecture, unless the one we already have is more specified
-        if (replace_local_arch)
-            m_arch = other;
-        if (log)
-            log->Printf ("Target::SetArchitecture set architecture to %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
-        return true;
-    }
-    
-    // If we have an executable file, try to reset the executable to the desired architecture
-    if (log)
-      log->Printf ("Target::SetArchitecture changing architecture to %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
-    m_arch = other;
-    ModuleSP executable_sp = GetExecutableModule ();
+    FileSpecList dependent_files;
+    ObjectFile *executable_objfile = executable_sp->GetObjectFile();
 
-    ClearModules(true);
-    // Need to do something about unsetting breakpoints.
-    
-    if (executable_sp)
-    {
-        if (log)
-          log->Printf("Target::SetArchitecture Trying to select executable file architecture %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
-        ModuleSpec module_spec (executable_sp->GetFileSpec(), other);
-        Error error = ModuleList::GetSharedModule(module_spec, 
-                                                  executable_sp, 
-                                                  &GetExecutableSearchPaths(),
-                                                  nullptr, 
-                                                  nullptr);
-                                      
-        if (!error.Fail() && executable_sp)
-        {
-            SetExecutableModule (executable_sp, true);
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-Target::MergeArchitecture (const ArchSpec &arch_spec)
-{
-    if (arch_spec.IsValid())
-    {
-        if (m_arch.IsCompatibleMatch(arch_spec))
-        {
-            // The current target arch is compatible with "arch_spec", see if we
-            // can improve our current architecture using bits from "arch_spec"
-
-            // Merge bits from arch_spec into "merged_arch" and set our architecture
-            ArchSpec merged_arch (m_arch);
-            merged_arch.MergeFrom (arch_spec);
-            return SetArchitecture(merged_arch);
-        }
-        else
-        {
-            // The new architecture is different, we just need to replace it
-            return SetArchitecture(arch_spec);
-        }
-    }
-    return false;
-}
-
-void
-Target::WillClearList (const ModuleList& module_list)
-{
-}
-
-void
-Target::ModuleAdded (const ModuleList& module_list, const ModuleSP &module_sp)
-{
-    // A module is being added to this target for the first time
-    if (m_valid)
-    {
-        ModuleList my_module_list;
-        my_module_list.Append(module_sp);
-        LoadScriptingResourceForModule(module_sp, this);
-        ModulesDidLoad (my_module_list);
-    }
-}
-
-void
-Target::ModuleRemoved (const ModuleList& module_list, const ModuleSP &module_sp)
-{
-    // A module is being removed from this target.
-    if (m_valid)
-    {
-        ModuleList my_module_list;
-        my_module_list.Append(module_sp);
-        ModulesDidUnload (my_module_list, false);
-    }
-}
-
-void
-Target::ModuleUpdated (const ModuleList& module_list, const ModuleSP &old_module_sp, const ModuleSP &new_module_sp)
-{
-    // A module is replacing an already added module
-    if (m_valid)
-    {
-        m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp);
-        m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp);
-    }
-}
-
-void
-Target::ModulesDidLoad (ModuleList &module_list)
-{
-    if (m_valid && module_list.GetSize())
-    {
-        m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
-        m_internal_breakpoint_list.UpdateBreakpoints (module_list, true, false);
-        if (m_process_sp)
-        {
-            m_process_sp->ModulesDidLoad (module_list);
-        }
-        BroadcastEvent (eBroadcastBitModulesLoaded, new TargetEventData (this->shared_from_this(), module_list));
-    }
-}
-
-void
-Target::SymbolsDidLoad (ModuleList &module_list)
-{
-    if (m_valid && module_list.GetSize())
-    {
-        if (m_process_sp)
-        {
-            LanguageRuntime* runtime = m_process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-            if (runtime)
-            {
-                ObjCLanguageRuntime *objc_runtime = (ObjCLanguageRuntime*)runtime;
-                objc_runtime->SymbolsDidLoad(module_list);
-            }
-        }
-        
-        m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
-        m_internal_breakpoint_list.UpdateBreakpoints (module_list, true, false);
-        BroadcastEvent (eBroadcastBitSymbolsLoaded, new TargetEventData (this->shared_from_this(), module_list));
-    }
-}
-
-void
-Target::ModulesDidUnload (ModuleList &module_list, bool delete_locations)
-{
-    if (m_valid && module_list.GetSize())
-    {
-        UnloadModuleSections (module_list);
-        m_breakpoint_list.UpdateBreakpoints (module_list, false, delete_locations);
-        m_internal_breakpoint_list.UpdateBreakpoints (module_list, false, delete_locations);
-        BroadcastEvent (eBroadcastBitModulesUnloaded, new TargetEventData (this->shared_from_this(), module_list));
-    }
-}
-
-bool
-Target::ModuleIsExcludedForUnconstrainedSearches (const FileSpec &module_file_spec)
-{
-    if (GetBreakpointsConsultPlatformAvoidList())
-    {
-        ModuleList matchingModules;
-        ModuleSpec module_spec (module_file_spec);
-        size_t num_modules = GetImages().FindModules(module_spec, matchingModules);
-        
-        // If there is more than one module for this file spec, only return true if ALL the modules are on the
-        // black list.
-        if (num_modules > 0)
-        {
-            for (size_t i  = 0; i < num_modules; i++)
-            {
-                if (!ModuleIsExcludedForUnconstrainedSearches (matchingModules.GetModuleAtIndex(i)))
-                    return false;
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-Target::ModuleIsExcludedForUnconstrainedSearches (const lldb::ModuleSP &module_sp)
-{
-    if (GetBreakpointsConsultPlatformAvoidList())
-    {
+    if (executable_objfile && get_dependent_files) {
+      executable_objfile->GetDependentModules(dependent_files);
+      for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
+        FileSpec dependent_file_spec(
+            dependent_files.GetFileSpecPointerAtIndex(i));
+        FileSpec platform_dependent_file_spec;
         if (m_platform_sp)
-            return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches (*this, module_sp);
+          m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr,
+                                         platform_dependent_file_spec);
+        else
+          platform_dependent_file_spec = dependent_file_spec;
+
+        ModuleSpec module_spec(platform_dependent_file_spec, m_arch);
+        ModuleSP image_module_sp(GetSharedModule(module_spec));
+        if (image_module_sp) {
+          ObjectFile *objfile = image_module_sp->GetObjectFile();
+          if (objfile)
+            objfile->GetDependentModules(dependent_files);
+        }
+      }
     }
-    return false;
+  }
 }
 
-size_t
-Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len, Error &error)
-{
-    SectionSP section_sp (addr.GetSection());
-    if (section_sp)
-    {
-        // If the contents of this section are encrypted, the on-disk file is unusable.  Read only from live memory.
-        if (section_sp->IsEncrypted())
-        {
-            error.SetErrorString("section is encrypted");
-            return 0;
-        }
-        ModuleSP module_sp (section_sp->GetModule());
-        if (module_sp)
-        {
-            ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();
-            if (objfile)
-            {
-                size_t bytes_read = objfile->ReadSectionData (section_sp.get(), 
-                                                              addr.GetOffset(), 
-                                                              dst, 
-                                                              dst_len);
-                if (bytes_read > 0)
-                    return bytes_read;
-                else
-                    error.SetErrorStringWithFormat("error reading data from section %s", section_sp->GetName().GetCString());
-            }
-            else
-                error.SetErrorString("address isn't from a object file");
-        }
-        else
-            error.SetErrorString("address isn't in a module");
-    }
-    else
-        error.SetErrorString("address doesn't contain a section that points to a section in a object file");
+bool Target::SetArchitecture(const ArchSpec &arch_spec) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+  bool missing_local_arch = !m_arch.IsValid();
+  bool replace_local_arch = true;
+  bool compatible_local_arch = false;
+  ArchSpec other(arch_spec);
 
-    return 0;
+  if (!missing_local_arch) {
+    if (m_arch.IsCompatibleMatch(arch_spec)) {
+      other.MergeFrom(m_arch);
+
+      if (m_arch.IsCompatibleMatch(other)) {
+        compatible_local_arch = true;
+        bool arch_changed, vendor_changed, os_changed, os_ver_changed,
+            env_changed;
+
+        m_arch.PiecewiseTripleCompare(other, arch_changed, vendor_changed,
+                                      os_changed, os_ver_changed, env_changed);
+
+        if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
+          replace_local_arch = false;
+      }
+    }
+  }
+
+  if (compatible_local_arch || missing_local_arch) {
+    // If we haven't got a valid arch spec, or the architectures are compatible
+    // update the architecture, unless the one we already have is more specified
+    if (replace_local_arch)
+      m_arch = other;
+    if (log)
+      log->Printf("Target::SetArchitecture set architecture to %s (%s)",
+                  m_arch.GetArchitectureName(),
+                  m_arch.GetTriple().getTriple().c_str());
+    return true;
+  }
+
+  // If we have an executable file, try to reset the executable to the desired
+  // architecture
+  if (log)
+    log->Printf("Target::SetArchitecture changing architecture to %s (%s)",
+                arch_spec.GetArchitectureName(),
+                arch_spec.GetTriple().getTriple().c_str());
+  m_arch = other;
+  ModuleSP executable_sp = GetExecutableModule();
+
+  ClearModules(true);
+  // Need to do something about unsetting breakpoints.
+
+  if (executable_sp) {
+    if (log)
+      log->Printf("Target::SetArchitecture Trying to select executable file "
+                  "architecture %s (%s)",
+                  arch_spec.GetArchitectureName(),
+                  arch_spec.GetTriple().getTriple().c_str());
+    ModuleSpec module_spec(executable_sp->GetFileSpec(), other);
+    Error error = ModuleList::GetSharedModule(module_spec, executable_sp,
+                                              &GetExecutableSearchPaths(),
+                                              nullptr, nullptr);
+
+    if (!error.Fail() && executable_sp) {
+      SetExecutableModule(executable_sp, true);
+      return true;
+    }
+  }
+  return false;
 }
 
-size_t
-Target::ReadMemory (const Address& addr,
-                    bool prefer_file_cache,
-                    void *dst,
-                    size_t dst_len,
-                    Error &error,
-                    lldb::addr_t *load_addr_ptr)
-{
-    error.Clear();
-    
-    // if we end up reading this from process memory, we will fill this
-    // with the actual load address
-    if (load_addr_ptr)
-        *load_addr_ptr = LLDB_INVALID_ADDRESS;
-    
-    size_t bytes_read = 0;
+bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
+  if (arch_spec.IsValid()) {
+    if (m_arch.IsCompatibleMatch(arch_spec)) {
+      // The current target arch is compatible with "arch_spec", see if we
+      // can improve our current architecture using bits from "arch_spec"
 
-    addr_t load_addr = LLDB_INVALID_ADDRESS;
-    addr_t file_addr = LLDB_INVALID_ADDRESS;
-    Address resolved_addr;
-    if (!addr.IsSectionOffset())
-    {
-        SectionLoadList &section_load_list = GetSectionLoadList();
-        if (section_load_list.IsEmpty())
-        {
-            // No sections are loaded, so we must assume we are not running
-            // yet and anything we are given is a file address.
-            file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its offset is the file address
-            m_images.ResolveFileAddress (file_addr, resolved_addr);            
-        }
-        else
-        {
-            // We have at least one section loaded. This can be because
-            // we have manually loaded some sections with "target modules load ..."
-            // or because we have have a live process that has sections loaded
-            // through the dynamic loader
-            load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its offset is the load address
-            section_load_list.ResolveLoadAddress (load_addr, resolved_addr);
-        }
+      // Merge bits from arch_spec into "merged_arch" and set our architecture
+      ArchSpec merged_arch(m_arch);
+      merged_arch.MergeFrom(arch_spec);
+      return SetArchitecture(merged_arch);
+    } else {
+      // The new architecture is different, we just need to replace it
+      return SetArchitecture(arch_spec);
     }
-    if (!resolved_addr.IsValid())
-        resolved_addr = addr;
+  }
+  return false;
+}
 
-    if (prefer_file_cache)
-    {
-        bytes_read = ReadMemoryFromFileCache (resolved_addr, dst, dst_len, error);
+void Target::WillClearList(const ModuleList &module_list) {}
+
+void Target::ModuleAdded(const ModuleList &module_list,
+                         const ModuleSP &module_sp) {
+  // A module is being added to this target for the first time
+  if (m_valid) {
+    ModuleList my_module_list;
+    my_module_list.Append(module_sp);
+    LoadScriptingResourceForModule(module_sp, this);
+    ModulesDidLoad(my_module_list);
+  }
+}
+
+void Target::ModuleRemoved(const ModuleList &module_list,
+                           const ModuleSP &module_sp) {
+  // A module is being removed from this target.
+  if (m_valid) {
+    ModuleList my_module_list;
+    my_module_list.Append(module_sp);
+    ModulesDidUnload(my_module_list, false);
+  }
+}
+
+void Target::ModuleUpdated(const ModuleList &module_list,
+                           const ModuleSP &old_module_sp,
+                           const ModuleSP &new_module_sp) {
+  // A module is replacing an already added module
+  if (m_valid) {
+    m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,
+                                                            new_module_sp);
+    m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(
+        old_module_sp, new_module_sp);
+  }
+}
+
+void Target::ModulesDidLoad(ModuleList &module_list) {
+  if (m_valid && module_list.GetSize()) {
+    m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    if (m_process_sp) {
+      m_process_sp->ModulesDidLoad(module_list);
+    }
+    BroadcastEvent(eBroadcastBitModulesLoaded,
+                   new TargetEventData(this->shared_from_this(), module_list));
+  }
+}
+
+void Target::SymbolsDidLoad(ModuleList &module_list) {
+  if (m_valid && module_list.GetSize()) {
+    if (m_process_sp) {
+      LanguageRuntime *runtime =
+          m_process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+      if (runtime) {
+        ObjCLanguageRuntime *objc_runtime = (ObjCLanguageRuntime *)runtime;
+        objc_runtime->SymbolsDidLoad(module_list);
+      }
+    }
+
+    m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    BroadcastEvent(eBroadcastBitSymbolsLoaded,
+                   new TargetEventData(this->shared_from_this(), module_list));
+  }
+}
+
+void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {
+  if (m_valid && module_list.GetSize()) {
+    UnloadModuleSections(module_list);
+    m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);
+    m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,
+                                                 delete_locations);
+    BroadcastEvent(eBroadcastBitModulesUnloaded,
+                   new TargetEventData(this->shared_from_this(), module_list));
+  }
+}
+
+bool Target::ModuleIsExcludedForUnconstrainedSearches(
+    const FileSpec &module_file_spec) {
+  if (GetBreakpointsConsultPlatformAvoidList()) {
+    ModuleList matchingModules;
+    ModuleSpec module_spec(module_file_spec);
+    size_t num_modules = GetImages().FindModules(module_spec, matchingModules);
+
+    // If there is more than one module for this file spec, only return true if
+    // ALL the modules are on the
+    // black list.
+    if (num_modules > 0) {
+      for (size_t i = 0; i < num_modules; i++) {
+        if (!ModuleIsExcludedForUnconstrainedSearches(
+                matchingModules.GetModuleAtIndex(i)))
+          return false;
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+bool Target::ModuleIsExcludedForUnconstrainedSearches(
+    const lldb::ModuleSP &module_sp) {
+  if (GetBreakpointsConsultPlatformAvoidList()) {
+    if (m_platform_sp)
+      return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(*this,
+                                                                     module_sp);
+  }
+  return false;
+}
+
+size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,
+                                       size_t dst_len, Error &error) {
+  SectionSP section_sp(addr.GetSection());
+  if (section_sp) {
+    // If the contents of this section are encrypted, the on-disk file is
+    // unusable.  Read only from live memory.
+    if (section_sp->IsEncrypted()) {
+      error.SetErrorString("section is encrypted");
+      return 0;
+    }
+    ModuleSP module_sp(section_sp->GetModule());
+    if (module_sp) {
+      ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();
+      if (objfile) {
+        size_t bytes_read = objfile->ReadSectionData(
+            section_sp.get(), addr.GetOffset(), dst, dst_len);
         if (bytes_read > 0)
-            return bytes_read;
-    }
-    
-    if (ProcessIsValid())
-    {
-        if (load_addr == LLDB_INVALID_ADDRESS)
-            load_addr = resolved_addr.GetLoadAddress (this);
-
-        if (load_addr == LLDB_INVALID_ADDRESS)
-        {
-            ModuleSP addr_module_sp (resolved_addr.GetModule());
-            if (addr_module_sp && addr_module_sp->GetFileSpec())
-                error.SetErrorStringWithFormat("%s[0x%" PRIx64 "] can't be resolved, %s in not currently loaded",
-                                               addr_module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
-                                               resolved_addr.GetFileAddress(),
-                                               addr_module_sp->GetFileSpec().GetFilename().AsCString("<Unknonw>"));
-            else
-                error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved", resolved_addr.GetFileAddress());
-        }
+          return bytes_read;
         else
-        {
-            bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
-            if (bytes_read != dst_len)
-            {
-                if (error.Success())
-                {
-                    if (bytes_read == 0)
-                        error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", load_addr);
-                    else
-                        error.SetErrorStringWithFormat("only %" PRIu64 " of %" PRIu64 " bytes were read from memory at 0x%" PRIx64, (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
-                }
-            }
-            if (bytes_read)
-            {
-                if (load_addr_ptr)
-                    *load_addr_ptr = load_addr;
-                return bytes_read;
-            }
-            // If the address is not section offset we have an address that
-            // doesn't resolve to any address in any currently loaded shared
-            // libraries and we failed to read memory so there isn't anything
-            // more we can do. If it is section offset, we might be able to
-            // read cached memory from the object file.
-            if (!resolved_addr.IsSectionOffset())
-                return 0;
-        }
-    }
-    
-    if (!prefer_file_cache && resolved_addr.IsSectionOffset())
-    {
-        // If we didn't already try and read from the object file cache, then
-        // try it after failing to read from the process.
-        return ReadMemoryFromFileCache (resolved_addr, dst, dst_len, error);
-    }
-    return 0;
+          error.SetErrorStringWithFormat("error reading data from section %s",
+                                         section_sp->GetName().GetCString());
+      } else
+        error.SetErrorString("address isn't from a object file");
+    } else
+      error.SetErrorString("address isn't in a module");
+  } else
+    error.SetErrorString("address doesn't contain a section that points to a "
+                         "section in a object file");
+
+  return 0;
 }
 
-size_t
-Target::ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error)
-{
-    char buf[256];
-    out_str.clear();
+size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
+                          void *dst, size_t dst_len, Error &error,
+                          lldb::addr_t *load_addr_ptr) {
+  error.Clear();
+
+  // if we end up reading this from process memory, we will fill this
+  // with the actual load address
+  if (load_addr_ptr)
+    *load_addr_ptr = LLDB_INVALID_ADDRESS;
+
+  size_t bytes_read = 0;
+
+  addr_t load_addr = LLDB_INVALID_ADDRESS;
+  addr_t file_addr = LLDB_INVALID_ADDRESS;
+  Address resolved_addr;
+  if (!addr.IsSectionOffset()) {
+    SectionLoadList &section_load_list = GetSectionLoadList();
+    if (section_load_list.IsEmpty()) {
+      // No sections are loaded, so we must assume we are not running
+      // yet and anything we are given is a file address.
+      file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
+                                    // offset is the file address
+      m_images.ResolveFileAddress(file_addr, resolved_addr);
+    } else {
+      // We have at least one section loaded. This can be because
+      // we have manually loaded some sections with "target modules load ..."
+      // or because we have have a live process that has sections loaded
+      // through the dynamic loader
+      load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
+                                    // offset is the load address
+      section_load_list.ResolveLoadAddress(load_addr, resolved_addr);
+    }
+  }
+  if (!resolved_addr.IsValid())
+    resolved_addr = addr;
+
+  if (prefer_file_cache) {
+    bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
+    if (bytes_read > 0)
+      return bytes_read;
+  }
+
+  if (ProcessIsValid()) {
+    if (load_addr == LLDB_INVALID_ADDRESS)
+      load_addr = resolved_addr.GetLoadAddress(this);
+
+    if (load_addr == LLDB_INVALID_ADDRESS) {
+      ModuleSP addr_module_sp(resolved_addr.GetModule());
+      if (addr_module_sp && addr_module_sp->GetFileSpec())
+        error.SetErrorStringWithFormat(
+            "%s[0x%" PRIx64 "] can't be resolved, %s in not currently loaded",
+            addr_module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
+            resolved_addr.GetFileAddress(),
+            addr_module_sp->GetFileSpec().GetFilename().AsCString("<Unknonw>"));
+      else
+        error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved",
+                                       resolved_addr.GetFileAddress());
+    } else {
+      bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
+      if (bytes_read != dst_len) {
+        if (error.Success()) {
+          if (bytes_read == 0)
+            error.SetErrorStringWithFormat(
+                "read memory from 0x%" PRIx64 " failed", load_addr);
+          else
+            error.SetErrorStringWithFormat(
+                "only %" PRIu64 " of %" PRIu64
+                " bytes were read from memory at 0x%" PRIx64,
+                (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
+        }
+      }
+      if (bytes_read) {
+        if (load_addr_ptr)
+          *load_addr_ptr = load_addr;
+        return bytes_read;
+      }
+      // If the address is not section offset we have an address that
+      // doesn't resolve to any address in any currently loaded shared
+      // libraries and we failed to read memory so there isn't anything
+      // more we can do. If it is section offset, we might be able to
+      // read cached memory from the object file.
+      if (!resolved_addr.IsSectionOffset())
+        return 0;
+    }
+  }
+
+  if (!prefer_file_cache && resolved_addr.IsSectionOffset()) {
+    // If we didn't already try and read from the object file cache, then
+    // try it after failing to read from the process.
+    return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
+  }
+  return 0;
+}
+
+size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
+                                     Error &error) {
+  char buf[256];
+  out_str.clear();
+  addr_t curr_addr = addr.GetLoadAddress(this);
+  Address address(addr);
+  while (1) {
+    size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
+    if (length == 0)
+      break;
+    out_str.append(buf, length);
+    // If we got "length - 1" bytes, we didn't get the whole C string, we
+    // need to read some more characters
+    if (length == sizeof(buf) - 1)
+      curr_addr += length;
+    else
+      break;
+    address = Address(curr_addr);
+  }
+  return out_str.size();
+}
+
+size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
+                                     size_t dst_max_len, Error &result_error) {
+  size_t total_cstr_len = 0;
+  if (dst && dst_max_len) {
+    result_error.Clear();
+    // NULL out everything just to be safe
+    memset(dst, 0, dst_max_len);
+    Error error;
     addr_t curr_addr = addr.GetLoadAddress(this);
     Address address(addr);
-    while (1)
-    {
-        size_t length = ReadCStringFromMemory (address, buf, sizeof(buf), error);
-        if (length == 0)
-            break;
-        out_str.append(buf, length);
-        // If we got "length - 1" bytes, we didn't get the whole C string, we
-        // need to read some more characters
-        if (length == sizeof(buf) - 1)
-            curr_addr += length;
-        else
-            break;
-        address = Address(curr_addr);
+
+    // We could call m_process_sp->GetMemoryCacheLineSize() but I don't
+    // think this really needs to be tied to the memory cache subsystem's
+    // cache line size, so leave this as a fixed constant.
+    const size_t cache_line_size = 512;
+
+    size_t bytes_left = dst_max_len - 1;
+    char *curr_dst = dst;
+
+    while (bytes_left > 0) {
+      addr_t cache_line_bytes_left =
+          cache_line_size - (curr_addr % cache_line_size);
+      addr_t bytes_to_read =
+          std::min<addr_t>(bytes_left, cache_line_bytes_left);
+      size_t bytes_read =
+          ReadMemory(address, false, curr_dst, bytes_to_read, error);
+
+      if (bytes_read == 0) {
+        result_error = error;
+        dst[total_cstr_len] = '\0';
+        break;
+      }
+      const size_t len = strlen(curr_dst);
+
+      total_cstr_len += len;
+
+      if (len < bytes_to_read)
+        break;
+
+      curr_dst += bytes_read;
+      curr_addr += bytes_read;
+      bytes_left -= bytes_read;
+      address = Address(curr_addr);
     }
-    return out_str.size();
-}
-
-size_t
-Target::ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error)
-{
-    size_t total_cstr_len = 0;
-    if (dst && dst_max_len)
-    {
-        result_error.Clear();
-        // NULL out everything just to be safe
-        memset (dst, 0, dst_max_len);
-        Error error;
-        addr_t curr_addr = addr.GetLoadAddress(this);
-        Address address(addr);
-
-        // We could call m_process_sp->GetMemoryCacheLineSize() but I don't
-        // think this really needs to be tied to the memory cache subsystem's
-        // cache line size, so leave this as a fixed constant.
-        const size_t cache_line_size = 512;
-
-        size_t bytes_left = dst_max_len - 1;
-        char *curr_dst = dst;
-        
-        while (bytes_left > 0)
-        {
-            addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
-            addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
-            size_t bytes_read = ReadMemory (address, false, curr_dst, bytes_to_read, error);
-            
-            if (bytes_read == 0)
-            {
-                result_error = error;
-                dst[total_cstr_len] = '\0';
-                break;
-            }
-            const size_t len = strlen(curr_dst);
-            
-            total_cstr_len += len;
-            
-            if (len < bytes_to_read)
-                break;
-            
-            curr_dst += bytes_read;
-            curr_addr += bytes_read;
-            bytes_left -= bytes_read;
-            address = Address(curr_addr);
-        }
-    }
+  } else {
+    if (dst == nullptr)
+      result_error.SetErrorString("invalid arguments");
     else
-    {
-        if (dst == nullptr)
-            result_error.SetErrorString("invalid arguments");
-        else
-            result_error.Clear();
-    }
-    return total_cstr_len;
+      result_error.Clear();
+  }
+  return total_cstr_len;
 }
 
-size_t
-Target::ReadScalarIntegerFromMemory (const Address& addr, 
-                                     bool prefer_file_cache,
-                                     uint32_t byte_size, 
-                                     bool is_signed, 
-                                     Scalar &scalar, 
-                                     Error &error)
-{
-    uint64_t uval;
-    
-    if (byte_size <= sizeof(uval))
-    {
-        size_t bytes_read = ReadMemory (addr, prefer_file_cache, &uval, byte_size, error);
-        if (bytes_read == byte_size)
-        {
-            DataExtractor data (&uval, sizeof(uval), m_arch.GetByteOrder(), m_arch.GetAddressByteSize());
-            lldb::offset_t offset = 0;
-            if (byte_size <= 4)
-                scalar = data.GetMaxU32 (&offset, byte_size);
-            else
-                scalar = data.GetMaxU64 (&offset, byte_size);
-            
-            if (is_signed)
-                scalar.SignExtend(byte_size * 8);
-            return bytes_read;
+size_t Target::ReadScalarIntegerFromMemory(const Address &addr,
+                                           bool prefer_file_cache,
+                                           uint32_t byte_size, bool is_signed,
+                                           Scalar &scalar, Error &error) {
+  uint64_t uval;
+
+  if (byte_size <= sizeof(uval)) {
+    size_t bytes_read =
+        ReadMemory(addr, prefer_file_cache, &uval, byte_size, error);
+    if (bytes_read == byte_size) {
+      DataExtractor data(&uval, sizeof(uval), m_arch.GetByteOrder(),
+                         m_arch.GetAddressByteSize());
+      lldb::offset_t offset = 0;
+      if (byte_size <= 4)
+        scalar = data.GetMaxU32(&offset, byte_size);
+      else
+        scalar = data.GetMaxU64(&offset, byte_size);
+
+      if (is_signed)
+        scalar.SignExtend(byte_size * 8);
+      return bytes_read;
+    }
+  } else {
+    error.SetErrorStringWithFormat(
+        "byte size of %u is too large for integer scalar type", byte_size);
+  }
+  return 0;
+}
+
+uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,
+                                               bool prefer_file_cache,
+                                               size_t integer_byte_size,
+                                               uint64_t fail_value,
+                                               Error &error) {
+  Scalar scalar;
+  if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size,
+                                  false, scalar, error))
+    return scalar.ULongLong(fail_value);
+  return fail_value;
+}
+
+bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
+                                   Error &error, Address &pointer_addr) {
+  Scalar scalar;
+  if (ReadScalarIntegerFromMemory(addr, prefer_file_cache,
+                                  m_arch.GetAddressByteSize(), false, scalar,
+                                  error)) {
+    addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
+    if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
+      SectionLoadList &section_load_list = GetSectionLoadList();
+      if (section_load_list.IsEmpty()) {
+        // No sections are loaded, so we must assume we are not running
+        // yet and anything we are given is a file address.
+        m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr);
+      } else {
+        // We have at least one section loaded. This can be because
+        // we have manually loaded some sections with "target modules load ..."
+        // or because we have have a live process that has sections loaded
+        // through the dynamic loader
+        section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr);
+      }
+      // We weren't able to resolve the pointer value, so just return
+      // an address with no section
+      if (!pointer_addr.IsValid())
+        pointer_addr.SetOffset(pointer_vm_addr);
+      return true;
+    }
+  }
+  return false;
+}
+
+ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
+                                 Error *error_ptr) {
+  ModuleSP module_sp;
+
+  Error error;
+
+  // First see if we already have this module in our module list.  If we do,
+  // then we're done, we don't need
+  // to consult the shared modules list.  But only do this if we are passed a
+  // UUID.
+
+  if (module_spec.GetUUID().IsValid())
+    module_sp = m_images.FindFirstModule(module_spec);
+
+  if (!module_sp) {
+    ModuleSP old_module_sp; // This will get filled in if we have a new version
+                            // of the library
+    bool did_create_module = false;
+
+    // If there are image search path entries, try to use them first to acquire
+    // a suitable image.
+    if (m_image_search_paths.GetSize()) {
+      ModuleSpec transformed_spec(module_spec);
+      if (m_image_search_paths.RemapPath(
+              module_spec.GetFileSpec().GetDirectory(),
+              transformed_spec.GetFileSpec().GetDirectory())) {
+        transformed_spec.GetFileSpec().GetFilename() =
+            module_spec.GetFileSpec().GetFilename();
+        error = ModuleList::GetSharedModule(transformed_spec, module_sp,
+                                            &GetExecutableSearchPaths(),
+                                            &old_module_sp, &did_create_module);
+      }
+    }
+
+    if (!module_sp) {
+      // If we have a UUID, we can check our global shared module list in case
+      // we already have it. If we don't have a valid UUID, then we can't since
+      // the path in "module_spec" will be a platform path, and we will need to
+      // let the platform find that file. For example, we could be asking for
+      // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick
+      // the local copy of "/usr/lib/dyld" since our platform could be a remote
+      // platform that has its own "/usr/lib/dyld" in an SDK or in a local file
+      // cache.
+      if (module_spec.GetUUID().IsValid()) {
+        // We have a UUID, it is OK to check the global module list...
+        error = ModuleList::GetSharedModule(module_spec, module_sp,
+                                            &GetExecutableSearchPaths(),
+                                            &old_module_sp, &did_create_module);
+      }
+
+      if (!module_sp) {
+        // The platform is responsible for finding and caching an appropriate
+        // module in the shared module cache.
+        if (m_platform_sp) {
+          error = m_platform_sp->GetSharedModule(
+              module_spec, m_process_sp.get(), module_sp,
+              &GetExecutableSearchPaths(), &old_module_sp, &did_create_module);
+        } else {
+          error.SetErrorString("no platform is currently set");
         }
+      }
     }
-    else
-    {
-        error.SetErrorStringWithFormat ("byte size of %u is too large for integer scalar type", byte_size);
-    }
-    return 0;
-}
 
-uint64_t
-Target::ReadUnsignedIntegerFromMemory (const Address& addr, 
-                                       bool prefer_file_cache,
-                                       size_t integer_byte_size, 
-                                       uint64_t fail_value, 
-                                       Error &error)
-{
-    Scalar scalar;
-    if (ReadScalarIntegerFromMemory (addr, 
-                                     prefer_file_cache, 
-                                     integer_byte_size, 
-                                     false, 
-                                     scalar, 
-                                     error))
-        return scalar.ULongLong(fail_value);
-    return fail_value;
-}
-
-bool
-Target::ReadPointerFromMemory (const Address& addr, 
-                               bool prefer_file_cache,
-                               Error &error,
-                               Address &pointer_addr)
-{
-    Scalar scalar;
-    if (ReadScalarIntegerFromMemory (addr, 
-                                     prefer_file_cache, 
-                                     m_arch.GetAddressByteSize(), 
-                                     false, 
-                                     scalar, 
-                                     error))
-    {
-        addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
-        if (pointer_vm_addr != LLDB_INVALID_ADDRESS)
-        {
-            SectionLoadList &section_load_list = GetSectionLoadList();
-            if (section_load_list.IsEmpty())
-            {
-                // No sections are loaded, so we must assume we are not running
-                // yet and anything we are given is a file address.
-                m_images.ResolveFileAddress (pointer_vm_addr, pointer_addr);
-            }
-            else
-            {
-                // We have at least one section loaded. This can be because
-                // we have manually loaded some sections with "target modules load ..."
-                // or because we have have a live process that has sections loaded
-                // through the dynamic loader
-                section_load_list.ResolveLoadAddress (pointer_vm_addr, pointer_addr);
-            }
-            // We weren't able to resolve the pointer value, so just return
-            // an address with no section
-            if (!pointer_addr.IsValid())
-                pointer_addr.SetOffset (pointer_vm_addr);
-            return true;
-            
+    // We found a module that wasn't in our target list.  Let's make sure that
+    // there wasn't an equivalent
+    // module in the list already, and if there was, let's remove it.
+    if (module_sp) {
+      ObjectFile *objfile = module_sp->GetObjectFile();
+      if (objfile) {
+        switch (objfile->GetType()) {
+        case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of
+                                        /// a program's execution state
+        case ObjectFile::eTypeExecutable:    /// A normal executable
+        case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker
+                                             /// executable
+        case ObjectFile::eTypeObjectFile:    /// An intermediate object file
+        case ObjectFile::eTypeSharedLibrary: /// A shared library that can be
+                                             /// used during execution
+          break;
+        case ObjectFile::eTypeDebugInfo: /// An object file that contains only
+                                         /// debug information
+          if (error_ptr)
+            error_ptr->SetErrorString("debug info files aren't valid target "
+                                      "modules, please specify an executable");
+          return ModuleSP();
+        case ObjectFile::eTypeStubLibrary: /// A library that can be linked
+                                           /// against but not used for
+                                           /// execution
+          if (error_ptr)
+            error_ptr->SetErrorString("stub libraries aren't valid target "
+                                      "modules, please specify an executable");
+          return ModuleSP();
+        default:
+          if (error_ptr)
+            error_ptr->SetErrorString(
+                "unsupported file type, please specify an executable");
+          return ModuleSP();
         }
-    }
-    return false;
-}
+        // GetSharedModule is not guaranteed to find the old shared module, for
+        // instance
+        // in the common case where you pass in the UUID, it is only going to
+        // find the one
+        // module matching the UUID.  In fact, it has no good way to know what
+        // the "old module"
+        // relevant to this target is, since there might be many copies of a
+        // module with this file spec
+        // in various running debug sessions, but only one of them will belong
+        // to this target.
+        // So let's remove the UUID from the module list, and look in the
+        // target's module list.
+        // Only do this if there is SOMETHING else in the module spec...
+        if (!old_module_sp) {
+          if (module_spec.GetUUID().IsValid() &&
+              !module_spec.GetFileSpec().GetFilename().IsEmpty() &&
+              !module_spec.GetFileSpec().GetDirectory().IsEmpty()) {
+            ModuleSpec module_spec_copy(module_spec.GetFileSpec());
+            module_spec_copy.GetUUID().Clear();
 
-ModuleSP
-Target::GetSharedModule (const ModuleSpec &module_spec, Error *error_ptr)
-{
-    ModuleSP module_sp;
-
-    Error error;
-
-    // First see if we already have this module in our module list.  If we do, then we're done, we don't need
-    // to consult the shared modules list.  But only do this if we are passed a UUID.
-    
-    if (module_spec.GetUUID().IsValid())
-        module_sp = m_images.FindFirstModule(module_spec);
-        
-    if (!module_sp)
-    {
-        ModuleSP old_module_sp; // This will get filled in if we have a new version of the library
-        bool did_create_module = false;
-    
-        // If there are image search path entries, try to use them first to acquire a suitable image.
-        if (m_image_search_paths.GetSize())
-        {
-            ModuleSpec transformed_spec (module_spec);
-            if (m_image_search_paths.RemapPath (module_spec.GetFileSpec().GetDirectory(), transformed_spec.GetFileSpec().GetDirectory()))
-            {
-                transformed_spec.GetFileSpec().GetFilename() = module_spec.GetFileSpec().GetFilename();
-                error = ModuleList::GetSharedModule (transformed_spec, 
-                                                     module_sp, 
-                                                     &GetExecutableSearchPaths(),
-                                                     &old_module_sp, 
-                                                     &did_create_module);
+            ModuleList found_modules;
+            size_t num_found =
+                m_images.FindModules(module_spec_copy, found_modules);
+            if (num_found == 1) {
+              old_module_sp = found_modules.GetModuleAtIndex(0);
             }
-        }
-        
-        if (!module_sp)
-        {
-            // If we have a UUID, we can check our global shared module list in case
-            // we already have it. If we don't have a valid UUID, then we can't since
-            // the path in "module_spec" will be a platform path, and we will need to
-            // let the platform find that file. For example, we could be asking for
-            // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick
-            // the local copy of "/usr/lib/dyld" since our platform could be a remote
-            // platform that has its own "/usr/lib/dyld" in an SDK or in a local file
-            // cache.
-            if (module_spec.GetUUID().IsValid())
-            {
-                // We have a UUID, it is OK to check the global module list...
-                error = ModuleList::GetSharedModule (module_spec,
-                                                     module_sp, 
-                                                     &GetExecutableSearchPaths(),
-                                                     &old_module_sp,
-                                                     &did_create_module);
-            }
-
-            if (!module_sp)
-            {
-                // The platform is responsible for finding and caching an appropriate
-                // module in the shared module cache.
-                if (m_platform_sp)
-                {
-                    error = m_platform_sp->GetSharedModule (module_spec,
-                                                            m_process_sp.get(),
-                                                            module_sp,
-                                                            &GetExecutableSearchPaths(),
-                                                            &old_module_sp,
-                                                            &did_create_module);
-                }
-                else
-                {
-                    error.SetErrorString("no platform is currently set");
-                }
-            }
+          }
         }
 
-        // We found a module that wasn't in our target list.  Let's make sure that there wasn't an equivalent
-        // module in the list already, and if there was, let's remove it.
-        if (module_sp)
-        {
-            ObjectFile *objfile = module_sp->GetObjectFile();
-            if (objfile)
-            {
-                switch (objfile->GetType())
-                {
-                    case ObjectFile::eTypeCoreFile:      /// A core file that has a checkpoint of a program's execution state
-                    case ObjectFile::eTypeExecutable:    /// A normal executable
-                    case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker executable
-                    case ObjectFile::eTypeObjectFile:    /// An intermediate object file
-                    case ObjectFile::eTypeSharedLibrary: /// A shared library that can be used during execution
-                        break;
-                    case ObjectFile::eTypeDebugInfo:     /// An object file that contains only debug information
-                        if (error_ptr)
-                            error_ptr->SetErrorString("debug info files aren't valid target modules, please specify an executable");
-                        return ModuleSP();
-                    case ObjectFile::eTypeStubLibrary:   /// A library that can be linked against but not used for execution
-                        if (error_ptr)
-                            error_ptr->SetErrorString("stub libraries aren't valid target modules, please specify an executable");
-                        return ModuleSP();
-                    default:
-                        if (error_ptr)
-                            error_ptr->SetErrorString("unsupported file type, please specify an executable");
-                        return ModuleSP();
-                }
-                // GetSharedModule is not guaranteed to find the old shared module, for instance
-                // in the common case where you pass in the UUID, it is only going to find the one
-                // module matching the UUID.  In fact, it has no good way to know what the "old module"
-                // relevant to this target is, since there might be many copies of a module with this file spec
-                // in various running debug sessions, but only one of them will belong to this target.
-                // So let's remove the UUID from the module list, and look in the target's module list.
-                // Only do this if there is SOMETHING else in the module spec...
-                if (!old_module_sp)
-                {
-                    if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
-                    {
-                        ModuleSpec module_spec_copy(module_spec.GetFileSpec());
-                        module_spec_copy.GetUUID().Clear();
-                        
-                        ModuleList found_modules;
-                        size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
-                        if (num_found == 1)
-                        {
-                            old_module_sp = found_modules.GetModuleAtIndex(0);
-                        }
-                    }
-                }
-                
-                if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
-                {
-                    m_images.ReplaceModule(old_module_sp, module_sp);
-                    Module *old_module_ptr = old_module_sp.get();
-                    old_module_sp.reset();
-                    ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
-                }
-                else
-                    m_images.Append(module_sp);
-            }
-            else
-                module_sp.reset();
-        }
+        if (old_module_sp &&
+            m_images.GetIndexForModule(old_module_sp.get()) !=
+                LLDB_INVALID_INDEX32) {
+          m_images.ReplaceModule(old_module_sp, module_sp);
+          Module *old_module_ptr = old_module_sp.get();
+          old_module_sp.reset();
+          ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr);
+        } else
+          m_images.Append(module_sp);
+      } else
+        module_sp.reset();
     }
-    if (error_ptr)
-        *error_ptr = error;
-    return module_sp;
+  }
+  if (error_ptr)
+    *error_ptr = error;
+  return module_sp;
 }
 
-TargetSP
-Target::CalculateTarget ()
-{
-    return shared_from_this();
+TargetSP Target::CalculateTarget() { return shared_from_this(); }
+
+ProcessSP Target::CalculateProcess() { return m_process_sp; }
+
+ThreadSP Target::CalculateThread() { return ThreadSP(); }
+
+StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); }
+
+void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) {
+  exe_ctx.Clear();
+  exe_ctx.SetTargetPtr(this);
 }
 
-ProcessSP
-Target::CalculateProcess ()
-{
-    return m_process_sp;
+PathMappingList &Target::GetImageSearchPathList() {
+  return m_image_search_paths;
 }
 
-ThreadSP
-Target::CalculateThread ()
-{
-    return ThreadSP();
+void Target::ImageSearchPathsChanged(const PathMappingList &path_list,
+                                     void *baton) {
+  Target *target = (Target *)baton;
+  ModuleSP exe_module_sp(target->GetExecutableModule());
+  if (exe_module_sp)
+    target->SetExecutableModule(exe_module_sp, true);
 }
 
-StackFrameSP
-Target::CalculateStackFrame ()
-{
-    return StackFrameSP();
-}
+TypeSystem *Target::GetScratchTypeSystemForLanguage(Error *error,
+                                                    lldb::LanguageType language,
+                                                    bool create_on_demand) {
+  if (!m_valid)
+    return nullptr;
 
-void
-Target::CalculateExecutionContext (ExecutionContext &exe_ctx)
-{
-    exe_ctx.Clear();
-    exe_ctx.SetTargetPtr(this);
-}
+  if (error) {
+    error->Clear();
+  }
 
-PathMappingList &
-Target::GetImageSearchPathList ()
-{
-    return m_image_search_paths;
-}
+  if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all
+                                             // assembly code
+      || language == eLanguageTypeUnknown) {
+    std::set<lldb::LanguageType> languages_for_types;
+    std::set<lldb::LanguageType> languages_for_expressions;
 
-void
-Target::ImageSearchPathsChanged(const PathMappingList &path_list,
-                                void *baton)
-{
-    Target *target = (Target *)baton;
-    ModuleSP exe_module_sp (target->GetExecutableModule());
-    if (exe_module_sp)
-        target->SetExecutableModule (exe_module_sp, true);
-}
+    Language::GetLanguagesSupportingTypeSystems(languages_for_types,
+                                                languages_for_expressions);
 
-TypeSystem *
-Target::GetScratchTypeSystemForLanguage (Error *error, lldb::LanguageType language, bool create_on_demand)
-{
-    if (!m_valid)
+    if (languages_for_expressions.count(eLanguageTypeC)) {
+      language = eLanguageTypeC; // LLDB's default.  Override by setting the
+                                 // target language.
+    } else {
+      if (languages_for_expressions.empty()) {
         return nullptr;
-
-    if (error)
-    {
-        error->Clear();
+      } else {
+        language = *languages_for_expressions.begin();
+      }
     }
-    
-    if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all assembly code
-        || language == eLanguageTypeUnknown)
-    {
-        std::set<lldb::LanguageType> languages_for_types;
-        std::set<lldb::LanguageType> languages_for_expressions;
-        
-        Language::GetLanguagesSupportingTypeSystems(languages_for_types, languages_for_expressions);
-        
-        if (languages_for_expressions.count(eLanguageTypeC))
-        {
-            language = eLanguageTypeC; // LLDB's default.  Override by setting the target language.
-        }
-        else
-        {
-            if (languages_for_expressions.empty())
-            {
-                return nullptr;
-            }
-            else
-            {
-                language = *languages_for_expressions.begin();
-            }
-        }
-    }
+  }
 
-    return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this, create_on_demand);
+  return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this,
+                                                            create_on_demand);
 }
 
 PersistentExpressionState *
-Target::GetPersistentExpressionStateForLanguage (lldb::LanguageType language)
-{
-    TypeSystem *type_system = GetScratchTypeSystemForLanguage(nullptr, language, true);
-    
-    if (type_system)
-    {
-        return type_system->GetPersistentExpressionState();
-    }
-    else
-    {
-        return nullptr;
-    }
+Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
+  TypeSystem *type_system =
+      GetScratchTypeSystemForLanguage(nullptr, language, true);
+
+  if (type_system) {
+    return type_system->GetPersistentExpressionState();
+  } else {
+    return nullptr;
+  }
 }
 
-UserExpression *
-Target::GetUserExpressionForLanguage(const char *expr,
-                                     const char *expr_prefix,
-                                     lldb::LanguageType language,
-                                     Expression::ResultType desired_type,
-                                     const EvaluateExpressionOptions &options,
-                                     Error &error)
-{
-    Error type_system_error;
-    
-    TypeSystem *type_system = GetScratchTypeSystemForLanguage (&type_system_error, language);
-    UserExpression *user_expr = nullptr;
-    
-    if (!type_system)
-    {
-        error.SetErrorStringWithFormat("Could not find type system for language %s: %s", Language::GetNameForLanguageType(language), type_system_error.AsCString());
-        return nullptr;
-    }
-    
-    user_expr = type_system->GetUserExpression(expr, expr_prefix, language, desired_type, options);
-    if (!user_expr)
-        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
-    
-    return user_expr;
+UserExpression *Target::GetUserExpressionForLanguage(
+    const char *expr, const char *expr_prefix, lldb::LanguageType language,
+    Expression::ResultType desired_type,
+    const EvaluateExpressionOptions &options, Error &error) {
+  Error type_system_error;
+
+  TypeSystem *type_system =
+      GetScratchTypeSystemForLanguage(&type_system_error, language);
+  UserExpression *user_expr = nullptr;
+
+  if (!type_system) {
+    error.SetErrorStringWithFormat(
+        "Could not find type system for language %s: %s",
+        Language::GetNameForLanguageType(language),
+        type_system_error.AsCString());
+    return nullptr;
+  }
+
+  user_expr = type_system->GetUserExpression(expr, expr_prefix, language,
+                                             desired_type, options);
+  if (!user_expr)
+    error.SetErrorStringWithFormat(
+        "Could not create an expression for language %s",
+        Language::GetNameForLanguageType(language));
+
+  return user_expr;
 }
 
-FunctionCaller *
-Target::GetFunctionCallerForLanguage (lldb::LanguageType language,
-                                      const CompilerType &return_type,
-                                      const Address& function_address,
-                                      const ValueList &arg_value_list,
-                                      const char *name,
-                                      Error &error)
-{
-    Error type_system_error;
-    TypeSystem *type_system = GetScratchTypeSystemForLanguage (&type_system_error, language);
-    FunctionCaller *persistent_fn = nullptr;
-    
-    if (!type_system)
-    {
-        error.SetErrorStringWithFormat("Could not find type system for language %s: %s", Language::GetNameForLanguageType(language), type_system_error.AsCString());
-        return persistent_fn;
-    }
-    
-    persistent_fn = type_system->GetFunctionCaller (return_type, function_address, arg_value_list, name);
-    if (!persistent_fn)
-        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
-    
+FunctionCaller *Target::GetFunctionCallerForLanguage(
+    lldb::LanguageType language, const CompilerType &return_type,
+    const Address &function_address, const ValueList &arg_value_list,
+    const char *name, Error &error) {
+  Error type_system_error;
+  TypeSystem *type_system =
+      GetScratchTypeSystemForLanguage(&type_system_error, language);
+  FunctionCaller *persistent_fn = nullptr;
+
+  if (!type_system) {
+    error.SetErrorStringWithFormat(
+        "Could not find type system for language %s: %s",
+        Language::GetNameForLanguageType(language),
+        type_system_error.AsCString());
     return persistent_fn;
+  }
+
+  persistent_fn = type_system->GetFunctionCaller(return_type, function_address,
+                                                 arg_value_list, name);
+  if (!persistent_fn)
+    error.SetErrorStringWithFormat(
+        "Could not create an expression for language %s",
+        Language::GetNameForLanguageType(language));
+
+  return persistent_fn;
 }
 
 UtilityFunction *
-Target::GetUtilityFunctionForLanguage (const char *text,
-                                       lldb::LanguageType language,
-                                       const char *name,
-                                       Error &error)
-{
-    Error type_system_error;
-    TypeSystem *type_system = GetScratchTypeSystemForLanguage (&type_system_error, language);
-    UtilityFunction *utility_fn = nullptr;
-    
-    if (!type_system)
-    {
-        error.SetErrorStringWithFormat("Could not find type system for language %s: %s", Language::GetNameForLanguageType(language), type_system_error.AsCString());
-        return utility_fn;
-    }
-    
-    utility_fn = type_system->GetUtilityFunction (text, name);
-    if (!utility_fn)
-        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
-    
+Target::GetUtilityFunctionForLanguage(const char *text,
+                                      lldb::LanguageType language,
+                                      const char *name, Error &error) {
+  Error type_system_error;
+  TypeSystem *type_system =
+      GetScratchTypeSystemForLanguage(&type_system_error, language);
+  UtilityFunction *utility_fn = nullptr;
+
+  if (!type_system) {
+    error.SetErrorStringWithFormat(
+        "Could not find type system for language %s: %s",
+        Language::GetNameForLanguageType(language),
+        type_system_error.AsCString());
     return utility_fn;
+  }
+
+  utility_fn = type_system->GetUtilityFunction(text, name);
+  if (!utility_fn)
+    error.SetErrorStringWithFormat(
+        "Could not create an expression for language %s",
+        Language::GetNameForLanguageType(language));
+
+  return utility_fn;
 }
 
-ClangASTContext *
-Target::GetScratchClangASTContext(bool create_on_demand)
-{
-    if (m_valid)
-    {
-        if (TypeSystem* type_system = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC, create_on_demand))
-            return llvm::dyn_cast<ClangASTContext>(type_system);
+ClangASTContext *Target::GetScratchClangASTContext(bool create_on_demand) {
+  if (m_valid) {
+    if (TypeSystem *type_system = GetScratchTypeSystemForLanguage(
+            nullptr, eLanguageTypeC, create_on_demand))
+      return llvm::dyn_cast<ClangASTContext>(type_system);
+  }
+  return nullptr;
+}
+
+ClangASTImporterSP Target::GetClangASTImporter() {
+  if (m_valid) {
+    if (!m_ast_importer_sp) {
+      m_ast_importer_sp.reset(new ClangASTImporter());
     }
-    return nullptr;
+    return m_ast_importer_sp;
+  }
+  return ClangASTImporterSP();
 }
 
-ClangASTImporterSP
-Target::GetClangASTImporter()
-{
-    if (m_valid)
-    {
-        if (!m_ast_importer_sp)
-        {
-            m_ast_importer_sp.reset(new ClangASTImporter());
-        }
-        return m_ast_importer_sp;
-    }
-    return ClangASTImporterSP();
+void Target::SettingsInitialize() { Process::SettingsInitialize(); }
+
+void Target::SettingsTerminate() { Process::SettingsTerminate(); }
+
+FileSpecList Target::GetDefaultExecutableSearchPaths() {
+  TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+  if (properties_sp)
+    return properties_sp->GetExecutableSearchPaths();
+  return FileSpecList();
 }
 
-void
-Target::SettingsInitialize ()
-{
-    Process::SettingsInitialize ();
+FileSpecList Target::GetDefaultDebugFileSearchPaths() {
+  TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+  if (properties_sp)
+    return properties_sp->GetDebugFileSearchPaths();
+  return FileSpecList();
 }
 
-void
-Target::SettingsTerminate ()
-{
-    Process::SettingsTerminate ();
+FileSpecList Target::GetDefaultClangModuleSearchPaths() {
+  TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+  if (properties_sp)
+    return properties_sp->GetClangModuleSearchPaths();
+  return FileSpecList();
 }
 
-FileSpecList
-Target::GetDefaultExecutableSearchPaths ()
-{
-    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
-    if (properties_sp)
-        return properties_sp->GetExecutableSearchPaths();
-    return FileSpecList();
+ArchSpec Target::GetDefaultArchitecture() {
+  TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+  if (properties_sp)
+    return properties_sp->GetDefaultArchitecture();
+  return ArchSpec();
 }
 
-FileSpecList
-Target::GetDefaultDebugFileSearchPaths ()
-{
-    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
-    if (properties_sp)
-        return properties_sp->GetDebugFileSearchPaths();
-    return FileSpecList();
+void Target::SetDefaultArchitecture(const ArchSpec &arch) {
+  TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+  if (properties_sp) {
+    LogIfAnyCategoriesSet(
+        LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's "
+                            "default architecture to  %s (%s)",
+        arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
+    return properties_sp->SetDefaultArchitecture(arch);
+  }
 }
 
-FileSpecList
-Target::GetDefaultClangModuleSearchPaths ()
-{
-    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
-    if (properties_sp)
-        return properties_sp->GetClangModuleSearchPaths();
-    return FileSpecList();
+Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,
+                                      const SymbolContext *sc_ptr) {
+  // The target can either exist in the "process" of ExecutionContext, or in
+  // the "target_sp" member of SymbolContext. This accessor helper function
+  // will get the target from one of these locations.
+
+  Target *target = nullptr;
+  if (sc_ptr != nullptr)
+    target = sc_ptr->target_sp.get();
+  if (target == nullptr && exe_ctx_ptr)
+    target = exe_ctx_ptr->GetTargetPtr();
+  return target;
 }
 
-ArchSpec
-Target::GetDefaultArchitecture ()
-{
-    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
-    if (properties_sp)
-        return properties_sp->GetDefaultArchitecture();
-    return ArchSpec();
-}
+ExpressionResults Target::EvaluateExpression(
+    const char *expr_cstr, ExecutionContextScope *exe_scope,
+    lldb::ValueObjectSP &result_valobj_sp,
+    const EvaluateExpressionOptions &options, std::string *fixed_expression) {
+  result_valobj_sp.reset();
 
-void
-Target::SetDefaultArchitecture (const ArchSpec &arch)
-{
-    TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
-    if (properties_sp)
-    {
-        LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's default architecture to  %s (%s)", arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
-        return properties_sp->SetDefaultArchitecture(arch);
-    }
-}
+  ExpressionResults execution_results = eExpressionSetupError;
 
-Target *
-Target::GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
-{
-    // The target can either exist in the "process" of ExecutionContext, or in 
-    // the "target_sp" member of SymbolContext. This accessor helper function
-    // will get the target from one of these locations.
-
-    Target *target = nullptr;
-    if (sc_ptr != nullptr)
-        target = sc_ptr->target_sp.get();
-    if (target == nullptr && exe_ctx_ptr)
-        target = exe_ctx_ptr->GetTargetPtr();
-    return target;
-}
-
-ExpressionResults
-Target::EvaluateExpression(const char *expr_cstr,
-                           ExecutionContextScope *exe_scope,
-                           lldb::ValueObjectSP &result_valobj_sp,
-                           const EvaluateExpressionOptions& options,
-                           std::string *fixed_expression)
-{
-    result_valobj_sp.reset();
-    
-    ExpressionResults execution_results = eExpressionSetupError;
-
-    if (expr_cstr == nullptr || expr_cstr[0] == '\0')
-        return execution_results;
-
-    // We shouldn't run stop hooks in expressions.
-    // Be sure to reset this if you return anywhere within this function.
-    bool old_suppress_value = m_suppress_stop_hooks;
-    m_suppress_stop_hooks = true;
-
-    ExecutionContext exe_ctx;
-    
-    if (exe_scope)
-    {
-        exe_scope->CalculateExecutionContext(exe_ctx);
-    }
-    else if (m_process_sp)
-    {
-        m_process_sp->CalculateExecutionContext(exe_ctx);
-    }
-    else
-    {
-        CalculateExecutionContext(exe_ctx);
-    }
-    
-    // Make sure we aren't just trying to see the value of a persistent
-    // variable (something like "$0")
-    lldb::ExpressionVariableSP persistent_var_sp;
-    // Only check for persistent variables the expression starts with a '$' 
-    if (expr_cstr[0] == '$')
-        persistent_var_sp = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC)->GetPersistentExpressionState()->GetVariable (expr_cstr);
-
-    if (persistent_var_sp)
-    {
-        result_valobj_sp = persistent_var_sp->GetValueObject ();
-        execution_results = eExpressionCompleted;
-    }
-    else
-    {
-        const char *prefix = GetExpressionPrefixContentsAsCString();
-        Error error;
-        execution_results = UserExpression::Evaluate (exe_ctx,
-                                                      options,
-                                                      expr_cstr,
-                                                      prefix,
-                                                      result_valobj_sp,
-                                                      error,
-                                                      0, // Line Number
-                                                      fixed_expression);
-    }
-    
-    m_suppress_stop_hooks = old_suppress_value;
-    
+  if (expr_cstr == nullptr || expr_cstr[0] == '\0')
     return execution_results;
+
+  // We shouldn't run stop hooks in expressions.
+  // Be sure to reset this if you return anywhere within this function.
+  bool old_suppress_value = m_suppress_stop_hooks;
+  m_suppress_stop_hooks = true;
+
+  ExecutionContext exe_ctx;
+
+  if (exe_scope) {
+    exe_scope->CalculateExecutionContext(exe_ctx);
+  } else if (m_process_sp) {
+    m_process_sp->CalculateExecutionContext(exe_ctx);
+  } else {
+    CalculateExecutionContext(exe_ctx);
+  }
+
+  // Make sure we aren't just trying to see the value of a persistent
+  // variable (something like "$0")
+  lldb::ExpressionVariableSP persistent_var_sp;
+  // Only check for persistent variables the expression starts with a '$'
+  if (expr_cstr[0] == '$')
+    persistent_var_sp = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC)
+                            ->GetPersistentExpressionState()
+                            ->GetVariable(expr_cstr);
+
+  if (persistent_var_sp) {
+    result_valobj_sp = persistent_var_sp->GetValueObject();
+    execution_results = eExpressionCompleted;
+  } else {
+    const char *prefix = GetExpressionPrefixContentsAsCString();
+    Error error;
+    execution_results = UserExpression::Evaluate(
+        exe_ctx, options, expr_cstr, prefix, result_valobj_sp, error,
+        0, // Line Number
+        fixed_expression);
+  }
+
+  m_suppress_stop_hooks = old_suppress_value;
+
+  return execution_results;
 }
 
 lldb::ExpressionVariableSP
-Target::GetPersistentVariable(const ConstString &name)
-{
-    lldb::ExpressionVariableSP variable_sp;
-    m_scratch_type_system_map.ForEach([this, name, &variable_sp](TypeSystem *type_system) -> bool
-    {
-        if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState())
-        {
-            variable_sp = persistent_state->GetVariable(name);
+Target::GetPersistentVariable(const ConstString &name) {
+  lldb::ExpressionVariableSP variable_sp;
+  m_scratch_type_system_map.ForEach(
+      [this, name, &variable_sp](TypeSystem *type_system) -> bool {
+        if (PersistentExpressionState *persistent_state =
+                type_system->GetPersistentExpressionState()) {
+          variable_sp = persistent_state->GetVariable(name);
 
-            if (variable_sp)
-                return false;   // Stop iterating the ForEach
+          if (variable_sp)
+            return false; // Stop iterating the ForEach
         }
-        return true;    // Keep iterating the ForEach
-    });
-    return variable_sp;
+        return true; // Keep iterating the ForEach
+      });
+  return variable_sp;
 }
 
-lldb::addr_t
-Target::GetPersistentSymbol(const ConstString &name)
-{
-    lldb::addr_t address = LLDB_INVALID_ADDRESS;
-    
-    m_scratch_type_system_map.ForEach([this, name, &address](TypeSystem *type_system) -> bool
-    {
-        if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState())
-        {
-            address = persistent_state->LookupSymbol(name);
-            if (address != LLDB_INVALID_ADDRESS)
-                return false;   // Stop iterating the ForEach
+lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) {
+  lldb::addr_t address = LLDB_INVALID_ADDRESS;
+
+  m_scratch_type_system_map.ForEach(
+      [this, name, &address](TypeSystem *type_system) -> bool {
+        if (PersistentExpressionState *persistent_state =
+                type_system->GetPersistentExpressionState()) {
+          address = persistent_state->LookupSymbol(name);
+          if (address != LLDB_INVALID_ADDRESS)
+            return false; // Stop iterating the ForEach
         }
-        return true;    // Keep iterating the ForEach
-    });
-    return address;
+        return true; // Keep iterating the ForEach
+      });
+  return address;
 }
 
-lldb::addr_t
-Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const
-{
-    addr_t code_addr = load_addr;
-    switch (m_arch.GetMachine())
-    {
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-        switch (addr_class)
-        {
-        case eAddressClassData:
-        case eAddressClassDebug:
-            return LLDB_INVALID_ADDRESS;
+lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
+                                            AddressClass addr_class) const {
+  addr_t code_addr = load_addr;
+  switch (m_arch.GetMachine()) {
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    switch (addr_class) {
+    case eAddressClassData:
+    case eAddressClassDebug:
+      return LLDB_INVALID_ADDRESS;
 
-        case eAddressClassUnknown:
-        case eAddressClassInvalid:
-        case eAddressClassCode:
-        case eAddressClassCodeAlternateISA:
-        case eAddressClassRuntime:
-            if ((code_addr & 2ull) || (addr_class == eAddressClassCodeAlternateISA))
-                code_addr |= 1ull;
-            break;
-        }
-        break;
-
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-        switch (addr_class)
-        {
-        case eAddressClassData:
-        case eAddressClassDebug:
-            return LLDB_INVALID_ADDRESS;
-            
-        case eAddressClassUnknown:
-        case eAddressClassInvalid:
-        case eAddressClassCode:
-        case eAddressClassCodeAlternateISA:
-        case eAddressClassRuntime:
-            // Check if bit zero it no set?
-            if ((code_addr & 1ull) == 0)
-            {
-                // Bit zero isn't set, check if the address is a multiple of 2?
-                if (code_addr & 2ull)
-                {
-                    // The address is a multiple of 2 so it must be thumb, set bit zero
-                    code_addr |= 1ull;
-                }
-                else if (addr_class == eAddressClassCodeAlternateISA)
-                {
-                    // We checked the address and the address claims to be the alternate ISA
-                    // which means thumb, so set bit zero.
-                    code_addr |= 1ull;
-                }
-            }
-            break;
-        }
-        break;
-            
-    default:
-        break;
+    case eAddressClassUnknown:
+    case eAddressClassInvalid:
+    case eAddressClassCode:
+    case eAddressClassCodeAlternateISA:
+    case eAddressClassRuntime:
+      if ((code_addr & 2ull) || (addr_class == eAddressClassCodeAlternateISA))
+        code_addr |= 1ull;
+      break;
     }
-    return code_addr;
-}
+    break;
 
-lldb::addr_t
-Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const
-{
-    addr_t opcode_addr = load_addr;
-    switch (m_arch.GetMachine())
-    {
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-        switch (addr_class)
-        {
-        case eAddressClassData:
-        case eAddressClassDebug:
-            return LLDB_INVALID_ADDRESS;
-            
-        case eAddressClassInvalid:
-        case eAddressClassUnknown:
-        case eAddressClassCode:
-        case eAddressClassCodeAlternateISA:
-        case eAddressClassRuntime:
-            opcode_addr &= ~(1ull);
-            break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    switch (addr_class) {
+    case eAddressClassData:
+    case eAddressClassDebug:
+      return LLDB_INVALID_ADDRESS;
+
+    case eAddressClassUnknown:
+    case eAddressClassInvalid:
+    case eAddressClassCode:
+    case eAddressClassCodeAlternateISA:
+    case eAddressClassRuntime:
+      // Check if bit zero it no set?
+      if ((code_addr & 1ull) == 0) {
+        // Bit zero isn't set, check if the address is a multiple of 2?
+        if (code_addr & 2ull) {
+          // The address is a multiple of 2 so it must be thumb, set bit zero
+          code_addr |= 1ull;
+        } else if (addr_class == eAddressClassCodeAlternateISA) {
+          // We checked the address and the address claims to be the alternate
+          // ISA
+          // which means thumb, so set bit zero.
+          code_addr |= 1ull;
         }
-        break;
-            
-    default:
-        break;
+      }
+      break;
     }
-    return opcode_addr;
+    break;
+
+  default:
+    break;
+  }
+  return code_addr;
 }
 
-lldb::addr_t
-Target::GetBreakableLoadAddress (lldb::addr_t addr)
-{
-    addr_t breakable_addr = addr;
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
+                                          AddressClass addr_class) const {
+  addr_t opcode_addr = load_addr;
+  switch (m_arch.GetMachine()) {
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    switch (addr_class) {
+    case eAddressClassData:
+    case eAddressClassDebug:
+      return LLDB_INVALID_ADDRESS;
 
-    switch (m_arch.GetMachine())
-    {
-    default:
-        break;
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-    case llvm::Triple::mips64:
-    case llvm::Triple::mips64el:
-    {
-        addr_t function_start = 0;
-        addr_t current_offset = 0;
-        uint32_t loop_count = 0;
-        Address resolved_addr;
-        uint32_t arch_flags = m_arch.GetFlags ();
-        bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16;
-        bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips;
-        SectionLoadList &section_load_list = GetSectionLoadList();
-
-        if (section_load_list.IsEmpty())
-            // No sections are loaded, so we must assume we are not running yet
-            // and need to operate only on file address.
-            m_images.ResolveFileAddress (addr, resolved_addr); 
-        else
-            section_load_list.ResolveLoadAddress(addr, resolved_addr);
-
-        // Get the function boundaries to make sure we don't scan back before the beginning of the current function.
-        ModuleSP temp_addr_module_sp (resolved_addr.GetModule());
-        if (temp_addr_module_sp)
-        {
-            SymbolContext sc;
-            uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
-            temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, resolve_scope, sc);
-            Address sym_addr;
-            if (sc.function)
-                sym_addr = sc.function->GetAddressRange().GetBaseAddress();
-            else if (sc.symbol)
-                sym_addr = sc.symbol->GetAddress();
-
-            function_start = sym_addr.GetLoadAddress(this);
-            if (function_start == LLDB_INVALID_ADDRESS)
-                function_start = sym_addr.GetFileAddress();
-
-            if (function_start)
-                current_offset = addr - function_start;
-        }
-
-        // If breakpoint address is start of function then we dont have to do anything.
-        if (current_offset == 0)
-            return breakable_addr;
-        else
-            loop_count = current_offset / 2;
-
-        if (loop_count > 3)
-        {
-            // Scan previous 6 bytes
-            if (IsMips16 | IsMicromips)
-                loop_count = 3;
-            // For mips-only, instructions are always 4 bytes, so scan previous 4 bytes only.
-            else
-                loop_count = 2;
-        }
-
-        // Create Disassembler Instance
-        lldb::DisassemblerSP disasm_sp(Disassembler::FindPlugin(m_arch, nullptr, nullptr));
-
-        ExecutionContext exe_ctx;
-        CalculateExecutionContext(exe_ctx);
-        InstructionList instruction_list;
-        InstructionSP prev_insn;
-        bool prefer_file_cache = true; // Read from file
-        uint32_t inst_to_choose = 0;
-
-        for (uint32_t i = 1; i <= loop_count; i++)
-        {
-            // Adjust the address to read from.
-            resolved_addr.Slide (-2);
-            AddressRange range(resolved_addr, i*2);
-            uint32_t insn_size = 0;
-
-            disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
-            
-            uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
-            if (num_insns)
-            {
-                prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0);
-                insn_size = prev_insn->GetOpcode().GetByteSize();
-                if (i == 1 && insn_size == 2)
-                {
-                    // This looks like a valid 2-byte instruction (but it could be a part of upper 4 byte instruction).
-                    instruction_list.Append(prev_insn);
-                    inst_to_choose = 1;
-                }
-                else if (i == 2)
-                {
-                    // Here we may get one 4-byte instruction or two 2-byte instructions.
-                    if (num_insns == 2)
-                    {
-                        // Looks like there are two 2-byte instructions above our breakpoint target address.
-                        // Now the upper 2-byte instruction is either a valid 2-byte instruction or could be a part of it's upper 4-byte instruction.
-                        // In both cases we don't care because in this case lower 2-byte instruction is definitely a valid instruction
-                        // and whatever i=1 iteration has found out is true.
-                        inst_to_choose = 1;
-                        break;
-                    }
-                    else if (insn_size == 4)
-                    {
-                        // This instruction claims its a valid 4-byte instruction. But it could be a part of it's upper 4-byte instruction.
-                        // Lets try scanning upper 2 bytes to verify this.
-                        instruction_list.Append(prev_insn);
-                        inst_to_choose = 2;
-                    }
-                }
-                else if (i == 3)
-                {
-                    if (insn_size == 4)
-                        // FIXME: We reached here that means instruction at [target - 4] has already claimed to be a 4-byte instruction,
-                        // and now instruction at [target - 6] is also claiming that it's a 4-byte instruction. This can not be true.
-                        // In this case we can not decide the valid previous instruction so we let lldb set the breakpoint at the address given by user.
-                        inst_to_choose = 0;
-                    else
-                        // This is straight-forward 
-                        inst_to_choose = 2;
-                    break;
-                }
-            }
-            else
-            {
-                // Decode failed, bytes do not form a valid instruction. So whatever previous iteration has found out is true.
-                if (i > 1)
-                {
-                    inst_to_choose = i - 1;
-                    break;
-                }
-            }
-        }
-
-        // Check if we are able to find any valid instruction.
-        if (inst_to_choose)
-        {
-            if (inst_to_choose > instruction_list.GetSize())
-                inst_to_choose--;
-            prev_insn = instruction_list.GetInstructionAtIndex(inst_to_choose - 1);
-
-            if (prev_insn->HasDelaySlot())
-            {
-                uint32_t shift_size = prev_insn->GetOpcode().GetByteSize();
-                // Adjust the breakable address
-                breakable_addr = addr - shift_size;
-                if (log)
-                    log->Printf ("Target::%s Breakpoint at 0x%8.8" PRIx64 " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", __FUNCTION__, addr, breakable_addr);
-            }
-        }
-        break;
+    case eAddressClassInvalid:
+    case eAddressClassUnknown:
+    case eAddressClassCode:
+    case eAddressClassCodeAlternateISA:
+    case eAddressClassRuntime:
+      opcode_addr &= ~(1ull);
+      break;
     }
-    }
-    return breakable_addr;
+    break;
+
+  default:
+    break;
+  }
+  return opcode_addr;
 }
 
-SourceManager &
-Target::GetSourceManager ()
-{
-    if (!m_source_manager_ap)
-        m_source_manager_ap.reset (new SourceManager(shared_from_this()));
-    return *m_source_manager_ap;
-}
+lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
+  addr_t breakable_addr = addr;
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
 
-ClangModulesDeclVendor *
-Target::GetClangModulesDeclVendor ()
-{
-    static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended we can make it per-target
+  switch (m_arch.GetMachine()) {
+  default:
+    break;
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el: {
+    addr_t function_start = 0;
+    addr_t current_offset = 0;
+    uint32_t loop_count = 0;
+    Address resolved_addr;
+    uint32_t arch_flags = m_arch.GetFlags();
+    bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16;
+    bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips;
+    SectionLoadList &section_load_list = GetSectionLoadList();
 
-    {
-        std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex);
-
-        if (!m_clang_modules_decl_vendor_ap)
-        {
-            m_clang_modules_decl_vendor_ap.reset(ClangModulesDeclVendor::Create(*this));
-        }
-    }
-    
-    return m_clang_modules_decl_vendor_ap.get();
-}
-
-Target::StopHookSP
-Target::CreateStopHook ()
-{
-    lldb::user_id_t new_uid = ++m_stop_hook_next_id;
-    Target::StopHookSP stop_hook_sp (new StopHook(shared_from_this(), new_uid));
-    m_stop_hooks[new_uid] = stop_hook_sp;
-    return stop_hook_sp;
-}
-
-bool
-Target::RemoveStopHookByID (lldb::user_id_t user_id)
-{
-    size_t num_removed = m_stop_hooks.erase(user_id);
-    return (num_removed != 0);
-}
-
-void
-Target::RemoveAllStopHooks ()
-{
-    m_stop_hooks.clear();
-}
-
-Target::StopHookSP
-Target::GetStopHookByID (lldb::user_id_t user_id)
-{
-    StopHookSP found_hook;
-    
-    StopHookCollection::iterator specified_hook_iter;
-    specified_hook_iter = m_stop_hooks.find (user_id);
-    if (specified_hook_iter != m_stop_hooks.end())
-        found_hook = (*specified_hook_iter).second;
-    return found_hook;
-}
-
-bool
-Target::SetStopHookActiveStateByID (lldb::user_id_t user_id, bool active_state)
-{
-    StopHookCollection::iterator specified_hook_iter;
-    specified_hook_iter = m_stop_hooks.find (user_id);
-    if (specified_hook_iter == m_stop_hooks.end())
-        return false;
-        
-    (*specified_hook_iter).second->SetIsActive (active_state);
-    return true;
-}
-
-void
-Target::SetAllStopHooksActiveState (bool active_state)
-{
-    StopHookCollection::iterator pos, end = m_stop_hooks.end();
-    for (pos = m_stop_hooks.begin(); pos != end; pos++)
-    {
-        (*pos).second->SetIsActive (active_state);
-    }
-}
-
-void
-Target::RunStopHooks ()
-{
-    if (m_suppress_stop_hooks)
-        return;
-        
-    if (!m_process_sp)
-        return;
-    
-    // <rdar://problem/12027563> make sure we check that we are not stopped because of us running a user expression
-    // since in that case we do not want to run the stop-hooks
-    if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression())
-        return;
-    
-    if (m_stop_hooks.empty())
-        return;
-        
-    StopHookCollection::iterator pos, end = m_stop_hooks.end();
-        
-    // If there aren't any active stop hooks, don't bother either:
-    bool any_active_hooks = false;
-    for (pos = m_stop_hooks.begin(); pos != end; pos++)
-    {
-        if ((*pos).second->IsActive())
-        {
-            any_active_hooks = true;
-            break;
-        }
-    }
-    if (!any_active_hooks)
-        return;
-    
-    CommandReturnObject result;
-    
-    std::vector<ExecutionContext> exc_ctx_with_reasons;
-    std::vector<SymbolContext> sym_ctx_with_reasons;
-    
-    ThreadList &cur_threadlist = m_process_sp->GetThreadList();
-    size_t num_threads = cur_threadlist.GetSize();
-    for (size_t i = 0; i < num_threads; i++)
-    {
-        lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex (i);
-        if (cur_thread_sp->ThreadStoppedForAReason())
-        {
-            lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);
-            exc_ctx_with_reasons.push_back(ExecutionContext(m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get()));
-            sym_ctx_with_reasons.push_back(cur_frame_sp->GetSymbolContext(eSymbolContextEverything));
-        }
-    }
-    
-    // If no threads stopped for a reason, don't run the stop-hooks.
-    size_t num_exe_ctx = exc_ctx_with_reasons.size();
-    if (num_exe_ctx == 0)
-        return;
-    
-    result.SetImmediateOutputStream (m_debugger.GetAsyncOutputStream());
-    result.SetImmediateErrorStream (m_debugger.GetAsyncErrorStream());
-    
-    bool keep_going = true;
-    bool hooks_ran = false;
-    bool print_hook_header = (m_stop_hooks.size() != 1);
-    bool print_thread_header = (num_exe_ctx != 1);
-    
-    for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++)
-    {
-        // result.Clear();
-        StopHookSP cur_hook_sp = (*pos).second;
-        if (!cur_hook_sp->IsActive())
-            continue;
-        
-        bool any_thread_matched = false;
-        for (size_t i = 0; keep_going && i < num_exe_ctx; i++)
-        {
-            if ((cur_hook_sp->GetSpecifier() == nullptr 
-                  || cur_hook_sp->GetSpecifier()->SymbolContextMatches(sym_ctx_with_reasons[i]))
-                && (cur_hook_sp->GetThreadSpecifier() == nullptr
-                    || cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx_with_reasons[i].GetThreadRef())))
-            {
-                if (!hooks_ran)
-                {
-                    hooks_ran = true;
-                }
-                if (print_hook_header && !any_thread_matched)
-                {
-                    const char *cmd = (cur_hook_sp->GetCommands().GetSize() == 1 ?
-                                       cur_hook_sp->GetCommands().GetStringAtIndex(0) :
-                                       nullptr);
-                    if (cmd)
-                        result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(), cmd);
-                    else
-                        result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
-                    any_thread_matched = true;
-                }
-                
-                if (print_thread_header)
-                    result.AppendMessageWithFormat("-- Thread %d\n", exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
-
-                CommandInterpreterRunOptions options;
-                options.SetStopOnContinue (true);
-                options.SetStopOnError (true);
-                options.SetEchoCommands (false);
-                options.SetPrintResults (true);
-                options.SetAddToHistory (false);
-
-                GetDebugger().GetCommandInterpreter().HandleCommands (cur_hook_sp->GetCommands(),
-                                                                      &exc_ctx_with_reasons[i],
-                                                                      options,
-                                                                      result);
-
-                // If the command started the target going again, we should bag out of
-                // running the stop hooks.
-                if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || 
-                    (result.GetStatus() == eReturnStatusSuccessContinuingResult))
-                {
-                    result.AppendMessageWithFormat ("Aborting stop hooks, hook %" PRIu64 " set the program running.", cur_hook_sp->GetID());
-                    keep_going = false;
-                }
-            }
-        }
-    }
-
-    result.GetImmediateOutputStream()->Flush();
-    result.GetImmediateErrorStream()->Flush();
-}
-
-const TargetPropertiesSP &
-Target::GetGlobalProperties()
-{
-    // NOTE: intentional leak so we don't crash if global destructor chain gets
-    // called as other threads still use the result of this function
-    static TargetPropertiesSP *g_settings_sp_ptr = nullptr;
-    static std::once_flag g_once_flag;
-    std::call_once(g_once_flag,  []() {
-        g_settings_sp_ptr = new TargetPropertiesSP(new TargetProperties(nullptr));
-    });
-    return *g_settings_sp_ptr;
-}
-
-Error
-Target::Install (ProcessLaunchInfo *launch_info)
-{
-    Error error;
-    PlatformSP platform_sp (GetPlatform());
-    if (platform_sp)
-    {
-        if (platform_sp->IsRemote())
-        {
-            if (platform_sp->IsConnected())
-            {
-                // Install all files that have an install path, and always install the
-                // main executable when connected to a remote platform
-                const ModuleList& modules = GetImages();
-                const size_t num_images = modules.GetSize();
-                for (size_t idx = 0; idx < num_images; ++idx)
-                {
-                    ModuleSP module_sp(modules.GetModuleAtIndex(idx));
-                    if (module_sp)
-                    {
-                        const bool is_main_executable = module_sp == GetExecutableModule();
-                        FileSpec local_file (module_sp->GetFileSpec());
-                        if (local_file)
-                        {
-                            FileSpec remote_file (module_sp->GetRemoteInstallFileSpec());
-                            if (!remote_file)
-                            {
-                                if (is_main_executable) // TODO: add setting for always installing main executable???
-                                {
-                                    // Always install the main executable
-                                    remote_file = platform_sp->GetRemoteWorkingDirectory();
-                                    remote_file.AppendPathComponent(module_sp->GetFileSpec().GetFilename().GetCString());
-                                }
-                            }
-                            if (remote_file)
-                            {
-                                error = platform_sp->Install(local_file, remote_file);
-                                if (error.Success())
-                                {
-                                    module_sp->SetPlatformFileSpec(remote_file);
-                                    if (is_main_executable)
-                                    {
-                                        platform_sp->SetFilePermissions(remote_file, 0700);
-                                        if (launch_info)
-                                            launch_info->SetExecutableFile(remote_file, false);
-                                    }
-                                }
-                                else
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    return error;
-}
-
-bool
-Target::ResolveLoadAddress (addr_t load_addr, Address &so_addr, uint32_t stop_id)
-{
-    return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);
-}
-
-bool
-Target::ResolveFileAddress (lldb::addr_t file_addr, Address &resolved_addr)
-{
-    return m_images.ResolveFileAddress(file_addr, resolved_addr);
-}
-
-bool
-Target::SetSectionLoadAddress (const SectionSP &section_sp, addr_t new_section_load_addr, bool warn_multiple)
-{
-    const addr_t old_section_load_addr = m_section_load_history.GetSectionLoadAddress (SectionLoadHistory::eStopIDNow, section_sp);
-    if (old_section_load_addr != new_section_load_addr)
-    {
-        uint32_t stop_id = 0;
-        ProcessSP process_sp(GetProcessSP());
-        if (process_sp)
-            stop_id = process_sp->GetStopID();
-        else
-            stop_id = m_section_load_history.GetLastStopID();
-        if (m_section_load_history.SetSectionLoadAddress (stop_id, section_sp, new_section_load_addr, warn_multiple))
-            return true; // Return true if the section load address was changed...
-    }
-    return false; // Return false to indicate nothing changed
-}
-
-size_t
-Target::UnloadModuleSections (const ModuleList &module_list)
-{
-    size_t section_unload_count = 0;
-    size_t num_modules = module_list.GetSize();
-    for (size_t i=0; i<num_modules; ++i)
-    {
-        section_unload_count += UnloadModuleSections (module_list.GetModuleAtIndex(i));
-    }
-    return section_unload_count;
-}
-
-size_t
-Target::UnloadModuleSections (const lldb::ModuleSP &module_sp)
-{
-    uint32_t stop_id = 0;
-    ProcessSP process_sp(GetProcessSP());
-    if (process_sp)
-        stop_id = process_sp->GetStopID();
+    if (section_load_list.IsEmpty())
+      // No sections are loaded, so we must assume we are not running yet
+      // and need to operate only on file address.
+      m_images.ResolveFileAddress(addr, resolved_addr);
     else
-        stop_id = m_section_load_history.GetLastStopID();
-    SectionList *sections = module_sp->GetSectionList();
-    size_t section_unload_count = 0;
-    if (sections)
-    {
-        const uint32_t num_sections = sections->GetNumSections(0);
-        for (uint32_t i = 0; i < num_sections; ++i)
-        {
-            section_unload_count += m_section_load_history.SetSectionUnloaded(stop_id, sections->GetSectionAtIndex(i));
-        }
-    }
-    return section_unload_count;
-}
+      section_load_list.ResolveLoadAddress(addr, resolved_addr);
 
-bool
-Target::SetSectionUnloaded (const lldb::SectionSP &section_sp)
-{
-    uint32_t stop_id = 0;
-    ProcessSP process_sp(GetProcessSP());
-    if (process_sp)
-        stop_id = process_sp->GetStopID();
+    // Get the function boundaries to make sure we don't scan back before the
+    // beginning of the current function.
+    ModuleSP temp_addr_module_sp(resolved_addr.GetModule());
+    if (temp_addr_module_sp) {
+      SymbolContext sc;
+      uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+      temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr,
+                                                          resolve_scope, sc);
+      Address sym_addr;
+      if (sc.function)
+        sym_addr = sc.function->GetAddressRange().GetBaseAddress();
+      else if (sc.symbol)
+        sym_addr = sc.symbol->GetAddress();
+
+      function_start = sym_addr.GetLoadAddress(this);
+      if (function_start == LLDB_INVALID_ADDRESS)
+        function_start = sym_addr.GetFileAddress();
+
+      if (function_start)
+        current_offset = addr - function_start;
+    }
+
+    // If breakpoint address is start of function then we dont have to do
+    // anything.
+    if (current_offset == 0)
+      return breakable_addr;
     else
-        stop_id = m_section_load_history.GetLastStopID();
-    return m_section_load_history.SetSectionUnloaded (stop_id, section_sp);
-}
+      loop_count = current_offset / 2;
 
-bool
-Target::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t load_addr)
-{
-    uint32_t stop_id = 0;
-    ProcessSP process_sp(GetProcessSP());
-    if (process_sp)
-        stop_id = process_sp->GetStopID();
-    else
-        stop_id = m_section_load_history.GetLastStopID();
-    return m_section_load_history.SetSectionUnloaded (stop_id, section_sp, load_addr);
-}
-
-void
-Target::ClearAllLoadedSections ()
-{
-    m_section_load_history.Clear();
-}
-
-Error
-Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
-{
-    Error error;
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
-
-    if (log)
-        log->Printf ("Target::%s() called for %s", __FUNCTION__, launch_info.GetExecutableFile().GetPath().c_str ());
-
-    StateType state = eStateInvalid;
-    
-    // Scope to temporarily get the process state in case someone has manually
-    // remotely connected already to a process and we can skip the platform
-    // launching.
-    {
-        ProcessSP process_sp (GetProcessSP());
-    
-        if (process_sp)
-        {
-            state = process_sp->GetState();
-            if (log)
-                log->Printf ("Target::%s the process exists, and its current state is %s", __FUNCTION__, StateAsCString (state));
-        }
-        else
-        {
-            if (log)
-                log->Printf ("Target::%s the process instance doesn't currently exist.", __FUNCTION__);
-        }
+    if (loop_count > 3) {
+      // Scan previous 6 bytes
+      if (IsMips16 | IsMicromips)
+        loop_count = 3;
+      // For mips-only, instructions are always 4 bytes, so scan previous 4
+      // bytes only.
+      else
+        loop_count = 2;
     }
 
-    launch_info.GetFlags().Set (eLaunchFlagDebug);
-    
-    // Get the value of synchronous execution here.  If you wait till after you have started to
-    // run, then you could have hit a breakpoint, whose command might switch the value, and
-    // then you'll pick up that incorrect value.
-    Debugger &debugger = GetDebugger();
-    const bool synchronous_execution = debugger.GetCommandInterpreter().GetSynchronous ();
-    
-    PlatformSP platform_sp (GetPlatform());
-    
-    // Finalize the file actions, and if none were given, default to opening
-    // up a pseudo terminal
-    const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
-    if (log)
-        log->Printf ("Target::%s have platform=%s, platform_sp->IsHost()=%s, default_to_use_pty=%s",
-                     __FUNCTION__,
-                     platform_sp ? "true" : "false",
-                     platform_sp ? (platform_sp->IsHost () ? "true" : "false") : "n/a",
-                     default_to_use_pty ? "true" : "false");
+    // Create Disassembler Instance
+    lldb::DisassemblerSP disasm_sp(
+        Disassembler::FindPlugin(m_arch, nullptr, nullptr));
 
-    launch_info.FinalizeFileActions (this, default_to_use_pty);
-    
-    if (state == eStateConnected)
-    {
-        if (launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
-        {
-            error.SetErrorString("can't launch in tty when launching through a remote connection");
-            return error;
+    ExecutionContext exe_ctx;
+    CalculateExecutionContext(exe_ctx);
+    InstructionList instruction_list;
+    InstructionSP prev_insn;
+    bool prefer_file_cache = true; // Read from file
+    uint32_t inst_to_choose = 0;
+
+    for (uint32_t i = 1; i <= loop_count; i++) {
+      // Adjust the address to read from.
+      resolved_addr.Slide(-2);
+      AddressRange range(resolved_addr, i * 2);
+      uint32_t insn_size = 0;
+
+      disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
+
+      uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
+      if (num_insns) {
+        prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0);
+        insn_size = prev_insn->GetOpcode().GetByteSize();
+        if (i == 1 && insn_size == 2) {
+          // This looks like a valid 2-byte instruction (but it could be a part
+          // of upper 4 byte instruction).
+          instruction_list.Append(prev_insn);
+          inst_to_choose = 1;
+        } else if (i == 2) {
+          // Here we may get one 4-byte instruction or two 2-byte instructions.
+          if (num_insns == 2) {
+            // Looks like there are two 2-byte instructions above our breakpoint
+            // target address.
+            // Now the upper 2-byte instruction is either a valid 2-byte
+            // instruction or could be a part of it's upper 4-byte instruction.
+            // In both cases we don't care because in this case lower 2-byte
+            // instruction is definitely a valid instruction
+            // and whatever i=1 iteration has found out is true.
+            inst_to_choose = 1;
+            break;
+          } else if (insn_size == 4) {
+            // This instruction claims its a valid 4-byte instruction. But it
+            // could be a part of it's upper 4-byte instruction.
+            // Lets try scanning upper 2 bytes to verify this.
+            instruction_list.Append(prev_insn);
+            inst_to_choose = 2;
+          }
+        } else if (i == 3) {
+          if (insn_size == 4)
+            // FIXME: We reached here that means instruction at [target - 4] has
+            // already claimed to be a 4-byte instruction,
+            // and now instruction at [target - 6] is also claiming that it's a
+            // 4-byte instruction. This can not be true.
+            // In this case we can not decide the valid previous instruction so
+            // we let lldb set the breakpoint at the address given by user.
+            inst_to_choose = 0;
+          else
+            // This is straight-forward
+            inst_to_choose = 2;
+          break;
         }
+      } else {
+        // Decode failed, bytes do not form a valid instruction. So whatever
+        // previous iteration has found out is true.
+        if (i > 1) {
+          inst_to_choose = i - 1;
+          break;
+        }
+      }
     }
-    
-    if (!launch_info.GetArchitecture().IsValid())
-        launch_info.GetArchitecture() = GetArchitecture();
 
-    // If we're not already connected to the process, and if we have a platform that can launch a process for debugging, go ahead and do that here.
-    if (state != eStateConnected && platform_sp && platform_sp->CanDebugProcess ())
-    {
+    // Check if we are able to find any valid instruction.
+    if (inst_to_choose) {
+      if (inst_to_choose > instruction_list.GetSize())
+        inst_to_choose--;
+      prev_insn = instruction_list.GetInstructionAtIndex(inst_to_choose - 1);
+
+      if (prev_insn->HasDelaySlot()) {
+        uint32_t shift_size = prev_insn->GetOpcode().GetByteSize();
+        // Adjust the breakable address
+        breakable_addr = addr - shift_size;
         if (log)
-            log->Printf ("Target::%s asking the platform to debug the process", __FUNCTION__);
-
-        // Get a weak pointer to the previous process if we have one
-        ProcessWP process_wp;
-        if (m_process_sp)
-            process_wp = m_process_sp;
-        m_process_sp = GetPlatform()->DebugProcess (launch_info,
-                                                    debugger,
-                                                    this,
-                                                    error);
-
-        // Cleanup the old process since someone might still have a strong
-        // reference to this process and we would like to allow it to cleanup
-        // as much as it can without the object being destroyed. We try to
-        // lock the shared pointer and if that works, then someone else still
-        // has a strong reference to the process.
-
-        ProcessSP old_process_sp(process_wp.lock());
-        if (old_process_sp)
-            old_process_sp->Finalize();
+          log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64
+                      " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
+                      __FUNCTION__, addr, breakable_addr);
+      }
     }
+    break;
+  }
+  }
+  return breakable_addr;
+}
+
+SourceManager &Target::GetSourceManager() {
+  if (!m_source_manager_ap)
+    m_source_manager_ap.reset(new SourceManager(shared_from_this()));
+  return *m_source_manager_ap;
+}
+
+ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() {
+  static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended
+                                                       // we can make it
+                                                       // per-target
+
+  {
+    std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex);
+
+    if (!m_clang_modules_decl_vendor_ap) {
+      m_clang_modules_decl_vendor_ap.reset(
+          ClangModulesDeclVendor::Create(*this));
+    }
+  }
+
+  return m_clang_modules_decl_vendor_ap.get();
+}
+
+Target::StopHookSP Target::CreateStopHook() {
+  lldb::user_id_t new_uid = ++m_stop_hook_next_id;
+  Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid));
+  m_stop_hooks[new_uid] = stop_hook_sp;
+  return stop_hook_sp;
+}
+
+bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {
+  size_t num_removed = m_stop_hooks.erase(user_id);
+  return (num_removed != 0);
+}
+
+void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); }
+
+Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) {
+  StopHookSP found_hook;
+
+  StopHookCollection::iterator specified_hook_iter;
+  specified_hook_iter = m_stop_hooks.find(user_id);
+  if (specified_hook_iter != m_stop_hooks.end())
+    found_hook = (*specified_hook_iter).second;
+  return found_hook;
+}
+
+bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id,
+                                        bool active_state) {
+  StopHookCollection::iterator specified_hook_iter;
+  specified_hook_iter = m_stop_hooks.find(user_id);
+  if (specified_hook_iter == m_stop_hooks.end())
+    return false;
+
+  (*specified_hook_iter).second->SetIsActive(active_state);
+  return true;
+}
+
+void Target::SetAllStopHooksActiveState(bool active_state) {
+  StopHookCollection::iterator pos, end = m_stop_hooks.end();
+  for (pos = m_stop_hooks.begin(); pos != end; pos++) {
+    (*pos).second->SetIsActive(active_state);
+  }
+}
+
+void Target::RunStopHooks() {
+  if (m_suppress_stop_hooks)
+    return;
+
+  if (!m_process_sp)
+    return;
+
+  // <rdar://problem/12027563> make sure we check that we are not stopped
+  // because of us running a user expression
+  // since in that case we do not want to run the stop-hooks
+  if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return;
+
+  if (m_stop_hooks.empty())
+    return;
+
+  StopHookCollection::iterator pos, end = m_stop_hooks.end();
+
+  // If there aren't any active stop hooks, don't bother either:
+  bool any_active_hooks = false;
+  for (pos = m_stop_hooks.begin(); pos != end; pos++) {
+    if ((*pos).second->IsActive()) {
+      any_active_hooks = true;
+      break;
+    }
+  }
+  if (!any_active_hooks)
+    return;
+
+  CommandReturnObject result;
+
+  std::vector<ExecutionContext> exc_ctx_with_reasons;
+  std::vector<SymbolContext> sym_ctx_with_reasons;
+
+  ThreadList &cur_threadlist = m_process_sp->GetThreadList();
+  size_t num_threads = cur_threadlist.GetSize();
+  for (size_t i = 0; i < num_threads; i++) {
+    lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);
+    if (cur_thread_sp->ThreadStoppedForAReason()) {
+      lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);
+      exc_ctx_with_reasons.push_back(ExecutionContext(
+          m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get()));
+      sym_ctx_with_reasons.push_back(
+          cur_frame_sp->GetSymbolContext(eSymbolContextEverything));
+    }
+  }
+
+  // If no threads stopped for a reason, don't run the stop-hooks.
+  size_t num_exe_ctx = exc_ctx_with_reasons.size();
+  if (num_exe_ctx == 0)
+    return;
+
+  result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream());
+  result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream());
+
+  bool keep_going = true;
+  bool hooks_ran = false;
+  bool print_hook_header = (m_stop_hooks.size() != 1);
+  bool print_thread_header = (num_exe_ctx != 1);
+
+  for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) {
+    // result.Clear();
+    StopHookSP cur_hook_sp = (*pos).second;
+    if (!cur_hook_sp->IsActive())
+      continue;
+
+    bool any_thread_matched = false;
+    for (size_t i = 0; keep_going && i < num_exe_ctx; i++) {
+      if ((cur_hook_sp->GetSpecifier() == nullptr ||
+           cur_hook_sp->GetSpecifier()->SymbolContextMatches(
+               sym_ctx_with_reasons[i])) &&
+          (cur_hook_sp->GetThreadSpecifier() == nullptr ||
+           cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests(
+               exc_ctx_with_reasons[i].GetThreadRef()))) {
+        if (!hooks_ran) {
+          hooks_ran = true;
+        }
+        if (print_hook_header && !any_thread_matched) {
+          const char *cmd =
+              (cur_hook_sp->GetCommands().GetSize() == 1
+                   ? cur_hook_sp->GetCommands().GetStringAtIndex(0)
+                   : nullptr);
+          if (cmd)
+            result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n",
+                                           cur_hook_sp->GetID(), cmd);
+          else
+            result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n",
+                                           cur_hook_sp->GetID());
+          any_thread_matched = true;
+        }
+
+        if (print_thread_header)
+          result.AppendMessageWithFormat(
+              "-- Thread %d\n",
+              exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
+
+        CommandInterpreterRunOptions options;
+        options.SetStopOnContinue(true);
+        options.SetStopOnError(true);
+        options.SetEchoCommands(false);
+        options.SetPrintResults(true);
+        options.SetAddToHistory(false);
+
+        GetDebugger().GetCommandInterpreter().HandleCommands(
+            cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options,
+            result);
+
+        // If the command started the target going again, we should bag out of
+        // running the stop hooks.
+        if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
+            (result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
+          result.AppendMessageWithFormat("Aborting stop hooks, hook %" PRIu64
+                                         " set the program running.",
+                                         cur_hook_sp->GetID());
+          keep_going = false;
+        }
+      }
+    }
+  }
+
+  result.GetImmediateOutputStream()->Flush();
+  result.GetImmediateErrorStream()->Flush();
+}
+
+const TargetPropertiesSP &Target::GetGlobalProperties() {
+  // NOTE: intentional leak so we don't crash if global destructor chain gets
+  // called as other threads still use the result of this function
+  static TargetPropertiesSP *g_settings_sp_ptr = nullptr;
+  static std::once_flag g_once_flag;
+  std::call_once(g_once_flag, []() {
+    g_settings_sp_ptr = new TargetPropertiesSP(new TargetProperties(nullptr));
+  });
+  return *g_settings_sp_ptr;
+}
+
+Error Target::Install(ProcessLaunchInfo *launch_info) {
+  Error error;
+  PlatformSP platform_sp(GetPlatform());
+  if (platform_sp) {
+    if (platform_sp->IsRemote()) {
+      if (platform_sp->IsConnected()) {
+        // Install all files that have an install path, and always install the
+        // main executable when connected to a remote platform
+        const ModuleList &modules = GetImages();
+        const size_t num_images = modules.GetSize();
+        for (size_t idx = 0; idx < num_images; ++idx) {
+          ModuleSP module_sp(modules.GetModuleAtIndex(idx));
+          if (module_sp) {
+            const bool is_main_executable = module_sp == GetExecutableModule();
+            FileSpec local_file(module_sp->GetFileSpec());
+            if (local_file) {
+              FileSpec remote_file(module_sp->GetRemoteInstallFileSpec());
+              if (!remote_file) {
+                if (is_main_executable) // TODO: add setting for always
+                                        // installing main executable???
+                {
+                  // Always install the main executable
+                  remote_file = platform_sp->GetRemoteWorkingDirectory();
+                  remote_file.AppendPathComponent(
+                      module_sp->GetFileSpec().GetFilename().GetCString());
+                }
+              }
+              if (remote_file) {
+                error = platform_sp->Install(local_file, remote_file);
+                if (error.Success()) {
+                  module_sp->SetPlatformFileSpec(remote_file);
+                  if (is_main_executable) {
+                    platform_sp->SetFilePermissions(remote_file, 0700);
+                    if (launch_info)
+                      launch_info->SetExecutableFile(remote_file, false);
+                  }
+                } else
+                  break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return error;
+}
+
+bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr,
+                                uint32_t stop_id) {
+  return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);
+}
+
+bool Target::ResolveFileAddress(lldb::addr_t file_addr,
+                                Address &resolved_addr) {
+  return m_images.ResolveFileAddress(file_addr, resolved_addr);
+}
+
+bool Target::SetSectionLoadAddress(const SectionSP &section_sp,
+                                   addr_t new_section_load_addr,
+                                   bool warn_multiple) {
+  const addr_t old_section_load_addr =
+      m_section_load_history.GetSectionLoadAddress(
+          SectionLoadHistory::eStopIDNow, section_sp);
+  if (old_section_load_addr != new_section_load_addr) {
+    uint32_t stop_id = 0;
+    ProcessSP process_sp(GetProcessSP());
+    if (process_sp)
+      stop_id = process_sp->GetStopID();
     else
-    {
-        if (log)
-            log->Printf ("Target::%s the platform doesn't know how to debug a process, getting a process plugin to do this for us.", __FUNCTION__);
+      stop_id = m_section_load_history.GetLastStopID();
+    if (m_section_load_history.SetSectionLoadAddress(
+            stop_id, section_sp, new_section_load_addr, warn_multiple))
+      return true; // Return true if the section load address was changed...
+  }
+  return false; // Return false to indicate nothing changed
+}
 
-        if (state == eStateConnected)
-        {
-            assert(m_process_sp);
-        }
-        else
-        {
-            // Use a Process plugin to construct the process.
-            const char *plugin_name = launch_info.GetProcessPluginName();
-            CreateProcess(launch_info.GetListenerForProcess(debugger), plugin_name, nullptr);
-        }
+size_t Target::UnloadModuleSections(const ModuleList &module_list) {
+  size_t section_unload_count = 0;
+  size_t num_modules = module_list.GetSize();
+  for (size_t i = 0; i < num_modules; ++i) {
+    section_unload_count +=
+        UnloadModuleSections(module_list.GetModuleAtIndex(i));
+  }
+  return section_unload_count;
+}
 
-        // Since we didn't have a platform launch the process, launch it here.
-        if (m_process_sp)
-            error = m_process_sp->Launch (launch_info);
+size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) {
+  uint32_t stop_id = 0;
+  ProcessSP process_sp(GetProcessSP());
+  if (process_sp)
+    stop_id = process_sp->GetStopID();
+  else
+    stop_id = m_section_load_history.GetLastStopID();
+  SectionList *sections = module_sp->GetSectionList();
+  size_t section_unload_count = 0;
+  if (sections) {
+    const uint32_t num_sections = sections->GetNumSections(0);
+    for (uint32_t i = 0; i < num_sections; ++i) {
+      section_unload_count += m_section_load_history.SetSectionUnloaded(
+          stop_id, sections->GetSectionAtIndex(i));
     }
-    
-    if (!m_process_sp)
-    {
-        if (error.Success())
-            error.SetErrorString("failed to launch or debug process");
-        return error;
+  }
+  return section_unload_count;
+}
+
+bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp) {
+  uint32_t stop_id = 0;
+  ProcessSP process_sp(GetProcessSP());
+  if (process_sp)
+    stop_id = process_sp->GetStopID();
+  else
+    stop_id = m_section_load_history.GetLastStopID();
+  return m_section_load_history.SetSectionUnloaded(stop_id, section_sp);
+}
+
+bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp,
+                                addr_t load_addr) {
+  uint32_t stop_id = 0;
+  ProcessSP process_sp(GetProcessSP());
+  if (process_sp)
+    stop_id = process_sp->GetStopID();
+  else
+    stop_id = m_section_load_history.GetLastStopID();
+  return m_section_load_history.SetSectionUnloaded(stop_id, section_sp,
+                                                   load_addr);
+}
+
+void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }
+
+Error Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
+  Error error;
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
+
+  if (log)
+    log->Printf("Target::%s() called for %s", __FUNCTION__,
+                launch_info.GetExecutableFile().GetPath().c_str());
+
+  StateType state = eStateInvalid;
+
+  // Scope to temporarily get the process state in case someone has manually
+  // remotely connected already to a process and we can skip the platform
+  // launching.
+  {
+    ProcessSP process_sp(GetProcessSP());
+
+    if (process_sp) {
+      state = process_sp->GetState();
+      if (log)
+        log->Printf(
+            "Target::%s the process exists, and its current state is %s",
+            __FUNCTION__, StateAsCString(state));
+    } else {
+      if (log)
+        log->Printf("Target::%s the process instance doesn't currently exist.",
+                    __FUNCTION__);
+    }
+  }
+
+  launch_info.GetFlags().Set(eLaunchFlagDebug);
+
+  // Get the value of synchronous execution here.  If you wait till after you
+  // have started to
+  // run, then you could have hit a breakpoint, whose command might switch the
+  // value, and
+  // then you'll pick up that incorrect value.
+  Debugger &debugger = GetDebugger();
+  const bool synchronous_execution =
+      debugger.GetCommandInterpreter().GetSynchronous();
+
+  PlatformSP platform_sp(GetPlatform());
+
+  // Finalize the file actions, and if none were given, default to opening
+  // up a pseudo terminal
+  const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
+  if (log)
+    log->Printf("Target::%s have platform=%s, platform_sp->IsHost()=%s, "
+                "default_to_use_pty=%s",
+                __FUNCTION__, platform_sp ? "true" : "false",
+                platform_sp ? (platform_sp->IsHost() ? "true" : "false")
+                            : "n/a",
+                default_to_use_pty ? "true" : "false");
+
+  launch_info.FinalizeFileActions(this, default_to_use_pty);
+
+  if (state == eStateConnected) {
+    if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
+      error.SetErrorString(
+          "can't launch in tty when launching through a remote connection");
+      return error;
+    }
+  }
+
+  if (!launch_info.GetArchitecture().IsValid())
+    launch_info.GetArchitecture() = GetArchitecture();
+
+  // If we're not already connected to the process, and if we have a platform
+  // that can launch a process for debugging, go ahead and do that here.
+  if (state != eStateConnected && platform_sp &&
+      platform_sp->CanDebugProcess()) {
+    if (log)
+      log->Printf("Target::%s asking the platform to debug the process",
+                  __FUNCTION__);
+
+    // Get a weak pointer to the previous process if we have one
+    ProcessWP process_wp;
+    if (m_process_sp)
+      process_wp = m_process_sp;
+    m_process_sp =
+        GetPlatform()->DebugProcess(launch_info, debugger, this, error);
+
+    // Cleanup the old process since someone might still have a strong
+    // reference to this process and we would like to allow it to cleanup
+    // as much as it can without the object being destroyed. We try to
+    // lock the shared pointer and if that works, then someone else still
+    // has a strong reference to the process.
+
+    ProcessSP old_process_sp(process_wp.lock());
+    if (old_process_sp)
+      old_process_sp->Finalize();
+  } else {
+    if (log)
+      log->Printf("Target::%s the platform doesn't know how to debug a "
+                  "process, getting a process plugin to do this for us.",
+                  __FUNCTION__);
+
+    if (state == eStateConnected) {
+      assert(m_process_sp);
+    } else {
+      // Use a Process plugin to construct the process.
+      const char *plugin_name = launch_info.GetProcessPluginName();
+      CreateProcess(launch_info.GetListenerForProcess(debugger), plugin_name,
+                    nullptr);
     }
 
+    // Since we didn't have a platform launch the process, launch it here.
+    if (m_process_sp)
+      error = m_process_sp->Launch(launch_info);
+  }
+
+  if (!m_process_sp) {
     if (error.Success())
-    {
-        if (synchronous_execution || !launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
-        {
-            ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
-            if (!hijack_listener_sp)
-            {
-                hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
-                launch_info.SetHijackListener(hijack_listener_sp);
-                m_process_sp->HijackProcessEvents(hijack_listener_sp);
-            }
-
-            StateType state = m_process_sp->WaitForProcessToStop(std::chrono::microseconds(0), nullptr, false,
-                                                                 hijack_listener_sp, nullptr);
-
-            if (state == eStateStopped)
-            {
-                if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
-                {
-                    if (synchronous_execution)
-                    {
-                        error = m_process_sp->PrivateResume();
-                        if (error.Success())
-                        {
-                            state = m_process_sp->WaitForProcessToStop(std::chrono::microseconds(0), nullptr, true,
-                                                                       hijack_listener_sp, stream);
-                            const bool must_be_alive = false; // eStateExited is ok, so this must be false
-                            if (!StateIsStoppedState(state, must_be_alive))
-                            {
-                                error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
-                            }
-                        }
-                    }
-                    else
-                    {
-                        m_process_sp->RestoreProcessEvents();
-                        error = m_process_sp->PrivateResume();
-                    }
-                    if (!error.Success())
-                    {
-                        Error error2;
-                        error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
-                        error = error2;
-                    }
-                }
-            }
-            else if (state == eStateExited)
-            {
-                bool with_shell = !!launch_info.GetShell();
-                const int exit_status = m_process_sp->GetExitStatus();
-                const char *exit_desc = m_process_sp->GetExitDescription();
-#define LAUNCH_SHELL_MESSAGE "\n'r' and 'run' are aliases that default to launching through a shell.\nTry launching without going through a shell by using 'process launch'."
-                if (exit_desc && exit_desc[0])
-                {
-                    if (with_shell)
-                        error.SetErrorStringWithFormat ("process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE, exit_status, exit_desc);
-                    else
-                        error.SetErrorStringWithFormat ("process exited with status %i (%s)", exit_status, exit_desc);
-                }
-                else
-                {
-                    if (with_shell)
-                        error.SetErrorStringWithFormat ("process exited with status %i" LAUNCH_SHELL_MESSAGE, exit_status);
-                    else
-                        error.SetErrorStringWithFormat ("process exited with status %i", exit_status);
-                }
-            }
-            else
-            {
-                error.SetErrorStringWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
-            }
-        }
-        m_process_sp->RestoreProcessEvents ();
-    }
-    else
-    {
-        Error error2;
-        error2.SetErrorStringWithFormat ("process launch failed: %s", error.AsCString());
-        error = error2;
-    }
+      error.SetErrorString("failed to launch or debug process");
     return error;
+  }
+
+  if (error.Success()) {
+    if (synchronous_execution ||
+        !launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
+      ListenerSP hijack_listener_sp(launch_info.GetHijackListener());
+      if (!hijack_listener_sp) {
+        hijack_listener_sp =
+            Listener::MakeListener("lldb.Target.Launch.hijack");
+        launch_info.SetHijackListener(hijack_listener_sp);
+        m_process_sp->HijackProcessEvents(hijack_listener_sp);
+      }
+
+      StateType state = m_process_sp->WaitForProcessToStop(
+          std::chrono::microseconds(0), nullptr, false, hijack_listener_sp,
+          nullptr);
+
+      if (state == eStateStopped) {
+        if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
+          if (synchronous_execution) {
+            error = m_process_sp->PrivateResume();
+            if (error.Success()) {
+              state = m_process_sp->WaitForProcessToStop(
+                  std::chrono::microseconds(0), nullptr, true,
+                  hijack_listener_sp, stream);
+              const bool must_be_alive =
+                  false; // eStateExited is ok, so this must be false
+              if (!StateIsStoppedState(state, must_be_alive)) {
+                error.SetErrorStringWithFormat("process isn't stopped: %s",
+                                               StateAsCString(state));
+              }
+            }
+          } else {
+            m_process_sp->RestoreProcessEvents();
+            error = m_process_sp->PrivateResume();
+          }
+          if (!error.Success()) {
+            Error error2;
+            error2.SetErrorStringWithFormat(
+                "process resume at entry point failed: %s", error.AsCString());
+            error = error2;
+          }
+        }
+      } else if (state == eStateExited) {
+        bool with_shell = !!launch_info.GetShell();
+        const int exit_status = m_process_sp->GetExitStatus();
+        const char *exit_desc = m_process_sp->GetExitDescription();
+#define LAUNCH_SHELL_MESSAGE                                                   \
+  "\n'r' and 'run' are aliases that default to launching through a "           \
+  "shell.\nTry launching without going through a shell by using 'process "     \
+  "launch'."
+        if (exit_desc && exit_desc[0]) {
+          if (with_shell)
+            error.SetErrorStringWithFormat(
+                "process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE,
+                exit_status, exit_desc);
+          else
+            error.SetErrorStringWithFormat("process exited with status %i (%s)",
+                                           exit_status, exit_desc);
+        } else {
+          if (with_shell)
+            error.SetErrorStringWithFormat(
+                "process exited with status %i" LAUNCH_SHELL_MESSAGE,
+                exit_status);
+          else
+            error.SetErrorStringWithFormat("process exited with status %i",
+                                           exit_status);
+        }
+      } else {
+        error.SetErrorStringWithFormat(
+            "initial process state wasn't stopped: %s", StateAsCString(state));
+      }
+    }
+    m_process_sp->RestoreProcessEvents();
+  } else {
+    Error error2;
+    error2.SetErrorStringWithFormat("process launch failed: %s",
+                                    error.AsCString());
+    error = error2;
+  }
+  return error;
 }
 
-Error
-Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
-{
-    auto state = eStateInvalid;
-    auto process_sp = GetProcessSP ();
-    if (process_sp)
-    {
-        state = process_sp->GetState ();
-        if (process_sp->IsAlive () && state != eStateConnected)
-        {
-            if (state == eStateAttaching)
-                return Error ("process attach is in progress");
-            return Error ("a process is already being debugged");
-        }
+Error Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
+  auto state = eStateInvalid;
+  auto process_sp = GetProcessSP();
+  if (process_sp) {
+    state = process_sp->GetState();
+    if (process_sp->IsAlive() && state != eStateConnected) {
+      if (state == eStateAttaching)
+        return Error("process attach is in progress");
+      return Error("a process is already being debugged");
     }
+  }
 
-    const ModuleSP old_exec_module_sp = GetExecutableModule ();
+  const ModuleSP old_exec_module_sp = GetExecutableModule();
 
-    // If no process info was specified, then use the target executable
-    // name as 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 ();
+  // If no process info was specified, then use the target executable
+  // name as 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();
 
-        if (!attach_info.ProcessInfoSpecified ())
-        {
-            return Error ("no process specified, create a target with a file, or specify the --pid or --name");
-        }
+    if (!attach_info.ProcessInfoSpecified()) {
+      return Error("no process specified, create a target with a file, or "
+                   "specify the --pid or --name");
     }
+  }
 
-    const auto platform_sp = GetDebugger ().GetPlatformList ().GetSelectedPlatform ();
-    ListenerSP hijack_listener_sp;
-    const bool async = attach_info.GetAsync();
-    if (!async)
-    {
-        hijack_listener_sp = Listener::MakeListener("lldb.Target.Attach.attach.hijack");
-        attach_info.SetHijackListener (hijack_listener_sp);
-    }
+  const auto platform_sp =
+      GetDebugger().GetPlatformList().GetSelectedPlatform();
+  ListenerSP hijack_listener_sp;
+  const bool async = attach_info.GetAsync();
+  if (!async) {
+    hijack_listener_sp =
+        Listener::MakeListener("lldb.Target.Attach.attach.hijack");
+    attach_info.SetHijackListener(hijack_listener_sp);
+  }
 
-    Error error;
-    if (state != eStateConnected && platform_sp != nullptr && platform_sp->CanDebugProcess ())
-    {
-        SetPlatform (platform_sp);
-        process_sp = platform_sp->Attach (attach_info, GetDebugger (), this, error);
+  Error error;
+  if (state != eStateConnected && platform_sp != nullptr &&
+      platform_sp->CanDebugProcess()) {
+    SetPlatform(platform_sp);
+    process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error);
+  } else {
+    if (state != eStateConnected) {
+      const char *plugin_name = attach_info.GetProcessPluginName();
+      process_sp =
+          CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),
+                        plugin_name, nullptr);
+      if (process_sp == nullptr) {
+        error.SetErrorStringWithFormat(
+            "failed to create process using plugin %s",
+            (plugin_name) ? plugin_name : "null");
+        return error;
+      }
     }
-    else
-    {
-        if (state != eStateConnected)
-        {
-            const char *plugin_name = attach_info.GetProcessPluginName ();
-            process_sp = CreateProcess (attach_info.GetListenerForProcess (GetDebugger ()), plugin_name, nullptr);
-            if (process_sp == nullptr)
-            {
-                error.SetErrorStringWithFormat ("failed to create process using plugin %s", (plugin_name) ? plugin_name : "null");
-                return error;
-            }
-        }
-        if (hijack_listener_sp)
-            process_sp->HijackProcessEvents (hijack_listener_sp);
-        error = process_sp->Attach (attach_info);
-    }
+    if (hijack_listener_sp)
+      process_sp->HijackProcessEvents(hijack_listener_sp);
+    error = process_sp->Attach(attach_info);
+  }
 
-    if (error.Success () && process_sp)
-    {
-        if (async)
-        {
-            process_sp->RestoreProcessEvents ();
-        }
+  if (error.Success() && process_sp) {
+    if (async) {
+      process_sp->RestoreProcessEvents();
+    } else {
+      state = process_sp->WaitForProcessToStop(
+          std::chrono::microseconds(0), nullptr, false,
+          attach_info.GetHijackListener(), stream);
+      process_sp->RestoreProcessEvents();
+
+      if (state != eStateStopped) {
+        const char *exit_desc = process_sp->GetExitDescription();
+        if (exit_desc)
+          error.SetErrorStringWithFormat("%s", exit_desc);
         else
-        {
-            state = process_sp->WaitForProcessToStop(std::chrono::microseconds(0), nullptr, false,
-                                                     attach_info.GetHijackListener(), stream);
-            process_sp->RestoreProcessEvents ();
-
-            if (state != eStateStopped)
-            {
-                const char *exit_desc = process_sp->GetExitDescription ();
-                if (exit_desc)
-                    error.SetErrorStringWithFormat ("%s", exit_desc);
-                else
-                    error.SetErrorString ("process did not stop (no such process or permission problem?)");
-                process_sp->Destroy (false);
-            }
-        }
+          error.SetErrorString(
+              "process did not stop (no such process or permission problem?)");
+        process_sp->Destroy(false);
+      }
     }
-    return error;
+  }
+  return error;
 }
 
 //--------------------------------------------------------------
 // Target::StopHook
 //--------------------------------------------------------------
-Target::StopHook::StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid) :
-        UserID (uid),
-        m_target_sp (target_sp),
-        m_commands (),
-        m_specifier_sp (),
-        m_thread_spec_ap(),
-        m_active (true)
-{
+Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
+    : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(),
+      m_thread_spec_ap(), m_active(true) {}
+
+Target::StopHook::StopHook(const StopHook &rhs)
+    : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
+      m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp),
+      m_thread_spec_ap(), m_active(rhs.m_active) {
+  if (rhs.m_thread_spec_ap)
+    m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
 }
 
-Target::StopHook::StopHook (const StopHook &rhs) :
-        UserID (rhs.GetID()),
-        m_target_sp (rhs.m_target_sp),
-        m_commands (rhs.m_commands),
-        m_specifier_sp (rhs.m_specifier_sp),
-        m_thread_spec_ap (),
-        m_active (rhs.m_active)
-{
-    if (rhs.m_thread_spec_ap)
-        m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
-}
-        
 Target::StopHook::~StopHook() = default;
 
-void
-Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier)
-{
-    m_specifier_sp.reset(specifier);
+void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {
+  m_specifier_sp.reset(specifier);
 }
 
-void
-Target::StopHook::SetThreadSpecifier (ThreadSpec *specifier)
-{
-    m_thread_spec_ap.reset (specifier);
+void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {
+  m_thread_spec_ap.reset(specifier);
 }
 
-void
-Target::StopHook::GetDescription (Stream *s, lldb::DescriptionLevel level) const
-{
-    int indent_level = s->GetIndentLevel();
+void Target::StopHook::GetDescription(Stream *s,
+                                      lldb::DescriptionLevel level) const {
+  int indent_level = s->GetIndentLevel();
 
+  s->SetIndentLevel(indent_level + 2);
+
+  s->Printf("Hook: %" PRIu64 "\n", GetID());
+  if (m_active)
+    s->Indent("State: enabled\n");
+  else
+    s->Indent("State: disabled\n");
+
+  if (m_specifier_sp) {
+    s->Indent();
+    s->PutCString("Specifier:\n");
+    s->SetIndentLevel(indent_level + 4);
+    m_specifier_sp->GetDescription(s, level);
     s->SetIndentLevel(indent_level + 2);
+  }
 
-    s->Printf ("Hook: %" PRIu64 "\n", GetID());
-    if (m_active)
-        s->Indent ("State: enabled\n");
-    else
-        s->Indent ("State: disabled\n");    
-    
-    if (m_specifier_sp)
-    {
-        s->Indent();
-        s->PutCString ("Specifier:\n");
-        s->SetIndentLevel (indent_level + 4);
-        m_specifier_sp->GetDescription (s, level);
-        s->SetIndentLevel (indent_level + 2);
-    }
+  if (m_thread_spec_ap) {
+    StreamString tmp;
+    s->Indent("Thread:\n");
+    m_thread_spec_ap->GetDescription(&tmp, level);
+    s->SetIndentLevel(indent_level + 4);
+    s->Indent(tmp.GetData());
+    s->PutCString("\n");
+    s->SetIndentLevel(indent_level + 2);
+  }
 
-    if (m_thread_spec_ap)
-    {
-        StreamString tmp;
-        s->Indent("Thread:\n");
-        m_thread_spec_ap->GetDescription (&tmp, level);
-        s->SetIndentLevel (indent_level + 4);
-        s->Indent (tmp.GetData());
-        s->PutCString ("\n");
-        s->SetIndentLevel (indent_level + 2);
-    }
-
-    s->Indent ("Commands: \n");
-    s->SetIndentLevel (indent_level + 4);
-    uint32_t num_commands = m_commands.GetSize();
-    for (uint32_t i = 0; i < num_commands; i++)
-    {
-        s->Indent(m_commands.GetStringAtIndex(i));
-        s->PutCString ("\n");
-    }
-    s->SetIndentLevel (indent_level);
+  s->Indent("Commands: \n");
+  s->SetIndentLevel(indent_level + 4);
+  uint32_t num_commands = m_commands.GetSize();
+  for (uint32_t i = 0; i < num_commands; i++) {
+    s->Indent(m_commands.GetStringAtIndex(i));
+    s->PutCString("\n");
+  }
+  s->SetIndentLevel(indent_level);
 }
 
 //--------------------------------------------------------------
 // class TargetProperties
 //--------------------------------------------------------------
 
-OptionEnumValueElement
-lldb_private::g_dynamic_value_types[] =
-{
-    { eNoDynamicValues,      "no-dynamic-values", "Don't calculate the dynamic type of values"},
-    { eDynamicCanRunTarget,  "run-target",        "Calculate the dynamic type of values even if you have to run the target."},
-    { eDynamicDontRunTarget, "no-run-target",     "Calculate the dynamic type of values, but don't run the target."},
-    { 0, nullptr, nullptr }
-};
+OptionEnumValueElement lldb_private::g_dynamic_value_types[] = {
+    {eNoDynamicValues, "no-dynamic-values",
+     "Don't calculate the dynamic type of values"},
+    {eDynamicCanRunTarget, "run-target", "Calculate the dynamic type of values "
+                                         "even if you have to run the target."},
+    {eDynamicDontRunTarget, "no-run-target",
+     "Calculate the dynamic type of values, but don't run the target."},
+    {0, nullptr, nullptr}};
 
-static OptionEnumValueElement
-g_inline_breakpoint_enums[] =
-{
-    { eInlineBreakpointsNever,   "never",     "Never look for inline breakpoint locations (fastest). This setting should only be used if you know that no inlining occurs in your programs."},
-    { eInlineBreakpointsHeaders, "headers",   "Only check for inline breakpoint locations when setting breakpoints in header files, but not when setting breakpoint in implementation source files (default)."},
-    { eInlineBreakpointsAlways,  "always",    "Always look for inline breakpoint locations when setting file and line breakpoints (slower but most accurate)."},
-    { 0, nullptr, nullptr }
-};
+static OptionEnumValueElement g_inline_breakpoint_enums[] = {
+    {eInlineBreakpointsNever, "never", "Never look for inline breakpoint "
+                                       "locations (fastest). This setting "
+                                       "should only be used if you know that "
+                                       "no inlining occurs in your programs."},
+    {eInlineBreakpointsHeaders, "headers",
+     "Only check for inline breakpoint locations when setting breakpoints in "
+     "header files, but not when setting breakpoint in implementation source "
+     "files (default)."},
+    {eInlineBreakpointsAlways, "always",
+     "Always look for inline breakpoint locations when setting file and line "
+     "breakpoints (slower but most accurate)."},
+    {0, nullptr, nullptr}};
 
-typedef enum x86DisassemblyFlavor
-{
-    eX86DisFlavorDefault,
-    eX86DisFlavorIntel,
-    eX86DisFlavorATT
+typedef enum x86DisassemblyFlavor {
+  eX86DisFlavorDefault,
+  eX86DisFlavorIntel,
+  eX86DisFlavorATT
 } x86DisassemblyFlavor;
 
-static OptionEnumValueElement
-g_x86_dis_flavor_value_types[] =
-{
-    { eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
-    { eX86DisFlavorIntel,   "intel",   "Intel disassembler flavor."},
-    { eX86DisFlavorATT,     "att",     "AT&T disassembler flavor."},
-    { 0, nullptr, nullptr }
+static OptionEnumValueElement g_x86_dis_flavor_value_types[] = {
+    {eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
+    {eX86DisFlavorIntel, "intel", "Intel disassembler flavor."},
+    {eX86DisFlavorATT, "att", "AT&T disassembler flavor."},
+    {0, nullptr, nullptr}};
+
+static OptionEnumValueElement g_hex_immediate_style_values[] = {
+    {Disassembler::eHexStyleC, "c", "C-style (0xffff)."},
+    {Disassembler::eHexStyleAsm, "asm", "Asm-style (0ffffh)."},
+    {0, nullptr, nullptr}};
+
+static OptionEnumValueElement g_load_script_from_sym_file_values[] = {
+    {eLoadScriptFromSymFileTrue, "true",
+     "Load debug scripts inside symbol files"},
+    {eLoadScriptFromSymFileFalse, "false",
+     "Do not load debug scripts inside symbol files."},
+    {eLoadScriptFromSymFileWarn, "warn",
+     "Warn about debug scripts inside symbol files but do not load them."},
+    {0, nullptr, nullptr}};
+
+static OptionEnumValueElement g_load_current_working_dir_lldbinit_values[] = {
+    {eLoadCWDlldbinitTrue, "true",
+     "Load .lldbinit files from current directory"},
+    {eLoadCWDlldbinitFalse, "false",
+     "Do not load .lldbinit files from current directory"},
+    {eLoadCWDlldbinitWarn, "warn",
+     "Warn about loading .lldbinit files from current directory"},
+    {0, nullptr, nullptr}};
+
+static OptionEnumValueElement g_memory_module_load_level_values[] = {
+    {eMemoryModuleLoadLevelMinimal, "minimal",
+     "Load minimal information when loading modules from memory. Currently "
+     "this setting loads sections only."},
+    {eMemoryModuleLoadLevelPartial, "partial",
+     "Load partial information when loading modules from memory. Currently "
+     "this setting loads sections and function bounds."},
+    {eMemoryModuleLoadLevelComplete, "complete",
+     "Load complete information when loading modules from memory. Currently "
+     "this setting loads sections and all symbols."},
+    {0, nullptr, nullptr}};
+
+static PropertyDefinition g_properties[] = {
+    {"default-arch", OptionValue::eTypeArch, true, 0, nullptr, nullptr,
+     "Default architecture to choose, when there's a choice."},
+    {"move-to-nearest-code", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Move breakpoints to nearest code."},
+    {"language", OptionValue::eTypeLanguage, false, eLanguageTypeUnknown,
+     nullptr, nullptr,
+     "The language to use when interpreting expressions entered in commands."},
+    {"expr-prefix", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr,
+     "Path to a file containing expressions to be prepended to all "
+     "expressions."},
+    {"prefer-dynamic-value", OptionValue::eTypeEnum, false,
+     eDynamicDontRunTarget, nullptr, g_dynamic_value_types,
+     "Should printed values be shown as their dynamic value."},
+    {"enable-synthetic-value", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Should synthetic values be used by default whenever available."},
+    {"skip-prologue", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
+     "Skip function prologues when setting breakpoints by name."},
+    {"source-map", OptionValue::eTypePathMap, false, 0, nullptr, nullptr,
+     "Source path remappings are used to track the change of location between "
+     "a source file when built, and "
+     "where it exists on the current system.  It consists of an array of "
+     "duples, the first element of each duple is "
+     "some part (starting at the root) of the path to the file when it was "
+     "built, "
+     "and the second is where the remainder of the original build hierarchy is "
+     "rooted on the local system.  "
+     "Each element of the array is checked in order and the first one that "
+     "results in a match wins."},
+    {"exec-search-paths", OptionValue::eTypeFileSpecList, false, 0, nullptr,
+     nullptr, "Executable search paths to use when locating executable files "
+              "whose paths don't match the local file system."},
+    {"debug-file-search-paths", OptionValue::eTypeFileSpecList, false, 0,
+     nullptr, nullptr,
+     "List of directories to be searched when locating debug symbol files."},
+    {"clang-module-search-paths", OptionValue::eTypeFileSpecList, false, 0,
+     nullptr, nullptr,
+     "List of directories to be searched when locating modules for Clang."},
+    {"auto-import-clang-modules", OptionValue::eTypeBoolean, false, true,
+     nullptr, nullptr,
+     "Automatically load Clang modules referred to by the program."},
+    {"auto-apply-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Automatically apply fix-it hints to expressions."},
+    {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Print the fixed expression text."},
+    {"max-children-count", OptionValue::eTypeSInt64, false, 256, nullptr,
+     nullptr, "Maximum number of children to expand in any level of depth."},
+    {"max-string-summary-length", OptionValue::eTypeSInt64, false, 1024,
+     nullptr, nullptr,
+     "Maximum number of characters to show when using %s in summary strings."},
+    {"max-memory-read-size", OptionValue::eTypeSInt64, false, 1024, nullptr,
+     nullptr, "Maximum number of bytes that 'memory read' will fetch before "
+              "--force must be specified."},
+    {"breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean, false,
+     true, nullptr, nullptr, "Consult the platform module avoid list when "
+                             "setting non-module specific breakpoints."},
+    {"arg0", OptionValue::eTypeString, false, 0, nullptr, nullptr,
+     "The first argument passed to the program in the argument array which can "
+     "be different from the executable itself."},
+    {"run-args", OptionValue::eTypeArgs, false, 0, nullptr, nullptr,
+     "A list containing all the arguments to be passed to the executable when "
+     "it is run. Note that this does NOT include the argv[0] which is in "
+     "target.arg0."},
+    {"env-vars", OptionValue::eTypeDictionary, false, OptionValue::eTypeString,
+     nullptr, nullptr, "A list of all the environment variables to be passed "
+                       "to the executable's environment, and their values."},
+    {"inherit-env", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
+     "Inherit the environment from the process that is running LLDB."},
+    {"input-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr,
+     "The file/path to be used by the executable program for reading its "
+     "standard input."},
+    {"output-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr,
+     "The file/path to be used by the executable program for writing its "
+     "standard output."},
+    {"error-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr,
+     "The file/path to be used by the executable program for writing its "
+     "standard error."},
+    {"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "debugserver will detach (rather than killing) a process if it "
+              "loses connection with lldb."},
+    {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
+     "Disable Address Space Layout Randomization (ASLR)"},
+    {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr,
+     "Disable stdin/stdout for process (e.g. for a GUI application)"},
+    {"inline-breakpoint-strategy", OptionValue::eTypeEnum, false,
+     eInlineBreakpointsAlways, nullptr, g_inline_breakpoint_enums,
+     "The strategy to use when settings breakpoints by file and line. "
+     "Breakpoint locations can end up being inlined by the compiler, so that a "
+     "compile unit 'a.c' might contain an inlined function from another source "
+     "file. "
+     "Usually this is limited to breakpoint locations from inlined functions "
+     "from header or other include files, or more accurately "
+     "non-implementation source files. "
+     "Sometimes code might #include implementation files and cause inlined "
+     "breakpoint locations in inlined implementation files. "
+     "Always checking for inlined breakpoint locations can be expensive "
+     "(memory and time), so if you have a project with many headers "
+     "and find that setting breakpoints is slow, then you can change this "
+     "setting to headers. "
+     "This setting allows you to control exactly which strategy is used when "
+     "setting "
+     "file and line breakpoints."},
+    // FIXME: This is the wrong way to do per-architecture settings, but we
+    // don't have a general per architecture settings system in place yet.
+    {"x86-disassembly-flavor", OptionValue::eTypeEnum, false,
+     eX86DisFlavorDefault, nullptr, g_x86_dis_flavor_value_types,
+     "The default disassembly flavor to use for x86 or x86-64 targets."},
+    {"use-hex-immediates", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Show immediates in disassembly as hexadecimal."},
+    {"hex-immediate-style", OptionValue::eTypeEnum, false,
+     Disassembler::eHexStyleC, nullptr, g_hex_immediate_style_values,
+     "Which style to use for printing hexadecimal disassembly values."},
+    {"use-fast-stepping", OptionValue::eTypeBoolean, false, true, nullptr,
+     nullptr, "Use a fast stepping algorithm based on running from branch to "
+              "branch rather than instruction single-stepping."},
+    {"load-script-from-symbol-file", OptionValue::eTypeEnum, false,
+     eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values,
+     "Allow LLDB to load scripting resources embedded in symbol files when "
+     "available."},
+    {"load-cwd-lldbinit", OptionValue::eTypeEnum, false, eLoadCWDlldbinitWarn,
+     nullptr, g_load_current_working_dir_lldbinit_values,
+     "Allow LLDB to .lldbinit files from the current directory automatically."},
+    {"memory-module-load-level", OptionValue::eTypeEnum, false,
+     eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values,
+     "Loading modules from memory can be slow as reading the symbol tables and "
+     "other data can take a long time depending on your connection to the "
+     "debug target. "
+     "This setting helps users control how much information gets loaded when "
+     "loading modules from memory."
+     "'complete' is the default value for this setting which will load all "
+     "sections and symbols by reading them from memory (slowest, most "
+     "accurate). "
+     "'partial' will load sections and attempt to find function bounds without "
+     "downloading the symbol table (faster, still accurate, missing symbol "
+     "names). "
+     "'minimal' is the fastest setting and will load section data with no "
+     "symbols, but should rarely be used as stack frames in these memory "
+     "regions will be inaccurate and not provide any context (fastest). "},
+    {"display-expression-in-crashlogs", OptionValue::eTypeBoolean, false, false,
+     nullptr, nullptr, "Expressions that crash will show up in crash logs if "
+                       "the host system supports executable specific crash log "
+                       "strings and this setting is set to true."},
+    {"trap-handler-names", OptionValue::eTypeArray, true,
+     OptionValue::eTypeString, nullptr, nullptr,
+     "A list of trap handler function names, e.g. a common Unix user process "
+     "one is _sigtramp."},
+    {"display-runtime-support-values", OptionValue::eTypeBoolean, false, false,
+     nullptr, nullptr, "If true, LLDB will show variables that are meant to "
+                       "support the operation of a language's runtime "
+                       "support."},
+    {"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, nullptr,
+     "Disable lock-step debugging, instead control threads independently."},
+    {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+
+enum {
+  ePropertyDefaultArch,
+  ePropertyMoveToNearestCode,
+  ePropertyLanguage,
+  ePropertyExprPrefix,
+  ePropertyPreferDynamic,
+  ePropertyEnableSynthetic,
+  ePropertySkipPrologue,
+  ePropertySourceMap,
+  ePropertyExecutableSearchPaths,
+  ePropertyDebugFileSearchPaths,
+  ePropertyClangModuleSearchPaths,
+  ePropertyAutoImportClangModules,
+  ePropertyAutoApplyFixIts,
+  ePropertyNotifyAboutFixIts,
+  ePropertyMaxChildrenCount,
+  ePropertyMaxSummaryLength,
+  ePropertyMaxMemReadSize,
+  ePropertyBreakpointUseAvoidList,
+  ePropertyArg0,
+  ePropertyRunArgs,
+  ePropertyEnvVars,
+  ePropertyInheritEnv,
+  ePropertyInputPath,
+  ePropertyOutputPath,
+  ePropertyErrorPath,
+  ePropertyDetachOnError,
+  ePropertyDisableASLR,
+  ePropertyDisableSTDIO,
+  ePropertyInlineStrategy,
+  ePropertyDisassemblyFlavor,
+  ePropertyUseHexImmediates,
+  ePropertyHexImmediateStyle,
+  ePropertyUseFastStepping,
+  ePropertyLoadScriptFromSymbolFile,
+  ePropertyLoadCWDlldbinitFile,
+  ePropertyMemoryModuleLoadLevel,
+  ePropertyDisplayExpressionsInCrashlogs,
+  ePropertyTrapHandlerNames,
+  ePropertyDisplayRuntimeSupportValues,
+  ePropertyNonStopModeEnabled,
+  ePropertyExperimental
 };
 
-static OptionEnumValueElement
-g_hex_immediate_style_values[] =
-{
-    { Disassembler::eHexStyleC,        "c",      "C-style (0xffff)."},
-    { Disassembler::eHexStyleAsm,      "asm",    "Asm-style (0ffffh)."},
-    { 0, nullptr, nullptr }
-};
-
-static OptionEnumValueElement
-g_load_script_from_sym_file_values[] =
-{
-    { eLoadScriptFromSymFileTrue,    "true",    "Load debug scripts inside symbol files"},
-    { eLoadScriptFromSymFileFalse,   "false",   "Do not load debug scripts inside symbol files."},
-    { eLoadScriptFromSymFileWarn,    "warn",    "Warn about debug scripts inside symbol files but do not load them."},
-    { 0, nullptr, nullptr }
-};
-
-static OptionEnumValueElement
-g_load_current_working_dir_lldbinit_values[] =
-{
-    { eLoadCWDlldbinitTrue,    "true",    "Load .lldbinit files from current directory"},
-    { eLoadCWDlldbinitFalse,   "false",   "Do not load .lldbinit files from current directory"},
-    { eLoadCWDlldbinitWarn,    "warn",    "Warn about loading .lldbinit files from current directory"},
-    { 0, nullptr, nullptr }
-};
-
-static OptionEnumValueElement
-g_memory_module_load_level_values[] =
-{
-    { eMemoryModuleLoadLevelMinimal,  "minimal" , "Load minimal information when loading modules from memory. Currently this setting loads sections only."},
-    { eMemoryModuleLoadLevelPartial,  "partial" , "Load partial information when loading modules from memory. Currently this setting loads sections and function bounds."},
-    { eMemoryModuleLoadLevelComplete, "complete", "Load complete information when loading modules from memory. Currently this setting loads sections and all symbols."},
-    { 0, nullptr, nullptr }
-};
-
-static PropertyDefinition
-g_properties[] =
-{
-    { "default-arch"                       , OptionValue::eTypeArch      , true , 0                         , nullptr, nullptr, "Default architecture to choose, when there's a choice." },
-    { "move-to-nearest-code"               , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Move breakpoints to nearest code." },
-    { "language"                           , OptionValue::eTypeLanguage  , false, eLanguageTypeUnknown      , nullptr, nullptr, "The language to use when interpreting expressions entered in commands." },
-    { "expr-prefix"                        , OptionValue::eTypeFileSpec  , false, 0                         , nullptr, nullptr, "Path to a file containing expressions to be prepended to all expressions." },
-    { "prefer-dynamic-value"               , OptionValue::eTypeEnum      , false, eDynamicDontRunTarget     , nullptr, g_dynamic_value_types, "Should printed values be shown as their dynamic value." },
-    { "enable-synthetic-value"             , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Should synthetic values be used by default whenever available." },
-    { "skip-prologue"                      , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Skip function prologues when setting breakpoints by name." },
-    { "source-map"                         , OptionValue::eTypePathMap   , false, 0                         , nullptr, nullptr, "Source path remappings are used to track the change of location between a source file when built, and "
-      "where it exists on the current system.  It consists of an array of duples, the first element of each duple is "
-      "some part (starting at the root) of the path to the file when it was built, "
-      "and the second is where the remainder of the original build hierarchy is rooted on the local system.  "
-      "Each element of the array is checked in order and the first one that results in a match wins." },
-    { "exec-search-paths"                  , OptionValue::eTypeFileSpecList, false, 0                       , nullptr, nullptr, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
-    { "debug-file-search-paths"            , OptionValue::eTypeFileSpecList, false, 0                       , nullptr, nullptr, "List of directories to be searched when locating debug symbol files." },
-    { "clang-module-search-paths"          , OptionValue::eTypeFileSpecList, false, 0                       , nullptr, nullptr, "List of directories to be searched when locating modules for Clang." },
-    { "auto-import-clang-modules"          , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Automatically load Clang modules referred to by the program." },
-    { "auto-apply-fixits"                  , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Automatically apply fix-it hints to expressions." },
-    { "notify-about-fixits"                , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Print the fixed expression text." },
-    { "max-children-count"                 , OptionValue::eTypeSInt64    , false, 256                       , nullptr, nullptr, "Maximum number of children to expand in any level of depth." },
-    { "max-string-summary-length"          , OptionValue::eTypeSInt64    , false, 1024                      , nullptr, nullptr, "Maximum number of characters to show when using %s in summary strings." },
-    { "max-memory-read-size"               , OptionValue::eTypeSInt64    , false, 1024                      , nullptr, nullptr, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
-    { "breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Consult the platform module avoid list when setting non-module specific breakpoints." },
-    { "arg0"                               , OptionValue::eTypeString    , false, 0                         , nullptr, nullptr, "The first argument passed to the program in the argument array which can be different from the executable itself." },
-    { "run-args"                           , OptionValue::eTypeArgs      , false, 0                         , nullptr, nullptr, "A list containing all the arguments to be passed to the executable when it is run. Note that this does NOT include the argv[0] which is in target.arg0." },
-    { "env-vars"                           , OptionValue::eTypeDictionary, false, OptionValue::eTypeString  , nullptr, nullptr, "A list of all the environment variables to be passed to the executable's environment, and their values." },
-    { "inherit-env"                        , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Inherit the environment from the process that is running LLDB." },
-    { "input-path"                         , OptionValue::eTypeFileSpec  , false, 0                         , nullptr, nullptr, "The file/path to be used by the executable program for reading its standard input." },
-    { "output-path"                        , OptionValue::eTypeFileSpec  , false, 0                         , nullptr, nullptr, "The file/path to be used by the executable program for writing its standard output." },
-    { "error-path"                         , OptionValue::eTypeFileSpec  , false, 0                         , nullptr, nullptr, "The file/path to be used by the executable program for writing its standard error." },
-    { "detach-on-error"                    , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "debugserver will detach (rather than killing) a process if it loses connection with lldb." },
-    { "disable-aslr"                       , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Disable Address Space Layout Randomization (ASLR)" },
-    { "disable-stdio"                      , OptionValue::eTypeBoolean   , false, false                     , nullptr, nullptr, "Disable stdin/stdout for process (e.g. for a GUI application)" },
-    { "inline-breakpoint-strategy"         , OptionValue::eTypeEnum      , false, eInlineBreakpointsAlways  , nullptr, g_inline_breakpoint_enums, "The strategy to use when settings breakpoints by file and line. "
-        "Breakpoint locations can end up being inlined by the compiler, so that a compile unit 'a.c' might contain an inlined function from another source file. "
-        "Usually this is limited to breakpoint locations from inlined functions from header or other include files, or more accurately non-implementation source files. "
-        "Sometimes code might #include implementation files and cause inlined breakpoint locations in inlined implementation files. "
-        "Always checking for inlined breakpoint locations can be expensive (memory and time), so if you have a project with many headers "
-        "and find that setting breakpoints is slow, then you can change this setting to headers. "
-        "This setting allows you to control exactly which strategy is used when setting "
-        "file and line breakpoints." },
-    // FIXME: This is the wrong way to do per-architecture settings, but we don't have a general per architecture settings system in place yet.
-    { "x86-disassembly-flavor"             , OptionValue::eTypeEnum      , false, eX86DisFlavorDefault,       nullptr, g_x86_dis_flavor_value_types, "The default disassembly flavor to use for x86 or x86-64 targets." },
-    { "use-hex-immediates"                 , OptionValue::eTypeBoolean   , false, true,                       nullptr, nullptr, "Show immediates in disassembly as hexadecimal." },
-    { "hex-immediate-style"                , OptionValue::eTypeEnum   ,    false, Disassembler::eHexStyleC,   nullptr, g_hex_immediate_style_values, "Which style to use for printing hexadecimal disassembly values." },
-    { "use-fast-stepping"                  , OptionValue::eTypeBoolean   , false, true,                       nullptr, nullptr, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." },
-    { "load-script-from-symbol-file"       , OptionValue::eTypeEnum   ,    false, eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." },
-    { "load-cwd-lldbinit"                  , OptionValue::eTypeEnum   ,    false, eLoadCWDlldbinitWarn,       nullptr, g_load_current_working_dir_lldbinit_values, "Allow LLDB to .lldbinit files from the current directory automatically." },
-    { "memory-module-load-level"           , OptionValue::eTypeEnum   ,    false, eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values,
-        "Loading modules from memory can be slow as reading the symbol tables and other data can take a long time depending on your connection to the debug target. "
-        "This setting helps users control how much information gets loaded when loading modules from memory."
-        "'complete' is the default value for this setting which will load all sections and symbols by reading them from memory (slowest, most accurate). "
-        "'partial' will load sections and attempt to find function bounds without downloading the symbol table (faster, still accurate, missing symbol names). "
-        "'minimal' is the fastest setting and will load section data with no symbols, but should rarely be used as stack frames in these memory regions will be inaccurate and not provide any context (fastest). " },
-    { "display-expression-in-crashlogs"    , OptionValue::eTypeBoolean   , false, false,                      nullptr, nullptr, "Expressions that crash will show up in crash logs if the host system supports executable specific crash log strings and this setting is set to true." },
-    { "trap-handler-names"                 , OptionValue::eTypeArray     , true,  OptionValue::eTypeString,   nullptr, nullptr, "A list of trap handler function names, e.g. a common Unix user process one is _sigtramp." },
-    { "display-runtime-support-values"     , OptionValue::eTypeBoolean   , false, false,                      nullptr, nullptr, "If true, LLDB will show variables that are meant to support the operation of a language's runtime support." },
-    { "non-stop-mode"                      , OptionValue::eTypeBoolean   , false, 0,                          nullptr, nullptr, "Disable lock-step debugging, instead control threads independently." },
-    { nullptr                                 , OptionValue::eTypeInvalid   , false, 0                         , nullptr, nullptr, nullptr }
-};
-
-enum
-{
-    ePropertyDefaultArch,
-    ePropertyMoveToNearestCode,
-    ePropertyLanguage,
-    ePropertyExprPrefix,
-    ePropertyPreferDynamic,
-    ePropertyEnableSynthetic,
-    ePropertySkipPrologue,
-    ePropertySourceMap,
-    ePropertyExecutableSearchPaths,
-    ePropertyDebugFileSearchPaths,
-    ePropertyClangModuleSearchPaths,
-    ePropertyAutoImportClangModules,
-    ePropertyAutoApplyFixIts,
-    ePropertyNotifyAboutFixIts,
-    ePropertyMaxChildrenCount,
-    ePropertyMaxSummaryLength,
-    ePropertyMaxMemReadSize,
-    ePropertyBreakpointUseAvoidList,
-    ePropertyArg0,
-    ePropertyRunArgs,
-    ePropertyEnvVars,
-    ePropertyInheritEnv,
-    ePropertyInputPath,
-    ePropertyOutputPath,
-    ePropertyErrorPath,
-    ePropertyDetachOnError,
-    ePropertyDisableASLR,
-    ePropertyDisableSTDIO,
-    ePropertyInlineStrategy,
-    ePropertyDisassemblyFlavor,
-    ePropertyUseHexImmediates,
-    ePropertyHexImmediateStyle,
-    ePropertyUseFastStepping,
-    ePropertyLoadScriptFromSymbolFile,
-    ePropertyLoadCWDlldbinitFile,
-    ePropertyMemoryModuleLoadLevel,
-    ePropertyDisplayExpressionsInCrashlogs,
-    ePropertyTrapHandlerNames,
-    ePropertyDisplayRuntimeSupportValues,
-    ePropertyNonStopModeEnabled,
-    ePropertyExperimental
-};
-
-class TargetOptionValueProperties : public OptionValueProperties
-{
+class TargetOptionValueProperties : public OptionValueProperties {
 public:
-    TargetOptionValueProperties (const ConstString &name) :
-        OptionValueProperties (name),
-        m_target(nullptr),
-        m_got_host_env (false)
-    {
-    }
+  TargetOptionValueProperties(const ConstString &name)
+      : OptionValueProperties(name), m_target(nullptr), m_got_host_env(false) {}
 
-    // This constructor is used when creating TargetOptionValueProperties when it
-    // is part of a new lldb_private::Target instance. It will copy all current
-    // global property values as needed
-    TargetOptionValueProperties (Target *target, const TargetPropertiesSP &target_properties_sp) :
-        OptionValueProperties(*target_properties_sp->GetValueProperties()),
-        m_target (target),
-        m_got_host_env (false)
-    {
-    }
+  // This constructor is used when creating TargetOptionValueProperties when it
+  // is part of a new lldb_private::Target instance. It will copy all current
+  // global property values as needed
+  TargetOptionValueProperties(Target *target,
+                              const TargetPropertiesSP &target_properties_sp)
+      : OptionValueProperties(*target_properties_sp->GetValueProperties()),
+        m_target(target), m_got_host_env(false) {}
 
-    const Property *
-    GetPropertyAtIndex(const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const override
-    {
-        // When getting the value for a key from the target options, we will always
-        // try and grab the setting from the current target if there is one. Else we just
-        // use the one from this instance.
-        if (idx == ePropertyEnvVars)
-            GetHostEnvironmentIfNeeded ();
-            
-        if (exe_ctx)
-        {
-            Target *target = exe_ctx->GetTargetPtr();
-            if (target)
-            {
-                TargetOptionValueProperties *target_properties = static_cast<TargetOptionValueProperties *>(target->GetValueProperties().get());
-                if (this != target_properties)
-                    return target_properties->ProtectedGetPropertyAtIndex (idx);
-            }
-        }
-        return ProtectedGetPropertyAtIndex (idx);
+  const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx,
+                                     bool will_modify,
+                                     uint32_t idx) const override {
+    // When getting the value for a key from the target options, we will always
+    // try and grab the setting from the current target if there is one. Else we
+    // just
+    // use the one from this instance.
+    if (idx == ePropertyEnvVars)
+      GetHostEnvironmentIfNeeded();
+
+    if (exe_ctx) {
+      Target *target = exe_ctx->GetTargetPtr();
+      if (target) {
+        TargetOptionValueProperties *target_properties =
+            static_cast<TargetOptionValueProperties *>(
+                target->GetValueProperties().get());
+        if (this != target_properties)
+          return target_properties->ProtectedGetPropertyAtIndex(idx);
+      }
     }
-    
-    lldb::TargetSP
-    GetTargetSP ()
-    {
-        return m_target->shared_from_this();
-    }
-    
+    return ProtectedGetPropertyAtIndex(idx);
+  }
+
+  lldb::TargetSP GetTargetSP() { return m_target->shared_from_this(); }
+
 protected:
-    void
-    GetHostEnvironmentIfNeeded () const
-    {
-        if (!m_got_host_env)
-        {
-            if (m_target)
-            {
-                m_got_host_env = true;
-                const uint32_t idx = ePropertyInheritEnv;
-                if (GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0))
-                {
-                    PlatformSP platform_sp (m_target->GetPlatform());
-                    if (platform_sp)
-                    {
-                        StringList env;
-                        if (platform_sp->GetEnvironment(env))
-                        {
-                            OptionValueDictionary *env_dict = GetPropertyAtIndexAsOptionValueDictionary(nullptr, ePropertyEnvVars);
-                            if (env_dict)
-                            {
-                                const bool can_replace = false;
-                                const size_t envc = env.GetSize();
-                                for (size_t idx=0; idx<envc; idx++)
-                                {
-                                    const char *env_entry = env.GetStringAtIndex (idx);
-                                    if (env_entry)
-                                    {
-                                        const char *equal_pos = ::strchr(env_entry, '=');
-                                        ConstString key;
-                                        // It is ok to have environment variables with no values
-                                        const char *value = nullptr;
-                                        if (equal_pos)
-                                        {
-                                            key.SetCStringWithLength(env_entry, equal_pos - env_entry);
-                                            if (equal_pos[1])
-                                                value = equal_pos + 1;
-                                        }
-                                        else
-                                        {
-                                            key.SetCString(env_entry);
-                                        }
-                                        // Don't allow existing keys to be replaced with ones we get from the platform environment
-                                        env_dict->SetValueForKey(key, OptionValueSP(new OptionValueString(value)), can_replace);
-                                    }
-                                }
-                            }
-                        }
+  void GetHostEnvironmentIfNeeded() const {
+    if (!m_got_host_env) {
+      if (m_target) {
+        m_got_host_env = true;
+        const uint32_t idx = ePropertyInheritEnv;
+        if (GetPropertyAtIndexAsBoolean(
+                nullptr, idx, g_properties[idx].default_uint_value != 0)) {
+          PlatformSP platform_sp(m_target->GetPlatform());
+          if (platform_sp) {
+            StringList env;
+            if (platform_sp->GetEnvironment(env)) {
+              OptionValueDictionary *env_dict =
+                  GetPropertyAtIndexAsOptionValueDictionary(nullptr,
+                                                            ePropertyEnvVars);
+              if (env_dict) {
+                const bool can_replace = false;
+                const size_t envc = env.GetSize();
+                for (size_t idx = 0; idx < envc; idx++) {
+                  const char *env_entry = env.GetStringAtIndex(idx);
+                  if (env_entry) {
+                    const char *equal_pos = ::strchr(env_entry, '=');
+                    ConstString key;
+                    // It is ok to have environment variables with no values
+                    const char *value = nullptr;
+                    if (equal_pos) {
+                      key.SetCStringWithLength(env_entry,
+                                               equal_pos - env_entry);
+                      if (equal_pos[1])
+                        value = equal_pos + 1;
+                    } else {
+                      key.SetCString(env_entry);
                     }
+                    // Don't allow existing keys to be replaced with ones we get
+                    // from the platform environment
+                    env_dict->SetValueForKey(
+                        key, OptionValueSP(new OptionValueString(value)),
+                        can_replace);
+                  }
                 }
+              }
             }
+          }
         }
+      }
     }
-    Target *m_target;
-    mutable bool m_got_host_env;
+  }
+  Target *m_target;
+  mutable bool m_got_host_env;
 };
 
 //----------------------------------------------------------------------
 // TargetProperties
 //----------------------------------------------------------------------
-static PropertyDefinition
-g_experimental_properties[] 
-{
-{   "inject-local-vars",        OptionValue::eTypeBoolean     , true, true, nullptr, nullptr, "If true, inject local variables explicitly into the expression text.  "
-                                                                                               "This will fix symbol resolution when there are name collisions between ivars and local variables.  "
-                                                                                               "But it can make expressions run much more slowly." },
-{   nullptr,                    OptionValue::eTypeInvalid     , true, 0    , nullptr, nullptr, nullptr }
-};
+static PropertyDefinition g_experimental_properties[]{
+    {"inject-local-vars", OptionValue::eTypeBoolean, true, true, nullptr,
+     nullptr,
+     "If true, inject local variables explicitly into the expression text.  "
+     "This will fix symbol resolution when there are name collisions between "
+     "ivars and local variables.  "
+     "But it can make expressions run much more slowly."},
+    {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
 
-enum
-{
-    ePropertyInjectLocalVars = 0
-};
+enum { ePropertyInjectLocalVars = 0 };
 
-class TargetExperimentalOptionValueProperties : public OptionValueProperties
-{
+class TargetExperimentalOptionValueProperties : public OptionValueProperties {
 public:
-    TargetExperimentalOptionValueProperties () :
-        OptionValueProperties (ConstString(Properties::GetExperimentalSettingsName()))
-    {
-    }
+  TargetExperimentalOptionValueProperties()
+      : OptionValueProperties(
+            ConstString(Properties::GetExperimentalSettingsName())) {}
 };
 
-TargetExperimentalProperties::TargetExperimentalProperties() :
-    Properties(OptionValuePropertiesSP(new TargetExperimentalOptionValueProperties()))
-{
-    m_collection_sp->Initialize(g_experimental_properties);
+TargetExperimentalProperties::TargetExperimentalProperties()
+    : Properties(OptionValuePropertiesSP(
+          new TargetExperimentalOptionValueProperties())) {
+  m_collection_sp->Initialize(g_experimental_properties);
 }
 
 //----------------------------------------------------------------------
 // TargetProperties
 //----------------------------------------------------------------------
-TargetProperties::TargetProperties (Target *target) :
-    Properties (),
-    m_launch_info ()
-{
-    if (target)
-    {
-        m_collection_sp.reset (new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
+TargetProperties::TargetProperties(Target *target)
+    : Properties(), m_launch_info() {
+  if (target) {
+    m_collection_sp.reset(
+        new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
 
-        // Set callbacks to update launch_info whenever "settins set" updated any of these properties
-        m_collection_sp->SetValueChangedCallback(ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyRunArgs, TargetProperties::RunArgsValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyEnvVars, TargetProperties::EnvVarsValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyInputPath, TargetProperties::InputPathValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyOutputPath, TargetProperties::OutputPathValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyErrorPath, TargetProperties::ErrorPathValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, TargetProperties::DetachOnErrorValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback, this);
-        m_collection_sp->SetValueChangedCallback(ePropertyDisableSTDIO, TargetProperties::DisableSTDIOValueChangedCallback, this);
+    // Set callbacks to update launch_info whenever "settins set" updated any of
+    // these properties
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyRunArgs, TargetProperties::RunArgsValueChangedCallback, this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyEnvVars, TargetProperties::EnvVarsValueChangedCallback, this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyInputPath, TargetProperties::InputPathValueChangedCallback,
+        this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyOutputPath, TargetProperties::OutputPathValueChangedCallback,
+        this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyErrorPath, TargetProperties::ErrorPathValueChangedCallback,
+        this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyDetachOnError,
+        TargetProperties::DetachOnErrorValueChangedCallback, this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback,
+        this);
+    m_collection_sp->SetValueChangedCallback(
+        ePropertyDisableSTDIO,
+        TargetProperties::DisableSTDIOValueChangedCallback, this);
 
-        m_experimental_properties_up.reset(new TargetExperimentalProperties());
-        m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
-                                         ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
-                                         true,
-                                         m_experimental_properties_up->GetValueProperties());
+    m_experimental_properties_up.reset(new TargetExperimentalProperties());
+    m_collection_sp->AppendProperty(
+        ConstString(Properties::GetExperimentalSettingsName()),
+        ConstString("Experimental settings - setting these won't produce "
+                    "errors if the setting is not present."),
+        true, m_experimental_properties_up->GetValueProperties());
 
-        // Update m_launch_info once it was created
-        Arg0ValueChangedCallback(this, nullptr);
-        RunArgsValueChangedCallback(this, nullptr);
-        //EnvVarsValueChangedCallback(this, nullptr); // FIXME: cause segfault in Target::GetPlatform()
-        InputPathValueChangedCallback(this, nullptr);
-        OutputPathValueChangedCallback(this, nullptr);
-        ErrorPathValueChangedCallback(this, nullptr);
-        DetachOnErrorValueChangedCallback(this, nullptr);
-        DisableASLRValueChangedCallback(this, nullptr);
-        DisableSTDIOValueChangedCallback(this, nullptr);
-    }
-    else
-    {
-        m_collection_sp.reset (new TargetOptionValueProperties(ConstString("target")));
-        m_collection_sp->Initialize(g_properties);
-        m_experimental_properties_up.reset(new TargetExperimentalProperties());
-        m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
-                                         ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
-                                         true,
-                                         m_experimental_properties_up->GetValueProperties());
-        m_collection_sp->AppendProperty(ConstString("process"),
-                                        ConstString("Settings specific to processes."),
-                                        true,
-                                        Process::GetGlobalProperties()->GetValueProperties());
-    }
+    // Update m_launch_info once it was created
+    Arg0ValueChangedCallback(this, nullptr);
+    RunArgsValueChangedCallback(this, nullptr);
+    // EnvVarsValueChangedCallback(this, nullptr); // FIXME: cause segfault in
+    // Target::GetPlatform()
+    InputPathValueChangedCallback(this, nullptr);
+    OutputPathValueChangedCallback(this, nullptr);
+    ErrorPathValueChangedCallback(this, nullptr);
+    DetachOnErrorValueChangedCallback(this, nullptr);
+    DisableASLRValueChangedCallback(this, nullptr);
+    DisableSTDIOValueChangedCallback(this, nullptr);
+  } else {
+    m_collection_sp.reset(
+        new TargetOptionValueProperties(ConstString("target")));
+    m_collection_sp->Initialize(g_properties);
+    m_experimental_properties_up.reset(new TargetExperimentalProperties());
+    m_collection_sp->AppendProperty(
+        ConstString(Properties::GetExperimentalSettingsName()),
+        ConstString("Experimental settings - setting these won't produce "
+                    "errors if the setting is not present."),
+        true, m_experimental_properties_up->GetValueProperties());
+    m_collection_sp->AppendProperty(
+        ConstString("process"), ConstString("Settings specific to processes."),
+        true, Process::GetGlobalProperties()->GetValueProperties());
+  }
 }
 
 TargetProperties::~TargetProperties() = default;
 
-bool
-TargetProperties::GetInjectLocalVariables(ExecutionContext *exe_ctx) const
-{
-    const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, false, ePropertyExperimental);
-    OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
-    if (exp_values)
-        return exp_values->GetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
-    else
-        return true;
+bool TargetProperties::GetInjectLocalVariables(
+    ExecutionContext *exe_ctx) const {
+  const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
+      exe_ctx, false, ePropertyExperimental);
+  OptionValueProperties *exp_values =
+      exp_property->GetValue()->GetAsProperties();
+  if (exp_values)
+    return exp_values->GetPropertyAtIndexAsBoolean(
+        exe_ctx, ePropertyInjectLocalVars, true);
+  else
+    return true;
 }
 
-void
-TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b)
-{
-    const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental);
-    OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
-    if (exp_values)
-        exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
+void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx,
+                                               bool b) {
+  const Property *exp_property =
+      m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental);
+  OptionValueProperties *exp_values =
+      exp_property->GetValue()->GetAsProperties();
+  if (exp_values)
+    exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars,
+                                            true);
 }
 
-ArchSpec
-TargetProperties::GetDefaultArchitecture () const
-{
-    OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(nullptr, ePropertyDefaultArch);
-    if (value)
-        return value->GetCurrentValue();
-    return ArchSpec();
+ArchSpec TargetProperties::GetDefaultArchitecture() const {
+  OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
+      nullptr, ePropertyDefaultArch);
+  if (value)
+    return value->GetCurrentValue();
+  return ArchSpec();
 }
 
-void
-TargetProperties::SetDefaultArchitecture (const ArchSpec& arch)
-{
-    OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(nullptr, ePropertyDefaultArch);
-    if (value)
-        return value->SetCurrentValue(arch, true);
+void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {
+  OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
+      nullptr, ePropertyDefaultArch);
+  if (value)
+    return value->SetCurrentValue(arch, true);
 }
 
-bool
-TargetProperties::GetMoveToNearestCode() const
-{
-    const uint32_t idx = ePropertyMoveToNearestCode;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetMoveToNearestCode() const {
+  const uint32_t idx = ePropertyMoveToNearestCode;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-lldb::DynamicValueType
-TargetProperties::GetPreferDynamicValue() const
-{
-    const uint32_t idx = ePropertyPreferDynamic;
-    return (lldb::DynamicValueType)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {
+  const uint32_t idx = ePropertyPreferDynamic;
+  return (lldb::DynamicValueType)
+      m_collection_sp->GetPropertyAtIndexAsEnumeration(
+          nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-bool
-TargetProperties::SetPreferDynamicValue (lldb::DynamicValueType d)
-{
-    const uint32_t idx = ePropertyPreferDynamic;
-    return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
+bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
+  const uint32_t idx = ePropertyPreferDynamic;
+  return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
 }
 
-bool
-TargetProperties::GetDisableASLR () const
-{
-    const uint32_t idx = ePropertyDisableASLR;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetDisableASLR() const {
+  const uint32_t idx = ePropertyDisableASLR;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-void
-TargetProperties::SetDisableASLR (bool b)
-{
-    const uint32_t idx = ePropertyDisableASLR;
-    m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+void TargetProperties::SetDisableASLR(bool b) {
+  const uint32_t idx = ePropertyDisableASLR;
+  m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
 }
 
-bool
-TargetProperties::GetDetachOnError () const
-{
-    const uint32_t idx = ePropertyDetachOnError;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetDetachOnError() const {
+  const uint32_t idx = ePropertyDetachOnError;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-void
-TargetProperties::SetDetachOnError (bool b)
-{
-    const uint32_t idx = ePropertyDetachOnError;
-    m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+void TargetProperties::SetDetachOnError(bool b) {
+  const uint32_t idx = ePropertyDetachOnError;
+  m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
 }
 
-bool
-TargetProperties::GetDisableSTDIO () const
-{
-    const uint32_t idx = ePropertyDisableSTDIO;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetDisableSTDIO() const {
+  const uint32_t idx = ePropertyDisableSTDIO;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-void
-TargetProperties::SetDisableSTDIO (bool b)
-{
-    const uint32_t idx = ePropertyDisableSTDIO;
-    m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+void TargetProperties::SetDisableSTDIO(bool b) {
+  const uint32_t idx = ePropertyDisableSTDIO;
+  m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
 }
 
+const char *TargetProperties::GetDisassemblyFlavor() const {
+  const uint32_t idx = ePropertyDisassemblyFlavor;
+  const char *return_value;
+
-const char *
-TargetProperties::GetDisassemblyFlavor () const
-{
-    const uint32_t idx = ePropertyDisassemblyFlavor;
-    const char *return_value;
-    
-    x86DisassemblyFlavor flavor_value = (x86DisassemblyFlavor) m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
-    return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
-    return return_value;
+  x86DisassemblyFlavor flavor_value =
+      (x86DisassemblyFlavor)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+          nullptr, idx, g_properties[idx].default_uint_value);
+  return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
+  return return_value;
 }
 
-InlineStrategy
-TargetProperties::GetInlineStrategy () const
-{
-    const uint32_t idx = ePropertyInlineStrategy;
-    return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+InlineStrategy TargetProperties::GetInlineStrategy() const {
+  const uint32_t idx = ePropertyInlineStrategy;
+  return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+      nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-const char *
-TargetProperties::GetArg0 () const
-{
-    const uint32_t idx = ePropertyArg0;
-    return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, nullptr);
+const char *TargetProperties::GetArg0() const {
+  const uint32_t idx = ePropertyArg0;
+  return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, nullptr);
 }
 
-void
-TargetProperties::SetArg0 (const char *arg)
-{
-    const uint32_t idx = ePropertyArg0;
-    m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, arg);
-    m_launch_info.SetArg0(arg);
+void TargetProperties::SetArg0(const char *arg) {
+  const uint32_t idx = ePropertyArg0;
+  m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, arg);
+  m_launch_info.SetArg0(arg);
 }
 
-bool
-TargetProperties::GetRunArguments (Args &args) const
-{
-    const uint32_t idx = ePropertyRunArgs;
-    return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
+bool TargetProperties::GetRunArguments(Args &args) const {
+  const uint32_t idx = ePropertyRunArgs;
+  return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
 }
 
-void
-TargetProperties::SetRunArguments (const Args &args)
-{
-    const uint32_t idx = ePropertyRunArgs;
-    m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
-    m_launch_info.GetArguments() = args;
+void TargetProperties::SetRunArguments(const Args &args) {
+  const uint32_t idx = ePropertyRunArgs;
+  m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
+  m_launch_info.GetArguments() = args;
 }
 
-size_t
-TargetProperties::GetEnvironmentAsArgs (Args &env) const
-{
-    const uint32_t idx = ePropertyEnvVars;
-    return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env);
+size_t TargetProperties::GetEnvironmentAsArgs(Args &env) const {
+  const uint32_t idx = ePropertyEnvVars;
+  return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env);
 }
 
-void
-TargetProperties::SetEnvironmentFromArgs (const Args &env)
-{
-    const uint32_t idx = ePropertyEnvVars;
-    m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, env);
-    m_launch_info.GetEnvironmentEntries() = env;
+void TargetProperties::SetEnvironmentFromArgs(const Args &env) {
+  const uint32_t idx = ePropertyEnvVars;
+  m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, env);
+  m_launch_info.GetEnvironmentEntries() = env;
 }
 
-bool
-TargetProperties::GetSkipPrologue() const
-{
-    const uint32_t idx = ePropertySkipPrologue;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetSkipPrologue() const {
+  const uint32_t idx = ePropertySkipPrologue;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-PathMappingList &
-TargetProperties::GetSourcePathMap () const
-{
-    const uint32_t idx = ePropertySourceMap;
-    OptionValuePathMappings *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(nullptr, false, idx);
-    assert(option_value);
-    return option_value->GetCurrentValue();
+PathMappingList &TargetProperties::GetSourcePathMap() const {
+  const uint32_t idx = ePropertySourceMap;
+  OptionValuePathMappings *option_value =
+      m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(nullptr,
+                                                                   false, idx);
+  assert(option_value);
+  return option_value->GetCurrentValue();
 }
 
-FileSpecList &
-TargetProperties::GetExecutableSearchPaths ()
-{
-    const uint32_t idx = ePropertyExecutableSearchPaths;
-    OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx);
-    assert(option_value);
-    return option_value->GetCurrentValue();
+FileSpecList &TargetProperties::GetExecutableSearchPaths() {
+  const uint32_t idx = ePropertyExecutableSearchPaths;
+  OptionValueFileSpecList *option_value =
+      m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
+                                                                   false, idx);
+  assert(option_value);
+  return option_value->GetCurrentValue();
 }
 
-FileSpecList &
-TargetProperties::GetDebugFileSearchPaths ()
-{
-    const uint32_t idx = ePropertyDebugFileSearchPaths;
-    OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx);
-    assert(option_value);
-    return option_value->GetCurrentValue();
+FileSpecList &TargetProperties::GetDebugFileSearchPaths() {
+  const uint32_t idx = ePropertyDebugFileSearchPaths;
+  OptionValueFileSpecList *option_value =
+      m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
+                                                                   false, idx);
+  assert(option_value);
+  return option_value->GetCurrentValue();
 }
 
-FileSpecList &
-TargetProperties::GetClangModuleSearchPaths ()
-{
-    const uint32_t idx = ePropertyClangModuleSearchPaths;
-    OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx);
-    assert(option_value);
-    return option_value->GetCurrentValue();
+FileSpecList &TargetProperties::GetClangModuleSearchPaths() {
+  const uint32_t idx = ePropertyClangModuleSearchPaths;
+  OptionValueFileSpecList *option_value =
+      m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
+                                                                   false, idx);
+  assert(option_value);
+  return option_value->GetCurrentValue();
 }
 
-bool
-TargetProperties::GetEnableAutoImportClangModules() const
-{
-    const uint32_t idx = ePropertyAutoImportClangModules;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetEnableAutoImportClangModules() const {
+  const uint32_t idx = ePropertyAutoImportClangModules;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetEnableAutoApplyFixIts() const
-{
-    const uint32_t idx = ePropertyAutoApplyFixIts;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetEnableAutoApplyFixIts() const {
+  const uint32_t idx = ePropertyAutoApplyFixIts;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetEnableNotifyAboutFixIts() const
-{
-    const uint32_t idx = ePropertyNotifyAboutFixIts;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetEnableNotifyAboutFixIts() const {
+  const uint32_t idx = ePropertyNotifyAboutFixIts;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetEnableSyntheticValue () const
-{
-    const uint32_t idx = ePropertyEnableSynthetic;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetEnableSyntheticValue() const {
+  const uint32_t idx = ePropertyEnableSynthetic;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-uint32_t
-TargetProperties::GetMaximumNumberOfChildrenToDisplay() const
-{
-    const uint32_t idx = ePropertyMaxChildrenCount;
-    return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
+  const uint32_t idx = ePropertyMaxChildrenCount;
+  return m_collection_sp->GetPropertyAtIndexAsSInt64(
+      nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-uint32_t
-TargetProperties::GetMaximumSizeOfStringSummary() const
-{
-    const uint32_t idx = ePropertyMaxSummaryLength;
-    return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
+  const uint32_t idx = ePropertyMaxSummaryLength;
+  return m_collection_sp->GetPropertyAtIndexAsSInt64(
+      nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-uint32_t
-TargetProperties::GetMaximumMemReadSize () const
-{
-    const uint32_t idx = ePropertyMaxMemReadSize;
-    return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+uint32_t TargetProperties::GetMaximumMemReadSize() const {
+  const uint32_t idx = ePropertyMaxMemReadSize;
+  return m_collection_sp->GetPropertyAtIndexAsSInt64(
+      nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-FileSpec
-TargetProperties::GetStandardInputPath () const
-{
-    const uint32_t idx = ePropertyInputPath;
-    return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
+FileSpec TargetProperties::GetStandardInputPath() const {
+  const uint32_t idx = ePropertyInputPath;
+  return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
 }
 
-void
-TargetProperties::SetStandardInputPath (const char *p)
-{
-    const uint32_t idx = ePropertyInputPath;
-    m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
+void TargetProperties::SetStandardInputPath(const char *p) {
+  const uint32_t idx = ePropertyInputPath;
+  m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
 }
 
-FileSpec
-TargetProperties::GetStandardOutputPath () const
-{
-    const uint32_t idx = ePropertyOutputPath;
-    return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
+FileSpec TargetProperties::GetStandardOutputPath() const {
+  const uint32_t idx = ePropertyOutputPath;
+  return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
 }
 
-void
-TargetProperties::SetStandardOutputPath (const char *p)
-{
-    const uint32_t idx = ePropertyOutputPath;
-    m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
+void TargetProperties::SetStandardOutputPath(const char *p) {
+  const uint32_t idx = ePropertyOutputPath;
+  m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
 }
 
-FileSpec
-TargetProperties::GetStandardErrorPath () const
-{
-    const uint32_t idx = ePropertyErrorPath;
-    return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
+FileSpec TargetProperties::GetStandardErrorPath() const {
+  const uint32_t idx = ePropertyErrorPath;
+  return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
 }
 
-LanguageType
-TargetProperties::GetLanguage () const
-{
-    OptionValueLanguage *value = m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(nullptr, ePropertyLanguage);
-    if (value)
-        return value->GetCurrentValue();
-    return LanguageType();
+LanguageType TargetProperties::GetLanguage() const {
+  OptionValueLanguage *value =
+      m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(
+          nullptr, ePropertyLanguage);
+  if (value)
+    return value->GetCurrentValue();
+  return LanguageType();
 }
 
-const char *
-TargetProperties::GetExpressionPrefixContentsAsCString ()
-{
-    const uint32_t idx = ePropertyExprPrefix;
-    OptionValueFileSpec *file = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, idx);
-    if (file)
-    {
-        const bool null_terminate = true;
-        DataBufferSP data_sp(file->GetFileContents(null_terminate));
-        if (data_sp)
-            return (const char *) data_sp->GetBytes();
-    }
-    return nullptr;
+const char *TargetProperties::GetExpressionPrefixContentsAsCString() {
+  const uint32_t idx = ePropertyExprPrefix;
+  OptionValueFileSpec *file =
+      m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
+                                                               idx);
+  if (file) {
+    const bool null_terminate = true;
+    DataBufferSP data_sp(file->GetFileContents(null_terminate));
+    if (data_sp)
+      return (const char *)data_sp->GetBytes();
+  }
+  return nullptr;
 }
 
-void
-TargetProperties::SetStandardErrorPath (const char *p)
-{
-    const uint32_t idx = ePropertyErrorPath;
-    m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
+void TargetProperties::SetStandardErrorPath(const char *p) {
+  const uint32_t idx = ePropertyErrorPath;
+  m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
 }
 
-bool
-TargetProperties::GetBreakpointsConsultPlatformAvoidList ()
-{
-    const uint32_t idx = ePropertyBreakpointUseAvoidList;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
+  const uint32_t idx = ePropertyBreakpointUseAvoidList;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetUseHexImmediates () const
-{
-    const uint32_t idx = ePropertyUseHexImmediates;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetUseHexImmediates() const {
+  const uint32_t idx = ePropertyUseHexImmediates;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetUseFastStepping () const
-{
-    const uint32_t idx = ePropertyUseFastStepping;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetUseFastStepping() const {
+  const uint32_t idx = ePropertyUseFastStepping;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetDisplayExpressionsInCrashlogs () const
-{
-    const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {
+  const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_properties[idx].default_uint_value != 0);
 }
 
-LoadScriptFromSymFile
-TargetProperties::GetLoadScriptFromSymbolFile () const
-{
-    const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
-    return (LoadScriptFromSymFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {
+  const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
+  return (LoadScriptFromSymFile)
+      m_collection_sp->GetPropertyAtIndexAsEnumeration(
+          nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-LoadCWDlldbinitFile
-TargetProperties::GetLoadCWDlldbinitFile () const
-{
-    const uint32_t idx = ePropertyLoadCWDlldbinitFile;
-    return (LoadCWDlldbinitFile) m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {
+  const uint32_t idx = ePropertyLoadCWDlldbinitFile;
+  return (LoadCWDlldbinitFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+      nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-Disassembler::HexImmediateStyle
-TargetProperties::GetHexImmediateStyle () const
-{
-    const uint32_t idx = ePropertyHexImmediateStyle;
-    return (Disassembler::HexImmediateStyle)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {
+  const uint32_t idx = ePropertyHexImmediateStyle;
+  return (Disassembler::HexImmediateStyle)
+      m_collection_sp->GetPropertyAtIndexAsEnumeration(
+          nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-MemoryModuleLoadLevel
-TargetProperties::GetMemoryModuleLoadLevel() const
-{
-    const uint32_t idx = ePropertyMemoryModuleLoadLevel;
-    return (MemoryModuleLoadLevel)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {
+  const uint32_t idx = ePropertyMemoryModuleLoadLevel;
+  return (MemoryModuleLoadLevel)
+      m_collection_sp->GetPropertyAtIndexAsEnumeration(
+          nullptr, idx, g_properties[idx].default_uint_value);
 }
 
-bool
-TargetProperties::GetUserSpecifiedTrapHandlerNames (Args &args) const
-{
-    const uint32_t idx = ePropertyTrapHandlerNames;
-    return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
+bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {
+  const uint32_t idx = ePropertyTrapHandlerNames;
+  return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
 }
 
-void
-TargetProperties::SetUserSpecifiedTrapHandlerNames (const Args &args)
-{
-    const uint32_t idx = ePropertyTrapHandlerNames;
-    m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
+void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) {
+  const uint32_t idx = ePropertyTrapHandlerNames;
+  m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
 }
 
-bool
-TargetProperties::GetDisplayRuntimeSupportValues () const
-{
-    const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
+bool TargetProperties::GetDisplayRuntimeSupportValues() const {
+  const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
 }
 
-void
-TargetProperties::SetDisplayRuntimeSupportValues (bool b)
-{
-    const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
-    m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+void TargetProperties::SetDisplayRuntimeSupportValues(bool b) {
+  const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
+  m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
 }
 
-bool
-TargetProperties::GetNonStopModeEnabled () const
-{
-    const uint32_t idx = ePropertyNonStopModeEnabled;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
+bool TargetProperties::GetNonStopModeEnabled() const {
+  const uint32_t idx = ePropertyNonStopModeEnabled;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
 }
 
-void
-TargetProperties::SetNonStopModeEnabled (bool b)
-{
-    const uint32_t idx = ePropertyNonStopModeEnabled;
-    m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+void TargetProperties::SetNonStopModeEnabled(bool b) {
+  const uint32_t idx = ePropertyNonStopModeEnabled;
+  m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
 }
 
-const ProcessLaunchInfo &
-TargetProperties::GetProcessLaunchInfo ()
-{
-    m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work
-    return m_launch_info;
+const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() {
+  m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work
+  return m_launch_info;
 }
 
-void
-TargetProperties::SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info)
-{
-    m_launch_info = launch_info;
-    SetArg0(launch_info.GetArg0());
-    SetRunArguments(launch_info.GetArguments());
-    SetEnvironmentFromArgs(launch_info.GetEnvironmentEntries());
-    const FileAction *input_file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
-    if (input_file_action)
-    {
-        const char *input_path = input_file_action->GetPath();
-        if (input_path)
-            SetStandardInputPath(input_path);
-    }
-    const FileAction *output_file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
-    if (output_file_action)
-    {
-        const char *output_path = output_file_action->GetPath();
-        if (output_path)
-            SetStandardOutputPath(output_path);
-    }
-    const FileAction *error_file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
-    if (error_file_action)
-    {
-        const char *error_path = error_file_action->GetPath();
-        if (error_path)
-            SetStandardErrorPath(error_path);
-    }
-    SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
-    SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
-    SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
+void TargetProperties::SetProcessLaunchInfo(
+    const ProcessLaunchInfo &launch_info) {
+  m_launch_info = launch_info;
+  SetArg0(launch_info.GetArg0());
+  SetRunArguments(launch_info.GetArguments());
+  SetEnvironmentFromArgs(launch_info.GetEnvironmentEntries());
+  const FileAction *input_file_action =
+      launch_info.GetFileActionForFD(STDIN_FILENO);
+  if (input_file_action) {
+    const char *input_path = input_file_action->GetPath();
+    if (input_path)
+      SetStandardInputPath(input_path);
+  }
+  const FileAction *output_file_action =
+      launch_info.GetFileActionForFD(STDOUT_FILENO);
+  if (output_file_action) {
+    const char *output_path = output_file_action->GetPath();
+    if (output_path)
+      SetStandardOutputPath(output_path);
+  }
+  const FileAction *error_file_action =
+      launch_info.GetFileActionForFD(STDERR_FILENO);
+  if (error_file_action) {
+    const char *error_path = error_file_action->GetPath();
+    if (error_path)
+      SetStandardErrorPath(error_path);
+  }
+  SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
+  SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
+  SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
 }
 
-void
-TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    this_->m_launch_info.SetArg0(this_->GetArg0());
+void TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr,
+                                                OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  this_->m_launch_info.SetArg0(this_->GetArg0());
 }
 
-void
-TargetProperties::RunArgsValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    Args args;
-    if (this_->GetRunArguments(args))
-        this_->m_launch_info.GetArguments() = args;
+void TargetProperties::RunArgsValueChangedCallback(void *target_property_ptr,
+                                                   OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  Args args;
+  if (this_->GetRunArguments(args))
+    this_->m_launch_info.GetArguments() = args;
 }
 
-void
-TargetProperties::EnvVarsValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    Args args;
-    if (this_->GetEnvironmentAsArgs(args))
-        this_->m_launch_info.GetEnvironmentEntries() = args;
+void TargetProperties::EnvVarsValueChangedCallback(void *target_property_ptr,
+                                                   OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  Args args;
+  if (this_->GetEnvironmentAsArgs(args))
+    this_->m_launch_info.GetEnvironmentEntries() = args;
 }
 
-void
-TargetProperties::InputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    this_->m_launch_info.AppendOpenFileAction(STDIN_FILENO, this_->GetStandardInputPath(), true, false);
+void TargetProperties::InputPathValueChangedCallback(void *target_property_ptr,
+                                                     OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  this_->m_launch_info.AppendOpenFileAction(
+      STDIN_FILENO, this_->GetStandardInputPath(), true, false);
 }
 
-void
-TargetProperties::OutputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    this_->m_launch_info.AppendOpenFileAction(STDOUT_FILENO, this_->GetStandardOutputPath(), false, true);
+void TargetProperties::OutputPathValueChangedCallback(void *target_property_ptr,
+                                                      OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  this_->m_launch_info.AppendOpenFileAction(
+      STDOUT_FILENO, this_->GetStandardOutputPath(), false, true);
 }
 
-void
-TargetProperties::ErrorPathValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    this_->m_launch_info.AppendOpenFileAction(STDERR_FILENO, this_->GetStandardErrorPath(), false, true);
+void TargetProperties::ErrorPathValueChangedCallback(void *target_property_ptr,
+                                                     OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  this_->m_launch_info.AppendOpenFileAction(
+      STDERR_FILENO, this_->GetStandardErrorPath(), false, true);
 }
 
-void
-TargetProperties::DetachOnErrorValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    if (this_->GetDetachOnError())
-        this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);
-    else
-        this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);
+void TargetProperties::DetachOnErrorValueChangedCallback(
+    void *target_property_ptr, OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  if (this_->GetDetachOnError())
+    this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);
+  else
+    this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);
 }
 
-void
-TargetProperties::DisableASLRValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    if (this_->GetDisableASLR())
-        this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);
-    else
-        this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);
+void TargetProperties::DisableASLRValueChangedCallback(
+    void *target_property_ptr, OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  if (this_->GetDisableASLR())
+    this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);
+  else
+    this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);
 }
 
-void
-TargetProperties::DisableSTDIOValueChangedCallback(void *target_property_ptr, OptionValue *)
-{
-    TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
-    if (this_->GetDisableSTDIO())
-        this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
-    else
-        this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);
+void TargetProperties::DisableSTDIOValueChangedCallback(
+    void *target_property_ptr, OptionValue *) {
+  TargetProperties *this_ =
+      reinterpret_cast<TargetProperties *>(target_property_ptr);
+  if (this_->GetDisableSTDIO())
+    this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
+  else
+    this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);
 }
 
 //----------------------------------------------------------------------
 // Target::TargetEventData
 //----------------------------------------------------------------------
 
-Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp) :
-    EventData (),
-    m_target_sp (target_sp),
-    m_module_list ()
-{
-}
+Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)
+    : EventData(), m_target_sp(target_sp), m_module_list() {}
 
-Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp, const ModuleList &module_list) :
-    EventData (),
-    m_target_sp (target_sp),
-    m_module_list (module_list)
-{
-}
+Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,
+                                         const ModuleList &module_list)
+    : EventData(), m_target_sp(target_sp), m_module_list(module_list) {}
 
 Target::TargetEventData::~TargetEventData() = default;
 
-const ConstString &
-Target::TargetEventData::GetFlavorString ()
-{
-    static ConstString g_flavor ("Target::TargetEventData");
-    return g_flavor;
+const ConstString &Target::TargetEventData::GetFlavorString() {
+  static ConstString g_flavor("Target::TargetEventData");
+  return g_flavor;
 }
 
-void
-Target::TargetEventData::Dump (Stream *s) const
-{
-    for (size_t i = 0; i < m_module_list.GetSize(); ++i)
-    {
-        if (i != 0)
-             *s << ", ";
-        m_module_list.GetModuleAtIndex(i)->GetDescription(s, lldb::eDescriptionLevelBrief);
-    }
+void Target::TargetEventData::Dump(Stream *s) const {
+  for (size_t i = 0; i < m_module_list.GetSize(); ++i) {
+    if (i != 0)
+      *s << ", ";
+    m_module_list.GetModuleAtIndex(i)->GetDescription(
+        s, lldb::eDescriptionLevelBrief);
+  }
 }
 
 const Target::TargetEventData *
-Target::TargetEventData::GetEventDataFromEvent (const Event *event_ptr)
-{
-    if (event_ptr)
-    {
-        const EventData *event_data = event_ptr->GetData();
-        if (event_data && event_data->GetFlavor() == TargetEventData::GetFlavorString())
-            return static_cast <const TargetEventData *> (event_ptr->GetData());
-    }
-    return nullptr;
+Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) {
+  if (event_ptr) {
+    const EventData *event_data = event_ptr->GetData();
+    if (event_data &&
+        event_data->GetFlavor() == TargetEventData::GetFlavorString())
+      return static_cast<const TargetEventData *>(event_ptr->GetData());
+  }
+  return nullptr;
 }
 
-TargetSP
-Target::TargetEventData::GetTargetFromEvent (const Event *event_ptr)
-{
-    TargetSP target_sp;
-    const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
-    if (event_data)
-        target_sp = event_data->m_target_sp;
-    return target_sp;
+TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {
+  TargetSP target_sp;
+  const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
+  if (event_data)
+    target_sp = event_data->m_target_sp;
+  return target_sp;
 }
 
 ModuleList
-Target::TargetEventData::GetModuleListFromEvent (const Event *event_ptr)
-{
-    ModuleList module_list;
-    const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
-    if (event_data)
-        module_list = event_data->m_module_list;
-    return module_list;
+Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
+  ModuleList module_list;
+  const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
+  if (event_data)
+    module_list = event_data->m_module_list;
+  return module_list;
 }
