diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp
index e3fcbaa..892d646 100644
--- a/lldb/source/Target/ThreadPlanTracer.cpp
+++ b/lldb/source/Target/ThreadPlanTracer.cpp
@@ -13,7 +13,6 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Target/ThreadPlan.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
@@ -27,244 +26,206 @@
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Target/ABI.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
 #pragma mark ThreadPlanTracer
 
-ThreadPlanTracer::ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp) :
-    m_thread (thread),
-    m_single_step(true),
-    m_enabled (false),
-    m_stream_sp (stream_sp)
-{
+ThreadPlanTracer::ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp)
+    : m_thread(thread), m_single_step(true), m_enabled(false),
+      m_stream_sp(stream_sp) {}
+
+ThreadPlanTracer::ThreadPlanTracer(Thread &thread)
+    : m_thread(thread), m_single_step(true), m_enabled(false), m_stream_sp() {}
+
+Stream *ThreadPlanTracer::GetLogStream() {
+  if (m_stream_sp)
+    return m_stream_sp.get();
+  else {
+    TargetSP target_sp(m_thread.CalculateTarget());
+    if (target_sp)
+      return target_sp->GetDebugger().GetOutputFile().get();
+  }
+  return nullptr;
 }
 
-ThreadPlanTracer::ThreadPlanTracer (Thread &thread) :
-    m_thread (thread),
-    m_single_step(true),
-    m_enabled (false),
-    m_stream_sp ()
-{
+void ThreadPlanTracer::Log() {
+  SymbolContext sc;
+  bool show_frame_index = false;
+  bool show_fullpaths = false;
+
+  Stream *stream = GetLogStream();
+  if (stream) {
+    m_thread.GetStackFrameAtIndex(0)->Dump(stream, show_frame_index,
+                                           show_fullpaths);
+    stream->Printf("\n");
+    stream->Flush();
+  }
 }
 
-Stream *
-ThreadPlanTracer::GetLogStream ()
-{
-    if (m_stream_sp)
-        return m_stream_sp.get();
-    else
-    {
-        TargetSP target_sp (m_thread.CalculateTarget());
-        if (target_sp)
-            return target_sp->GetDebugger().GetOutputFile().get();
-    }
-    return nullptr;
-}
-
-void 
-ThreadPlanTracer::Log()
-{
-    SymbolContext sc;
-    bool show_frame_index = false;
-    bool show_fullpaths = false;
-    
-    Stream *stream = GetLogStream();
-    if (stream)
-    {
-        m_thread.GetStackFrameAtIndex(0)->Dump (stream, show_frame_index, show_fullpaths);
-        stream->Printf("\n");
-        stream->Flush();
-    }
-}
-
-bool
-ThreadPlanTracer::TracerExplainsStop ()
-{
-    if (m_enabled && m_single_step)
-    {
-        lldb::StopInfoSP stop_info = m_thread.GetStopInfo();
-        return (stop_info->GetStopReason() == eStopReasonTrace);
-    }
-    else
-        return false;
+bool ThreadPlanTracer::TracerExplainsStop() {
+  if (m_enabled && m_single_step) {
+    lldb::StopInfoSP stop_info = m_thread.GetStopInfo();
+    return (stop_info->GetStopReason() == eStopReasonTrace);
+  } else
+    return false;
 }
 
 #pragma mark ThreadPlanAssemblyTracer
 
-ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp) :
-    ThreadPlanTracer (thread, stream_sp),
-    m_disassembler_sp (),
-    m_intptr_type (),
-    m_register_values ()
-{
+ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer(Thread &thread,
+                                                   lldb::StreamSP &stream_sp)
+    : ThreadPlanTracer(thread, stream_sp), m_disassembler_sp(), m_intptr_type(),
+      m_register_values() {}
+
+ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer(Thread &thread)
+    : ThreadPlanTracer(thread), m_disassembler_sp(), m_intptr_type(),
+      m_register_values() {}
+
+Disassembler *ThreadPlanAssemblyTracer::GetDisassembler() {
+  if (!m_disassembler_sp)
+    m_disassembler_sp = Disassembler::FindPlugin(
+        m_thread.GetProcess()->GetTarget().GetArchitecture(), nullptr, nullptr);
+  return m_disassembler_sp.get();
 }
 
-ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread) :
-    ThreadPlanTracer (thread),
-    m_disassembler_sp (),
-    m_intptr_type (),
-    m_register_values ()
-{
-}
-
-Disassembler *
-ThreadPlanAssemblyTracer::GetDisassembler ()
-{
-    if (!m_disassembler_sp)
-        m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), nullptr, nullptr);
-    return m_disassembler_sp.get();
-}
-
-TypeFromUser
-ThreadPlanAssemblyTracer::GetIntPointerType()
-{
-    if (!m_intptr_type.IsValid ())
-    {
-        TargetSP target_sp (m_thread.CalculateTarget());
-        if (target_sp)
-        {
-            TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
-            if (type_system)
-                m_intptr_type = TypeFromUser(type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8));
-        }        
+TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() {
+  if (!m_intptr_type.IsValid()) {
+    TargetSP target_sp(m_thread.CalculateTarget());
+    if (target_sp) {
+      TypeSystem *type_system =
+          target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
+      if (type_system)
+        m_intptr_type =
+            TypeFromUser(type_system->GetBuiltinTypeForEncodingAndBitSize(
+                eEncodingUint,
+                target_sp->GetArchitecture().GetAddressByteSize() * 8));
     }
-    return m_intptr_type;
+  }
+  return m_intptr_type;
 }
 
 ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer() = default;
 
-void 
-ThreadPlanAssemblyTracer::TracingStarted ()
-{
-    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
-    
-    if (m_register_values.empty())
-        m_register_values.resize (reg_ctx->GetRegisterCount());
+void ThreadPlanAssemblyTracer::TracingStarted() {
+  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+
+  if (m_register_values.empty())
+    m_register_values.resize(reg_ctx->GetRegisterCount());
 }
 
-void
-ThreadPlanAssemblyTracer::TracingEnded ()
-{
-    m_register_values.clear();
-}
+void ThreadPlanAssemblyTracer::TracingEnded() { m_register_values.clear(); }
 
-void 
-ThreadPlanAssemblyTracer::Log ()
-{
-    Stream *stream = GetLogStream ();
-    
-    if (!stream)
-        return;
-            
-    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
-    
-    lldb::addr_t pc = reg_ctx->GetPC();
-    ProcessSP process_sp (m_thread.GetProcess());
-    Address pc_addr;
-    bool addr_valid = false;
-    uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
-    addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
-    
-    pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
-    stream->PutCString (" ");
-    
-    Disassembler *disassembler = GetDisassembler();
-    if (disassembler)
-    {        
-        Error err;
-        process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
-        
-        if (err.Success())
-        {
-            DataExtractor extractor(buffer, sizeof(buffer), 
-                                    process_sp->GetByteOrder(), 
-                                    process_sp->GetAddressByteSize());
-            
-			bool data_from_file = false;
-            if (addr_valid)
-                disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
-            else
-                disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false, data_from_file);
-            
-            InstructionList &instruction_list = disassembler->GetInstructionList();
-            const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
+void ThreadPlanAssemblyTracer::Log() {
+  Stream *stream = GetLogStream();
 
-            if (instruction_list.GetSize())
-            {
-                const bool show_bytes = true;
-                const bool show_address = true;
-                Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
-                const FormatEntity::Entry *disassemble_format = m_thread.GetProcess()->GetTarget().GetDebugger().GetDisassemblyFormat();
-                instruction->Dump(stream,
-                                  max_opcode_byte_size,
-                                  show_address,
-                                  show_bytes,
-                                  nullptr,
-                                  nullptr,
-                                  nullptr,
-                                  disassemble_format,
-                                  0);
-            }
-        }
+  if (!stream)
+    return;
+
+  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+
+  lldb::addr_t pc = reg_ctx->GetPC();
+  ProcessSP process_sp(m_thread.GetProcess());
+  Address pc_addr;
+  bool addr_valid = false;
+  uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
+  addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(
+      pc, pc_addr);
+
+  pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription,
+               Address::DumpStyleModuleWithFileAddress);
+  stream->PutCString(" ");
+
+  Disassembler *disassembler = GetDisassembler();
+  if (disassembler) {
+    Error err;
+    process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
+
+    if (err.Success()) {
+      DataExtractor extractor(buffer, sizeof(buffer),
+                              process_sp->GetByteOrder(),
+                              process_sp->GetAddressByteSize());
+
+      bool data_from_file = false;
+      if (addr_valid)
+        disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false,
+                                         data_from_file);
+      else
+        disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false,
+                                         data_from_file);
+
+      InstructionList &instruction_list = disassembler->GetInstructionList();
+      const uint32_t max_opcode_byte_size =
+          instruction_list.GetMaxOpcocdeByteSize();
+
+      if (instruction_list.GetSize()) {
+        const bool show_bytes = true;
+        const bool show_address = true;
+        Instruction *instruction =
+            instruction_list.GetInstructionAtIndex(0).get();
+        const FormatEntity::Entry *disassemble_format =
+            m_thread.GetProcess()
+                ->GetTarget()
+                .GetDebugger()
+                .GetDisassemblyFormat();
+        instruction->Dump(stream, max_opcode_byte_size, show_address,
+                          show_bytes, nullptr, nullptr, nullptr,
+                          disassemble_format, 0);
+      }
     }
-    
-    const ABI *abi = process_sp->GetABI().get();
-    TypeFromUser intptr_type = GetIntPointerType();
-    
-    if (abi && intptr_type.IsValid())
-    {
-        ValueList value_list;
-        const int num_args = 1;
-        
-        for (int arg_index = 0; arg_index < num_args; ++arg_index)
-        {
-            Value value;
-            value.SetValueType (Value::eValueTypeScalar);
-//            value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType());
-            value.SetCompilerType (intptr_type);
-            value_list.PushValue (value);
-        }
-        
-        if (abi->GetArgumentValues (m_thread, value_list))
-        {                
-            for (int arg_index = 0; arg_index < num_args; ++arg_index)
-            {
-                stream->Printf("\n\targ[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
-                
-                if (arg_index + 1 < num_args)
-                    stream->PutCString (", ");
-            }
-        }
+  }
+
+  const ABI *abi = process_sp->GetABI().get();
+  TypeFromUser intptr_type = GetIntPointerType();
+
+  if (abi && intptr_type.IsValid()) {
+    ValueList value_list;
+    const int num_args = 1;
+
+    for (int arg_index = 0; arg_index < num_args; ++arg_index) {
+      Value value;
+      value.SetValueType(Value::eValueTypeScalar);
+      //            value.SetContext (Value::eContextTypeClangType,
+      //            intptr_type.GetOpaqueQualType());
+      value.SetCompilerType(intptr_type);
+      value_list.PushValue(value);
     }
 
-    RegisterValue reg_value;
-    for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
-         reg_num < num_registers;
-         ++reg_num)
-    {
-        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
-        if (reg_ctx->ReadRegister (reg_info, reg_value))
-        {
-            assert (reg_num < m_register_values.size());
-            if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid || 
-                reg_value != m_register_values[reg_num])
-            {
-                if (reg_value.GetType() != RegisterValue::eTypeInvalid)
-                {
-                    stream->PutCString ("\n\t");
-                    reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
-                }
-            }
-            m_register_values[reg_num] = reg_value;
-        }
+    if (abi->GetArgumentValues(m_thread, value_list)) {
+      for (int arg_index = 0; arg_index < num_args; ++arg_index) {
+        stream->Printf(
+            "\n\targ[%d]=%llx", arg_index,
+            value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
+
+        if (arg_index + 1 < num_args)
+          stream->PutCString(", ");
+      }
     }
-    stream->EOL();
-    stream->Flush();
+  }
+
+  RegisterValue reg_value;
+  for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
+       reg_num < num_registers; ++reg_num) {
+    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+      assert(reg_num < m_register_values.size());
+      if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
+          reg_value != m_register_values[reg_num]) {
+        if (reg_value.GetType() != RegisterValue::eTypeInvalid) {
+          stream->PutCString("\n\t");
+          reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
+        }
+      }
+      m_register_values[reg_num] = reg_value;
+    }
+  }
+  stream->EOL();
+  stream->Flush();
 }
