diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 8872071..e491c59 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -18,9 +18,9 @@
 #include "lldb/Core/Mangled.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/Symbol.h"
@@ -40,289 +40,221 @@
 // The first bits in the flags are reserved for the SymbolContext::Scope bits
 // so we know if we have tried to look up information in our internal symbol
 // context (m_sc) already.
-#define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
-#define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
-#define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
-#define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
-#define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
+#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
+#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
+#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
+#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
+#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
 
-StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa,
-                       bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame,
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
+                       user_id_t unwind_frame_index, addr_t cfa,
+                       bool cfa_is_valid, addr_t pc, uint32_t stop_id,
+                       bool stop_id_is_valid, bool is_history_frame,
                        const SymbolContext *sc_ptr)
-    : m_thread_wp(thread_sp),
-      m_frame_index(frame_idx),
-      m_concrete_frame_index(unwind_frame_index),
-      m_reg_context_sp(),
-      m_id(pc, cfa, nullptr),
-      m_frame_code_addr(pc),
-      m_sc(),
-      m_flags(),
-      m_frame_base(),
-      m_frame_base_error(),
-      m_cfa_is_valid(cfa_is_valid),
-      m_stop_id(stop_id),
-      m_stop_id_is_valid(stop_id_is_valid),
-      m_is_history_frame(is_history_frame),
-      m_variable_list_sp(),
-      m_variable_list_value_objects(),
-      m_disassembly(),
-      m_mutex()
-{
-    // If we don't have a CFA value, use the frame index for our StackID so that recursive
-    // functions properly aren't confused with one another on a history stack.
-    if (m_is_history_frame && !m_cfa_is_valid)
-    {
-        m_id.SetCFA(m_frame_index);
-    }
+    : m_thread_wp(thread_sp), m_frame_index(frame_idx),
+      m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
+      m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(),
+      m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
+      m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid),
+      m_is_history_frame(is_history_frame), m_variable_list_sp(),
+      m_variable_list_value_objects(), m_disassembly(), m_mutex() {
+  // If we don't have a CFA value, use the frame index for our StackID so that
+  // recursive
+  // functions properly aren't confused with one another on a history stack.
+  if (m_is_history_frame && !m_cfa_is_valid) {
+    m_id.SetCFA(m_frame_index);
+  }
 
-    if (sc_ptr != nullptr)
-    {
-        m_sc = *sc_ptr;
-        m_flags.Set(m_sc.GetResolvedMask());
-    }
+  if (sc_ptr != nullptr) {
+    m_sc = *sc_ptr;
+    m_flags.Set(m_sc.GetResolvedMask());
+  }
 }
 
-StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
-                       const RegisterContextSP &reg_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr)
-    : m_thread_wp(thread_sp),
-      m_frame_index(frame_idx),
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
+                       user_id_t unwind_frame_index,
+                       const RegisterContextSP &reg_context_sp, addr_t cfa,
+                       addr_t pc, const SymbolContext *sc_ptr)
+    : m_thread_wp(thread_sp), m_frame_index(frame_idx),
       m_concrete_frame_index(unwind_frame_index),
-      m_reg_context_sp(reg_context_sp),
-      m_id(pc, cfa, nullptr),
-      m_frame_code_addr(pc),
-      m_sc(),
-      m_flags(),
-      m_frame_base(),
-      m_frame_base_error(),
-      m_cfa_is_valid(true),
-      m_stop_id(0),
-      m_stop_id_is_valid(false),
-      m_is_history_frame(false),
-      m_variable_list_sp(),
-      m_variable_list_value_objects(),
-      m_disassembly(),
-      m_mutex()
-{
-    if (sc_ptr != nullptr)
-    {
-        m_sc = *sc_ptr;
-        m_flags.Set(m_sc.GetResolvedMask());
-    }
+      m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr),
+      m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(),
+      m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0),
+      m_stop_id_is_valid(false), m_is_history_frame(false),
+      m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(),
+      m_mutex() {
+  if (sc_ptr != nullptr) {
+    m_sc = *sc_ptr;
+    m_flags.Set(m_sc.GetResolvedMask());
+  }
 
-    if (reg_context_sp && !m_sc.target_sp)
-    {
-        m_sc.target_sp = reg_context_sp->CalculateTarget();
-        if (m_sc.target_sp)
-            m_flags.Set(eSymbolContextTarget);
-    }
+  if (reg_context_sp && !m_sc.target_sp) {
+    m_sc.target_sp = reg_context_sp->CalculateTarget();
+    if (m_sc.target_sp)
+      m_flags.Set(eSymbolContextTarget);
+  }
 }
 
-StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
-                       const RegisterContextSP &reg_context_sp, addr_t cfa, const Address &pc_addr,
-                       const SymbolContext *sc_ptr)
-    : m_thread_wp(thread_sp),
-      m_frame_index(frame_idx),
+StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
+                       user_id_t unwind_frame_index,
+                       const RegisterContextSP &reg_context_sp, addr_t cfa,
+                       const Address &pc_addr, const SymbolContext *sc_ptr)
+    : m_thread_wp(thread_sp), m_frame_index(frame_idx),
       m_concrete_frame_index(unwind_frame_index),
       m_reg_context_sp(reg_context_sp),
-      m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr),
-      m_frame_code_addr(pc_addr),
-      m_sc(),
-      m_flags(),
-      m_frame_base(),
-      m_frame_base_error(),
-      m_cfa_is_valid(true),
-      m_stop_id(0),
-      m_stop_id_is_valid(false),
-      m_is_history_frame(false),
-      m_variable_list_sp(),
-      m_variable_list_value_objects(),
-      m_disassembly(),
-      m_mutex()
-{
-    if (sc_ptr != nullptr)
-    {
-        m_sc = *sc_ptr;
-        m_flags.Set(m_sc.GetResolvedMask());
-    }
+      m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
+           nullptr),
+      m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
+      m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0),
+      m_stop_id_is_valid(false), m_is_history_frame(false),
+      m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(),
+      m_mutex() {
+  if (sc_ptr != nullptr) {
+    m_sc = *sc_ptr;
+    m_flags.Set(m_sc.GetResolvedMask());
+  }
 
-    if (!m_sc.target_sp && reg_context_sp)
-    {
-        m_sc.target_sp = reg_context_sp->CalculateTarget();
-        if (m_sc.target_sp)
-            m_flags.Set(eSymbolContextTarget);
-    }
+  if (!m_sc.target_sp && reg_context_sp) {
+    m_sc.target_sp = reg_context_sp->CalculateTarget();
+    if (m_sc.target_sp)
+      m_flags.Set(eSymbolContextTarget);
+  }
 
-    ModuleSP pc_module_sp(pc_addr.GetModule());
-    if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
-    {
-        if (pc_module_sp)
-        {
-            m_sc.module_sp = pc_module_sp;
-            m_flags.Set(eSymbolContextModule);
-        }
-        else
-        {
-            m_sc.module_sp.reset();
-        }
+  ModuleSP pc_module_sp(pc_addr.GetModule());
+  if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
+    if (pc_module_sp) {
+      m_sc.module_sp = pc_module_sp;
+      m_flags.Set(eSymbolContextModule);
+    } else {
+      m_sc.module_sp.reset();
     }
+  }
 }
 
 StackFrame::~StackFrame() = default;
 
-StackID&
-StackFrame::GetStackID()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    // Make sure we have resolved the StackID object's symbol context scope if
-    // we already haven't looked it up.
+StackID &StackFrame::GetStackID() {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  // Make sure we have resolved the StackID object's symbol context scope if
+  // we already haven't looked it up.
 
-    if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
-    {
-        if (m_id.GetSymbolContextScope ())
-        {
-            // We already have a symbol context scope, we just don't have our
-            // flag bit set.
-            m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
-        }
-        else
-        {
-            // Calculate the frame block and use this for the stack ID symbol
-            // context scope if we have one.
-            SymbolContextScope *scope = GetFrameBlock (); 
-            if (scope == nullptr)
-            {
-                // We don't have a block, so use the symbol
-                if (m_flags.IsClear (eSymbolContextSymbol))
-                    GetSymbolContext (eSymbolContextSymbol);
-                
-                // It is ok if m_sc.symbol is nullptr here
-                scope = m_sc.symbol;
-            }
-            // Set the symbol context scope (the accessor will set the
-            // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
-            SetSymbolContextScope (scope);
-        }
+  if (m_flags.IsClear(RESOLVED_FRAME_ID_SYMBOL_SCOPE)) {
+    if (m_id.GetSymbolContextScope()) {
+      // We already have a symbol context scope, we just don't have our
+      // flag bit set.
+      m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
+    } else {
+      // Calculate the frame block and use this for the stack ID symbol
+      // context scope if we have one.
+      SymbolContextScope *scope = GetFrameBlock();
+      if (scope == nullptr) {
+        // We don't have a block, so use the symbol
+        if (m_flags.IsClear(eSymbolContextSymbol))
+          GetSymbolContext(eSymbolContextSymbol);
+
+        // It is ok if m_sc.symbol is nullptr here
+        scope = m_sc.symbol;
+      }
+      // Set the symbol context scope (the accessor will set the
+      // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
+      SetSymbolContextScope(scope);
     }
-    return m_id;
+  }
+  return m_id;
 }
 
-uint32_t
-StackFrame::GetFrameIndex () const
-{
-    ThreadSP thread_sp = GetThread();
-    if (thread_sp)
-        return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
-    else
-        return m_frame_index;
+uint32_t StackFrame::GetFrameIndex() const {
+  ThreadSP thread_sp = GetThread();
+  if (thread_sp)
+    return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
+        m_frame_index);
+  else
+    return m_frame_index;
 }
 
-void
-StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
-    m_id.SetSymbolContextScope (symbol_scope);
+void StackFrame::SetSymbolContextScope(SymbolContextScope *symbol_scope) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
+  m_id.SetSymbolContextScope(symbol_scope);
 }
 
-const Address&
-StackFrame::GetFrameCodeAddress()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
-    {
-        m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
+const Address &StackFrame::GetFrameCodeAddress() {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) &&
+      !m_frame_code_addr.IsSectionOffset()) {
+    m_flags.Set(RESOLVED_FRAME_CODE_ADDR);
 
-        // Resolve the PC into a temporary address because if ResolveLoadAddress
-        // fails to resolve the address, it will clear the address object...
-        ThreadSP thread_sp (GetThread());
-        if (thread_sp)
-        {
-            TargetSP target_sp (thread_sp->CalculateTarget());
-            if (target_sp)
-            {
-                if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get(), eAddressClassCode))
-                {
-                    ModuleSP module_sp (m_frame_code_addr.GetModule());
-                    if (module_sp)
-                    {
-                        m_sc.module_sp = module_sp;
-                        m_flags.Set(eSymbolContextModule);
-                    }
-                }
-            }
+    // Resolve the PC into a temporary address because if ResolveLoadAddress
+    // fails to resolve the address, it will clear the address object...
+    ThreadSP thread_sp(GetThread());
+    if (thread_sp) {
+      TargetSP target_sp(thread_sp->CalculateTarget());
+      if (target_sp) {
+        if (m_frame_code_addr.SetOpcodeLoadAddress(
+                m_frame_code_addr.GetOffset(), target_sp.get(),
+                eAddressClassCode)) {
+          ModuleSP module_sp(m_frame_code_addr.GetModule());
+          if (module_sp) {
+            m_sc.module_sp = module_sp;
+            m_flags.Set(eSymbolContextModule);
+          }
         }
+      }
     }
-    return m_frame_code_addr;
+  }
+  return m_frame_code_addr;
 }
 
-bool
-StackFrame::ChangePC (addr_t pc)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    // We can't change the pc value of a history stack frame - it is immutable.
-    if (m_is_history_frame)
-        return false;
-    m_frame_code_addr.SetRawAddress(pc);
-    m_sc.Clear(false);
-    m_flags.Reset(0);
-    ThreadSP thread_sp (GetThread());
-    if (thread_sp)
-        thread_sp->ClearStackFrames ();
-    return true;
+bool StackFrame::ChangePC(addr_t pc) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  // We can't change the pc value of a history stack frame - it is immutable.
+  if (m_is_history_frame)
+    return false;
+  m_frame_code_addr.SetRawAddress(pc);
+  m_sc.Clear(false);
+  m_flags.Reset(0);
+  ThreadSP thread_sp(GetThread());
+  if (thread_sp)
+    thread_sp->ClearStackFrames();
+  return true;
 }
 
-const char *
-StackFrame::Disassemble ()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+const char *StackFrame::Disassemble() {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (m_disassembly.GetSize() == 0) {
+    ExecutionContext exe_ctx(shared_from_this());
+    Target *target = exe_ctx.GetTargetPtr();
+    if (target) {
+      const char *plugin_name = nullptr;
+      const char *flavor = nullptr;
+      Disassembler::Disassemble(target->GetDebugger(),
+                                target->GetArchitecture(), plugin_name, flavor,
+                                exe_ctx, 0, 0, 0, m_disassembly);
+    }
     if (m_disassembly.GetSize() == 0)
-    {
-        ExecutionContext exe_ctx (shared_from_this());
-        Target *target = exe_ctx.GetTargetPtr();
-        if (target)
-        {
-            const char *plugin_name = nullptr;
-            const char *flavor = nullptr;
-            Disassembler::Disassemble (target->GetDebugger(),
-                                       target->GetArchitecture(),
-                                       plugin_name,
-                                       flavor,
-                                       exe_ctx,
-                                       0,
-                                       0,
-                                       0,
-                                       m_disassembly);
-        }
-        if (m_disassembly.GetSize() == 0)
-            return nullptr;
-    }
-    return m_disassembly.GetData();
+      return nullptr;
+  }
+  return m_disassembly.GetData();
 }
 
-Block *
-StackFrame::GetFrameBlock ()
-{
-    if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
-        GetSymbolContext (eSymbolContextBlock);
+Block *StackFrame::GetFrameBlock() {
+  if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
+    GetSymbolContext(eSymbolContextBlock);
 
-    if (m_sc.block)
-    {    
-        Block *inline_block = m_sc.block->GetContainingInlinedBlock();
-        if (inline_block)
-        {
-            // Use the block with the inlined function info
-            // as the frame block we want this frame to have only the variables
-            // for the inlined function and its non-inlined block child blocks.
-            return inline_block;
-        }
-        else
-        {
-            // This block is not contained within any inlined function blocks
-            // with so we want to use the top most function block.
-            return &m_sc.function->GetBlock (false);
-        }
-    }    
-    return nullptr;
+  if (m_sc.block) {
+    Block *inline_block = m_sc.block->GetContainingInlinedBlock();
+    if (inline_block) {
+      // Use the block with the inlined function info
+      // as the frame block we want this frame to have only the variables
+      // for the inlined function and its non-inlined block child blocks.
+      return inline_block;
+    } else {
+      // This block is not contained within any inlined function blocks
+      // with so we want to use the top most function block.
+      return &m_sc.function->GetBlock(false);
+    }
+  }
+  return nullptr;
 }
 
 //----------------------------------------------------------------------
@@ -331,1840 +263,1658 @@
 // StackFrame object, everyone will have as much information as
 // possible and no one will ever have to look things up manually.
 //----------------------------------------------------------------------
-const SymbolContext&
-StackFrame::GetSymbolContext (uint32_t resolve_scope)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    // Copy our internal symbol context into "sc".
-    if ((m_flags.Get() & resolve_scope) != resolve_scope)
-    {
-        uint32_t resolved = 0;
+const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  // Copy our internal symbol context into "sc".
+  if ((m_flags.Get() & resolve_scope) != resolve_scope) {
+    uint32_t resolved = 0;
 
-        // If the target was requested add that:
-        if (!m_sc.target_sp)
-        {
-            m_sc.target_sp = CalculateTarget();
-            if (m_sc.target_sp)
-                resolved |= eSymbolContextTarget;
-        }
-        
-        // Resolve our PC to section offset if we haven't already done so
-        // and if we don't have a module. The resolved address section will
-        // contain the module to which it belongs
-        if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
-            GetFrameCodeAddress();
-
-        // If this is not frame zero, then we need to subtract 1 from the PC
-        // value when doing address lookups since the PC will be on the 
-        // instruction following the function call instruction...
-        
-        Address lookup_addr(GetFrameCodeAddress());
-        if (m_frame_index > 0 && lookup_addr.IsValid())
-        {
-            addr_t offset = lookup_addr.GetOffset();
-            if (offset > 0)
-            {
-                lookup_addr.SetOffset(offset - 1);
-
-            }
-            else
-            {
-                // lookup_addr is the start of a section.  We need
-                // do the math on the actual load address and re-compute
-                // the section.  We're working with a 'noreturn' function
-                // at the end of a section.
-                ThreadSP thread_sp (GetThread());
-                if (thread_sp)
-                {
-                    TargetSP target_sp (thread_sp->CalculateTarget());
-                    if (target_sp)
-                    {
-                        addr_t addr_minus_one = lookup_addr.GetLoadAddress(target_sp.get()) - 1;
-                        lookup_addr.SetLoadAddress (addr_minus_one, target_sp.get());
-                    }
-                    else
-                    {
-                    lookup_addr.SetOffset(offset - 1);
-                    }
-                }
-            }
-        }
-
-        if (m_sc.module_sp)
-        {
-            // We have something in our stack frame symbol context, lets check
-            // if we haven't already tried to lookup one of those things. If we
-            // haven't then we will do the query.
-            
-            uint32_t actual_resolve_scope = 0;
-            
-            if (resolve_scope & eSymbolContextCompUnit)
-            {
-                if (m_flags.IsClear (eSymbolContextCompUnit))
-                {
-                    if (m_sc.comp_unit)
-                        resolved |= eSymbolContextCompUnit;
-                    else
-                        actual_resolve_scope |= eSymbolContextCompUnit;
-                }
-            }
-
-            if (resolve_scope & eSymbolContextFunction)
-            {
-                if (m_flags.IsClear (eSymbolContextFunction))
-                {
-                    if (m_sc.function)
-                        resolved |= eSymbolContextFunction;
-                    else
-                        actual_resolve_scope |= eSymbolContextFunction;
-                }
-            }
-
-            if (resolve_scope & eSymbolContextBlock)
-            {
-                if (m_flags.IsClear (eSymbolContextBlock))
-                {
-                    if (m_sc.block)
-                        resolved |= eSymbolContextBlock;
-                    else
-                        actual_resolve_scope |= eSymbolContextBlock;
-                }
-            }
-
-            if (resolve_scope & eSymbolContextSymbol)
-            {
-                if (m_flags.IsClear (eSymbolContextSymbol))
-                {
-                    if (m_sc.symbol)
-                        resolved |= eSymbolContextSymbol;
-                    else
-                        actual_resolve_scope |= eSymbolContextSymbol;
-                }
-            }
-
-            if (resolve_scope & eSymbolContextLineEntry)
-            {
-                if (m_flags.IsClear (eSymbolContextLineEntry))
-                {
-                    if (m_sc.line_entry.IsValid())
-                        resolved |= eSymbolContextLineEntry;
-                    else
-                        actual_resolve_scope |= eSymbolContextLineEntry;
-                }
-            }
-            
-            if (actual_resolve_scope)
-            {
-                // We might be resolving less information than what is already
-                // in our current symbol context so resolve into a temporary 
-                // symbol context "sc" so we don't clear out data we have 
-                // already found in "m_sc"
-                SymbolContext sc;
-                // Set flags that indicate what we have tried to resolve
-                resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
-                // Only replace what we didn't already have as we may have 
-                // information for an inlined function scope that won't match
-                // what a standard lookup by address would match
-                if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == nullptr)  
-                    m_sc.comp_unit = sc.comp_unit;
-                if ((resolved & eSymbolContextFunction)  && m_sc.function == nullptr)  
-                    m_sc.function = sc.function;
-                if ((resolved & eSymbolContextBlock)     && m_sc.block == nullptr)  
-                    m_sc.block = sc.block;
-                if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == nullptr)  
-                    m_sc.symbol = sc.symbol;
-                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
-                {
-                    m_sc.line_entry = sc.line_entry;
-                    m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
-                }
-            }
-        }
-        else
-        {
-            // If we don't have a module, then we can't have the compile unit,
-            // function, block, line entry or symbol, so we can safely call
-            // ResolveSymbolContextForAddress with our symbol context member m_sc.
-            if (m_sc.target_sp)
-            {
-                resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
-            }
-        }
-
-        // Update our internal flags so we remember what we have tried to locate so
-        // we don't have to keep trying when more calls to this function are made.
-        // We might have dug up more information that was requested (for example
-        // if we were asked to only get the block, we will have gotten the 
-        // compile unit, and function) so set any additional bits that we resolved
-        m_flags.Set (resolve_scope | resolved);
+    // If the target was requested add that:
+    if (!m_sc.target_sp) {
+      m_sc.target_sp = CalculateTarget();
+      if (m_sc.target_sp)
+        resolved |= eSymbolContextTarget;
     }
 
-    // Return the symbol context with everything that was possible to resolve
-    // resolved.
-    return m_sc;
+    // Resolve our PC to section offset if we haven't already done so
+    // and if we don't have a module. The resolved address section will
+    // contain the module to which it belongs
+    if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
+      GetFrameCodeAddress();
+
+    // If this is not frame zero, then we need to subtract 1 from the PC
+    // value when doing address lookups since the PC will be on the
+    // instruction following the function call instruction...
+
+    Address lookup_addr(GetFrameCodeAddress());
+    if (m_frame_index > 0 && lookup_addr.IsValid()) {
+      addr_t offset = lookup_addr.GetOffset();
+      if (offset > 0) {
+        lookup_addr.SetOffset(offset - 1);
+
+      } else {
+        // lookup_addr is the start of a section.  We need
+        // do the math on the actual load address and re-compute
+        // the section.  We're working with a 'noreturn' function
+        // at the end of a section.
+        ThreadSP thread_sp(GetThread());
+        if (thread_sp) {
+          TargetSP target_sp(thread_sp->CalculateTarget());
+          if (target_sp) {
+            addr_t addr_minus_one =
+                lookup_addr.GetLoadAddress(target_sp.get()) - 1;
+            lookup_addr.SetLoadAddress(addr_minus_one, target_sp.get());
+          } else {
+            lookup_addr.SetOffset(offset - 1);
+          }
+        }
+      }
+    }
+
+    if (m_sc.module_sp) {
+      // We have something in our stack frame symbol context, lets check
+      // if we haven't already tried to lookup one of those things. If we
+      // haven't then we will do the query.
+
+      uint32_t actual_resolve_scope = 0;
+
+      if (resolve_scope & eSymbolContextCompUnit) {
+        if (m_flags.IsClear(eSymbolContextCompUnit)) {
+          if (m_sc.comp_unit)
+            resolved |= eSymbolContextCompUnit;
+          else
+            actual_resolve_scope |= eSymbolContextCompUnit;
+        }
+      }
+
+      if (resolve_scope & eSymbolContextFunction) {
+        if (m_flags.IsClear(eSymbolContextFunction)) {
+          if (m_sc.function)
+            resolved |= eSymbolContextFunction;
+          else
+            actual_resolve_scope |= eSymbolContextFunction;
+        }
+      }
+
+      if (resolve_scope & eSymbolContextBlock) {
+        if (m_flags.IsClear(eSymbolContextBlock)) {
+          if (m_sc.block)
+            resolved |= eSymbolContextBlock;
+          else
+            actual_resolve_scope |= eSymbolContextBlock;
+        }
+      }
+
+      if (resolve_scope & eSymbolContextSymbol) {
+        if (m_flags.IsClear(eSymbolContextSymbol)) {
+          if (m_sc.symbol)
+            resolved |= eSymbolContextSymbol;
+          else
+            actual_resolve_scope |= eSymbolContextSymbol;
+        }
+      }
+
+      if (resolve_scope & eSymbolContextLineEntry) {
+        if (m_flags.IsClear(eSymbolContextLineEntry)) {
+          if (m_sc.line_entry.IsValid())
+            resolved |= eSymbolContextLineEntry;
+          else
+            actual_resolve_scope |= eSymbolContextLineEntry;
+        }
+      }
+
+      if (actual_resolve_scope) {
+        // We might be resolving less information than what is already
+        // in our current symbol context so resolve into a temporary
+        // symbol context "sc" so we don't clear out data we have
+        // already found in "m_sc"
+        SymbolContext sc;
+        // Set flags that indicate what we have tried to resolve
+        resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
+            lookup_addr, actual_resolve_scope, sc);
+        // Only replace what we didn't already have as we may have
+        // information for an inlined function scope that won't match
+        // what a standard lookup by address would match
+        if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
+          m_sc.comp_unit = sc.comp_unit;
+        if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
+          m_sc.function = sc.function;
+        if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
+          m_sc.block = sc.block;
+        if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
+          m_sc.symbol = sc.symbol;
+        if ((resolved & eSymbolContextLineEntry) &&
+            !m_sc.line_entry.IsValid()) {
+          m_sc.line_entry = sc.line_entry;
+          m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
+        }
+      }
+    } else {
+      // If we don't have a module, then we can't have the compile unit,
+      // function, block, line entry or symbol, so we can safely call
+      // ResolveSymbolContextForAddress with our symbol context member m_sc.
+      if (m_sc.target_sp) {
+        resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
+            lookup_addr, resolve_scope, m_sc);
+      }
+    }
+
+    // Update our internal flags so we remember what we have tried to locate so
+    // we don't have to keep trying when more calls to this function are made.
+    // We might have dug up more information that was requested (for example
+    // if we were asked to only get the block, we will have gotten the
+    // compile unit, and function) so set any additional bits that we resolved
+    m_flags.Set(resolve_scope | resolved);
+  }
+
+  // Return the symbol context with everything that was possible to resolve
+  // resolved.
+  return m_sc;
 }
 
-VariableList *
-StackFrame::GetVariableList (bool get_file_globals)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    if (m_flags.IsClear(RESOLVED_VARIABLES))
-    {
-        m_flags.Set(RESOLVED_VARIABLES);
+VariableList *StackFrame::GetVariableList(bool get_file_globals) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (m_flags.IsClear(RESOLVED_VARIABLES)) {
+    m_flags.Set(RESOLVED_VARIABLES);
 
-        Block *frame_block = GetFrameBlock();
-        
-        if (frame_block)
-        {
-            const bool get_child_variables = true;
-            const bool can_create = true;
-            const bool stop_if_child_block_is_inlined_function = true;
-            m_variable_list_sp.reset(new VariableList());
-            frame_block->AppendBlockVariables(can_create,
-                                              get_child_variables,
-                                              stop_if_child_block_is_inlined_function,
-                                              [this](Variable* v) { return true; },
-                                              m_variable_list_sp.get());
-        }
+    Block *frame_block = GetFrameBlock();
+
+    if (frame_block) {
+      const bool get_child_variables = true;
+      const bool can_create = true;
+      const bool stop_if_child_block_is_inlined_function = true;
+      m_variable_list_sp.reset(new VariableList());
+      frame_block->AppendBlockVariables(can_create, get_child_variables,
+                                        stop_if_child_block_is_inlined_function,
+                                        [this](Variable *v) { return true; },
+                                        m_variable_list_sp.get());
     }
-    
-    if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
-        get_file_globals)
-    {
-        m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
-        
-        if (m_flags.IsClear (eSymbolContextCompUnit))
-            GetSymbolContext (eSymbolContextCompUnit);
-        
-        if (m_sc.comp_unit)
-        {
-            VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
-            if (m_variable_list_sp)
-                m_variable_list_sp->AddVariables (global_variable_list_sp.get());
-            else
-                m_variable_list_sp = global_variable_list_sp;
-        }
+  }
+
+  if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
+    m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
+
+    if (m_flags.IsClear(eSymbolContextCompUnit))
+      GetSymbolContext(eSymbolContextCompUnit);
+
+    if (m_sc.comp_unit) {
+      VariableListSP global_variable_list_sp(
+          m_sc.comp_unit->GetVariableList(true));
+      if (m_variable_list_sp)
+        m_variable_list_sp->AddVariables(global_variable_list_sp.get());
+      else
+        m_variable_list_sp = global_variable_list_sp;
     }
-    
-    return m_variable_list_sp.get();
+  }
+
+  return m_variable_list_sp.get();
 }
 
 VariableListSP
-StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    // We can't fetch variable information for a history stack frame.
-    if (m_is_history_frame)
-        return VariableListSP();
+StackFrame::GetInScopeVariableList(bool get_file_globals,
+                                   bool must_have_valid_location) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  // We can't fetch variable information for a history stack frame.
+  if (m_is_history_frame)
+    return VariableListSP();
 
-    VariableListSP var_list_sp(new VariableList);
-    GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
+  VariableListSP var_list_sp(new VariableList);
+  GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
 
-    if (m_sc.block)
-    {
-        const bool can_create = true;
-        const bool get_parent_variables = true;
-        const bool stop_if_block_is_inlined_function = true;
-        m_sc.block->AppendVariables (can_create, 
-                                     get_parent_variables,
-                                     stop_if_block_is_inlined_function,
-                                     [this, must_have_valid_location](Variable* v)
-                                     {
-                                         return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this));
-                                     },
-                                     var_list_sp.get());
-    }
-                     
-    if (m_sc.comp_unit && get_file_globals)
-    {
-        VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
-        if (global_variable_list_sp)
-            var_list_sp->AddVariables (global_variable_list_sp.get());
-    }
-    
-    return var_list_sp;
+  if (m_sc.block) {
+    const bool can_create = true;
+    const bool get_parent_variables = true;
+    const bool stop_if_block_is_inlined_function = true;
+    m_sc.block->AppendVariables(
+        can_create, get_parent_variables, stop_if_block_is_inlined_function,
+        [this, must_have_valid_location](Variable *v) {
+          return v->IsInScope(this) && (!must_have_valid_location ||
+                                        v->LocationIsValidForFrame(this));
+        },
+        var_list_sp.get());
+  }
+
+  if (m_sc.comp_unit && get_file_globals) {
+    VariableListSP global_variable_list_sp(
+        m_sc.comp_unit->GetVariableList(true));
+    if (global_variable_list_sp)
+      var_list_sp->AddVariables(global_variable_list_sp.get());
+  }
+
+  return var_list_sp;
 }
 
-ValueObjectSP
-StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
-                                               DynamicValueType use_dynamic,
-                                               uint32_t options, 
-                                               VariableSP &var_sp,
-                                               Error &error)
-{
-    // We can't fetch variable information for a history stack frame.
-    if (m_is_history_frame)
-        return ValueObjectSP();
-
-    if (var_expr_cstr && var_expr_cstr[0])
-    {
-        const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
-        const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
-        const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
-        //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
-        error.Clear();
-        bool deref = false;
-        bool address_of = false;
-        ValueObjectSP valobj_sp;
-        const bool get_file_globals = true;
-        // When looking up a variable for an expression, we need only consider the
-        // variables that are in scope.
-        VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
-        VariableList *variable_list = var_list_sp.get();
-        
-        if (variable_list)
-        {
-            // If first character is a '*', then show pointer contents
-            const char *var_expr = var_expr_cstr;
-            if (var_expr[0] == '*')
-            {
-                deref = true;
-                var_expr++; // Skip the '*'
-            }
-            else if (var_expr[0] == '&')
-            {
-                address_of = true;
-                var_expr++; // Skip the '&'
-            }
-
-            std::string var_path (var_expr);
-            size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
-            StreamString var_expr_path_strm;
-
-            ConstString name_const_string;
-            if (separator_idx == std::string::npos)
-                name_const_string.SetCString (var_path.c_str());
-            else
-                name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
-
-            var_sp = variable_list->FindVariable(name_const_string, false);
-            
-            bool synthetically_added_instance_object = false;
-
-            if (var_sp)
-            {
-                var_path.erase (0, name_const_string.GetLength ());
-            }
-            
-            if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess))
-            {
-                // Check for direct ivars access which helps us with implicit
-                // access to ivars with the "this->" or "self->"
-                GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
-                lldb::LanguageType method_language = eLanguageTypeUnknown;
-                bool is_instance_method = false;
-                ConstString method_object_name;
-                if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
-                {
-                    if (is_instance_method && method_object_name)
-                    {
-                        var_sp = variable_list->FindVariable(method_object_name);
-                        if (var_sp)
-                        {
-                            separator_idx = 0;
-                            var_path.insert(0, "->");
-                            synthetically_added_instance_object = true;
-                        }
-                    }
-                }
-            }
-            
-            if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions))
-            {
-                // Check if any anonymous unions are there which contain a variable with the name we need
-                for (size_t i = 0;
-                     i < variable_list->GetSize();
-                     i++)
-                {
-                    if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i))
-                    {
-                        if (variable_sp->GetName().IsEmpty())
-                        {
-                            if (Type *var_type = variable_sp->GetType())
-                            {
-                                if (var_type->GetForwardCompilerType().IsAnonymousType())
-                                {
-                                    valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
-                                    if (!valobj_sp)
-                                        return valobj_sp;
-                                    valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true);
-                                    if (valobj_sp)
-                                        break;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (var_sp && !valobj_sp)
-            {
-                valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
-                if (!valobj_sp)
-                    return valobj_sp;
-            }
-            if (valobj_sp)
-            {
-                // We are dumping at least one child
-                while (separator_idx != std::string::npos)
-                {
-                    // Calculate the next separator index ahead of time
-                    ValueObjectSP child_valobj_sp;
-                    const char separator_type = var_path[0];
-                    switch (separator_type)
-                    {
-                    case '-':
-                        if (var_path.size() >= 2 && var_path[1] != '>')
-                            return ValueObjectSP();
-
-                        if (no_fragile_ivar)
-                        {
-                            // Make sure we aren't trying to deref an objective
-                            // C ivar if this is not allowed
-                            const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
-                            if ((pointer_type_flags & eTypeIsObjC) &&
-                                (pointer_type_flags & eTypeIsPointer))
-                            {
-                                // This was an objective C object pointer and 
-                                // it was requested we skip any fragile ivars
-                                // so return nothing here
-                                return ValueObjectSP();
-                            }
-                        }
-                        var_path.erase (0, 1); // Remove the '-'
-                        LLVM_FALLTHROUGH;
-                    case '.':
-                        {
-                            const bool expr_is_ptr = var_path[0] == '>';
-
-                            var_path.erase (0, 1); // Remove the '.' or '>'
-                            separator_idx = var_path.find_first_of(".-[");
-                            ConstString child_name;
-                            if (separator_idx == std::string::npos)
-                                child_name.SetCString (var_path.c_str());
-                            else
-                                child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
-
-                            if (check_ptr_vs_member)
-                            {
-                                // We either have a pointer type and need to verify 
-                                // valobj_sp is a pointer, or we have a member of a 
-                                // class/union/struct being accessed with the . syntax 
-                                // and need to verify we don't have a pointer.
-                                const bool actual_is_ptr = valobj_sp->IsPointerType ();
-                                
-                                if (actual_is_ptr != expr_is_ptr)
-                                {
-                                    // Incorrect use of "." with a pointer, or "->" with
-                                    // a class/union/struct instance or reference.
-                                    valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                    if (actual_is_ptr)
-                                        error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 
-                                                                        var_expr_path_strm.GetString().c_str(), 
-                                                                        child_name.GetCString(),
-                                                                        var_expr_path_strm.GetString().c_str(), 
-                                                                        var_path.c_str());
-                                    else
-                                        error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 
-                                                                        var_expr_path_strm.GetString().c_str(), 
-                                                                        child_name.GetCString(),
-                                                                        var_expr_path_strm.GetString().c_str(), 
-                                                                        var_path.c_str());
-                                    return ValueObjectSP();
-                                }
-                            }
-                            child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
-                            if (!child_valobj_sp)
-                            {
-                                if (!no_synth_child)
-                                {
-                                    child_valobj_sp = valobj_sp->GetSyntheticValue();
-                                    if (child_valobj_sp)
-                                        child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
-                                }
-                                
-                                if (no_synth_child || !child_valobj_sp)
-                                {
-                                    // No child member with name "child_name"
-                                    if (synthetically_added_instance_object)
-                                    {
-                                        // We added a "this->" or "self->" to the beginning of the expression
-                                        // and this is the first pointer ivar access, so just return the normal
-                                        // error
-                                        error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
-                                                                       name_const_string.GetCString());
-                                    }
-                                    else
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        if (child_name)
-                                        {
-                                            error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 
-                                                                            child_name.GetCString(), 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                        else
-                                        {
-                                            error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
-                                                                            var_expr_path_strm.GetString().c_str(),
-                                                                            var_expr_cstr);
-                                        }
-                                    }
-                                    return ValueObjectSP();
-                                }
-                            }
-                            synthetically_added_instance_object = false;
-                            // Remove the child name from the path
-                            var_path.erase(0, child_name.GetLength());
-                            if (use_dynamic != eNoDynamicValues)
-                            {
-                                ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
-                                if (dynamic_value_sp)
-                                    child_valobj_sp = dynamic_value_sp;
-                            }
-                        }
-                        break;
-
-                    case '[':
-                        // Array member access, or treating pointer as an array
-                        if (var_path.size() > 2) // Need at least two brackets and a number
-                        {
-                            char *end = nullptr;
-                            long child_index = ::strtol (&var_path[1], &end, 0);
-                            if (end && *end == ']'
-                                && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
-                            {
-                                if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref)
-                                {
-                                    // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
-                                    // and extract bit low out of it. reading array item low
-                                    // would be done by saying ptr[low], without a deref * sign
-                                    Error error;
-                                    ValueObjectSP temp(valobj_sp->Dereference(error));
-                                    if (error.Fail())
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                        return ValueObjectSP();
-                                    }
-                                    valobj_sp = temp;
-                                    deref = false;
-                                }
-                                else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref)
-                                {
-                                    // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
-                                    // (an operation that is equivalent to deref-ing arr)
-                                    // and extract bit low out of it. reading array item low
-                                    // would be done by saying arr[low], without a deref * sign
-                                    Error error;
-                                    ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
-                                    if (error.Fail())
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                        return ValueObjectSP();
-                                    }
-                                    valobj_sp = temp;
-                                    deref = false;
-                                }
-                                
-                                bool is_incomplete_array = false;
-                                if (valobj_sp->IsPointerType ())
-                                {
-                                    bool is_objc_pointer = true;
-                                    
-                                    if (valobj_sp->GetCompilerType().GetMinimumLanguage() != eLanguageTypeObjC)
-                                        is_objc_pointer = false;
-                                    else if (!valobj_sp->GetCompilerType().IsPointerType())
-                                        is_objc_pointer = false;
-
-                                    if (no_synth_child && is_objc_pointer)
-                                    {
-                                        error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
-                                                                       valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                       var_expr_path_strm.GetString().c_str());
-                                        
-                                        return ValueObjectSP();
-                                    }
-                                    else if (is_objc_pointer)
-                                    {                                            
-                                        // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
-                                        ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
-                                        if (!synthetic /* no synthetic */
-                                            || synthetic == valobj_sp) /* synthetic is the same as the original object */
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                        else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 
-                                                                            child_index, 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                        else
-                                        {
-                                            child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
-                                            if (!child_valobj_sp)
-                                            {
-                                                valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                                error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 
-                                                                                child_index, 
-                                                                                valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                                var_expr_path_strm.GetString().c_str());
-                                            }
-                                        }
-                                    }
-                                    else
-                                    {
-                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
-                                        if (!child_valobj_sp)
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 
-                                                                            child_index, 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                    }
-                                }
-                                else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array))
-                                {
-                                    // Pass false to dynamic_value here so we can tell the difference between
-                                    // no dynamic value and no member of this type...
-                                    child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
-                                    if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
-                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
-
-                                    if (!child_valobj_sp)
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 
-                                                                        child_index, 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                    }
-                                }
-                                else if (valobj_sp->GetCompilerType().IsScalarType())
-                                {
-                                    // this is a bitfield asking to display just one bit
-                                    child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
-                                    if (!child_valobj_sp)
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 
-                                                                        child_index, child_index, 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                    }
-                                }
-                                else
-                                {
-                                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
-                                    if (no_synth_child /* synthetic is forbidden */ ||
-                                        !synthetic /* no synthetic */
-                                        || synthetic == valobj_sp) /* synthetic is the same as the original object */
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                    }
-                                    else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
-                                    {
-                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 
-                                                                        child_index, 
-                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                        var_expr_path_strm.GetString().c_str());
-                                    }
-                                    else
-                                    {
-                                        child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
-                                        if (!child_valobj_sp)
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 
-                                                                            child_index, 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                    }
-                                }
-
-                                if (!child_valobj_sp)
-                                {
-                                    // Invalid array index...
-                                    return ValueObjectSP();
-                                }
-
-                                // Erase the array member specification '[%i]' where 
-                                // %i is the array index
-                                var_path.erase(0, (end - var_path.c_str()) + 1);
-                                separator_idx = var_path.find_first_of(".-[");
-                                if (use_dynamic != eNoDynamicValues)
-                                {
-                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
-                                    if (dynamic_value_sp)
-                                        child_valobj_sp = dynamic_value_sp;
-                                }
-                                // Break out early from the switch since we were 
-                                // able to find the child member
-                                break;
-                            }
-                            else if (end && *end == '-')
-                            {
-                                // this is most probably a BitField, let's take a look
-                                char *real_end = nullptr;
-                                long final_index = ::strtol (end+1, &real_end, 0);
-                                bool expand_bitfield = true;
-                                if (real_end && *real_end == ']')
-                                {
-                                    // if the format given is [high-low], swap range
-                                    if (child_index > final_index)
-                                    {
-                                        long temp = child_index;
-                                        child_index = final_index;
-                                        final_index = temp;
-                                    }
-                                    
-                                    if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref)
-                                    {
-                                        // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
-                                        // and extract bits low thru high out of it. reading array items low thru high
-                                        // would be done by saying ptr[low-high], without a deref * sign
-                                        Error error;
-                                        ValueObjectSP temp(valobj_sp->Dereference(error));
-                                        if (error.Fail())
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                            return ValueObjectSP();
-                                        }
-                                        valobj_sp = temp;
-                                        deref = false;
-                                    }
-                                    else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref)
-                                    {
-                                        // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
-                                        // (an operation that is equivalent to deref-ing arr)
-                                        // and extract bits low thru high out of it. reading array items low thru high
-                                        // would be done by saying arr[low-high], without a deref * sign
-                                        Error error;
-                                        ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
-                                        if (error.Fail())
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                            return ValueObjectSP();
-                                        }
-                                        valobj_sp = temp;
-                                        deref = false;
-                                    }
-                                    /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
-                                    {
-                                        child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
-                                        expand_bitfield = false;
-                                        if (!child_valobj_sp)
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 
-                                                                            child_index, final_index, 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                    }*/
-
-                                    if (expand_bitfield)
-                                    {
-                                        child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
-                                        if (!child_valobj_sp)
-                                        {
-                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                                            error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 
-                                                                            child_index, final_index, 
-                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
-                                                                            var_expr_path_strm.GetString().c_str());
-                                        }
-                                    }
-                                }
-                                
-                                if (!child_valobj_sp)
-                                {
-                                    // Invalid bitfield range...
-                                    return ValueObjectSP();
-                                }
-                                
-                                // Erase the bitfield member specification '[%i-%i]' where 
-                                // %i is the index
-                                var_path.erase(0, (real_end - var_path.c_str()) + 1);
-                                separator_idx = var_path.find_first_of(".-[");
-                                if (use_dynamic != eNoDynamicValues)
-                                {
-                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
-                                    if (dynamic_value_sp)
-                                        child_valobj_sp = dynamic_value_sp;
-                                }
-                                // Break out early from the switch since we were 
-                                // able to find the child member
-                                break;
-
-                            }
-                        }
-                        else
-                        {
-                            error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 
-                                                           var_expr_path_strm.GetString().c_str(),
-                                                           var_path.c_str());
-                        }
-                        return ValueObjectSP();
-
-                    default:
-                        // Failure...
-                        {
-                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
-                            error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 
-                                                            separator_type,
-                                                            var_expr_path_strm.GetString().c_str(),
-                                                            var_path.c_str());
-
-                            return ValueObjectSP();
-                        }
-                    }
-
-                    if (child_valobj_sp)
-                        valobj_sp = child_valobj_sp;
-
-                    if (var_path.empty())
-                        break;
-                }
-                if (valobj_sp)
-                {
-                    if (deref)
-                    {
-                        ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
-                        valobj_sp = deref_valobj_sp;
-                    }
-                    else if (address_of)
-                    {
-                        ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
-                        valobj_sp = address_of_valobj_sp;
-                    }
-                }
-                return valobj_sp;
-            }
-            else
-            {
-                error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 
-                                               name_const_string.GetCString());
-            }
-        }
-    }
-    else
-    {
-        error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
-    }
+ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
+    const char *var_expr_cstr, DynamicValueType use_dynamic, uint32_t options,
+    VariableSP &var_sp, Error &error) {
+  // We can't fetch variable information for a history stack frame.
+  if (m_is_history_frame)
     return ValueObjectSP();
-}
 
-bool
-StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    if (!m_cfa_is_valid)
-    {
-        m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
-        return false;
-    }
-
-    if (m_flags.IsClear(GOT_FRAME_BASE))
-    {
-        if (m_sc.function)
-        {
-            m_frame_base.Clear();
-            m_frame_base_error.Clear();
-
-            m_flags.Set(GOT_FRAME_BASE);
-            ExecutionContext exe_ctx (shared_from_this());
-            Value expr_value;
-            addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
-            if (m_sc.function->GetFrameBaseExpression().IsLocationList())
-                loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
-
-            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx,
-                                                                 nullptr,
-                                                                 nullptr,
-                                                                 nullptr,
-                                                                 loclist_base_addr,
-                                                                 nullptr,
-                                                                 nullptr,
-                                                                 expr_value,
-                                                                 &m_frame_base_error) == false)
-            {
-                // We should really have an error if evaluate returns, but in case
-                // we don't, lets set the error to something at least.
-                if (m_frame_base_error.Success())
-                    m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
-            }
-            else
-            {
-                m_frame_base = expr_value.ResolveValue(&exe_ctx);
-            }
-        }
-        else
-        {
-            m_frame_base_error.SetErrorString ("No function in symbol context.");
-        }
-    }
-
-    if (m_frame_base_error.Success())
-        frame_base = m_frame_base;
-
-    if (error_ptr)
-        *error_ptr = m_frame_base_error;
-    return m_frame_base_error.Success();
-}
-
-DWARFExpression *
-StackFrame::GetFrameBaseExpression(Error *error_ptr)
-{
-    if (!m_sc.function)
-    {
-        if (error_ptr)
-        {
-            error_ptr->SetErrorString ("No function in symbol context.");
-        }
-        return nullptr;
-    }
-
-    return &m_sc.function->GetFrameBaseExpression();
-}
-
-RegisterContextSP
-StackFrame::GetRegisterContext ()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    if (!m_reg_context_sp)
-    {
-        ThreadSP thread_sp (GetThread());
-        if (thread_sp)
-            m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
-    }
-    return m_reg_context_sp;
-}
-
-bool
-StackFrame::HasDebugInformation ()
-{
-    GetSymbolContext (eSymbolContextLineEntry);
-    return m_sc.line_entry.IsValid();
-}
-
-ValueObjectSP
-StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (var_expr_cstr && var_expr_cstr[0]) {
+    const bool check_ptr_vs_member =
+        (options & eExpressionPathOptionCheckPtrVsMember) != 0;
+    const bool no_fragile_ivar =
+        (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
+    const bool no_synth_child =
+        (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
+    // const bool no_synth_array = (options &
+    // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
+    error.Clear();
+    bool deref = false;
+    bool address_of = false;
     ValueObjectSP valobj_sp;
-    if (m_is_history_frame)
-    {
-        return valobj_sp;
-    }
-    VariableList *var_list = GetVariableList (true);
-    if (var_list)
-    {
-        // Make sure the variable is a frame variable
-        const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
-        const uint32_t num_variables = var_list->GetSize();
-        if (var_idx < num_variables)
-        {
-            valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
-            if (!valobj_sp)
-            {
-                if (m_variable_list_value_objects.GetSize() < num_variables)
-                    m_variable_list_value_objects.Resize(num_variables);
-                valobj_sp = ValueObjectVariable::Create (this, variable_sp);
-                m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
+    const bool get_file_globals = true;
+    // When looking up a variable for an expression, we need only consider the
+    // variables that are in scope.
+    VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
+    VariableList *variable_list = var_list_sp.get();
+
+    if (variable_list) {
+      // If first character is a '*', then show pointer contents
+      const char *var_expr = var_expr_cstr;
+      if (var_expr[0] == '*') {
+        deref = true;
+        var_expr++; // Skip the '*'
+      } else if (var_expr[0] == '&') {
+        address_of = true;
+        var_expr++; // Skip the '&'
+      }
+
+      std::string var_path(var_expr);
+      size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
+      StreamString var_expr_path_strm;
+
+      ConstString name_const_string;
+      if (separator_idx == std::string::npos)
+        name_const_string.SetCString(var_path.c_str());
+      else
+        name_const_string.SetCStringWithLength(var_path.c_str(), separator_idx);
+
+      var_sp = variable_list->FindVariable(name_const_string, false);
+
+      bool synthetically_added_instance_object = false;
+
+      if (var_sp) {
+        var_path.erase(0, name_const_string.GetLength());
+      }
+
+      if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
+        // Check for direct ivars access which helps us with implicit
+        // access to ivars with the "this->" or "self->"
+        GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
+        lldb::LanguageType method_language = eLanguageTypeUnknown;
+        bool is_instance_method = false;
+        ConstString method_object_name;
+        if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method,
+                                       method_object_name)) {
+          if (is_instance_method && method_object_name) {
+            var_sp = variable_list->FindVariable(method_object_name);
+            if (var_sp) {
+              separator_idx = 0;
+              var_path.insert(0, "->");
+              synthetically_added_instance_object = true;
             }
+          }
         }
+      }
+
+      if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
+        // Check if any anonymous unions are there which contain a variable with
+        // the name we need
+        for (size_t i = 0; i < variable_list->GetSize(); i++) {
+          if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) {
+            if (variable_sp->GetName().IsEmpty()) {
+              if (Type *var_type = variable_sp->GetType()) {
+                if (var_type->GetForwardCompilerType().IsAnonymousType()) {
+                  valobj_sp =
+                      GetValueObjectForFrameVariable(variable_sp, use_dynamic);
+                  if (!valobj_sp)
+                    return valobj_sp;
+                  valobj_sp = valobj_sp->GetChildMemberWithName(
+                      name_const_string, true);
+                  if (valobj_sp)
+                    break;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      if (var_sp && !valobj_sp) {
+        valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
+        if (!valobj_sp)
+          return valobj_sp;
+      }
+      if (valobj_sp) {
+        // We are dumping at least one child
+        while (separator_idx != std::string::npos) {
+          // Calculate the next separator index ahead of time
+          ValueObjectSP child_valobj_sp;
+          const char separator_type = var_path[0];
+          switch (separator_type) {
+          case '-':
+            if (var_path.size() >= 2 && var_path[1] != '>')
+              return ValueObjectSP();
+
+            if (no_fragile_ivar) {
+              // Make sure we aren't trying to deref an objective
+              // C ivar if this is not allowed
+              const uint32_t pointer_type_flags =
+                  valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
+              if ((pointer_type_flags & eTypeIsObjC) &&
+                  (pointer_type_flags & eTypeIsPointer)) {
+                // This was an objective C object pointer and
+                // it was requested we skip any fragile ivars
+                // so return nothing here
+                return ValueObjectSP();
+              }
+            }
+            var_path.erase(0, 1); // Remove the '-'
+            LLVM_FALLTHROUGH;
+          case '.': {
+            const bool expr_is_ptr = var_path[0] == '>';
+
+            var_path.erase(0, 1); // Remove the '.' or '>'
+            separator_idx = var_path.find_first_of(".-[");
+            ConstString child_name;
+            if (separator_idx == std::string::npos)
+              child_name.SetCString(var_path.c_str());
+            else
+              child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
+
+            if (check_ptr_vs_member) {
+              // We either have a pointer type and need to verify
+              // valobj_sp is a pointer, or we have a member of a
+              // class/union/struct being accessed with the . syntax
+              // and need to verify we don't have a pointer.
+              const bool actual_is_ptr = valobj_sp->IsPointerType();
+
+              if (actual_is_ptr != expr_is_ptr) {
+                // Incorrect use of "." with a pointer, or "->" with
+                // a class/union/struct instance or reference.
+                valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                if (actual_is_ptr)
+                  error.SetErrorStringWithFormat(
+                      "\"%s\" is a pointer and . was used to attempt to access "
+                      "\"%s\". Did you mean \"%s->%s\"?",
+                      var_expr_path_strm.GetString().c_str(),
+                      child_name.GetCString(),
+                      var_expr_path_strm.GetString().c_str(), var_path.c_str());
+                else
+                  error.SetErrorStringWithFormat(
+                      "\"%s\" is not a pointer and -> was used to attempt to "
+                      "access \"%s\". Did you mean \"%s.%s\"?",
+                      var_expr_path_strm.GetString().c_str(),
+                      child_name.GetCString(),
+                      var_expr_path_strm.GetString().c_str(), var_path.c_str());
+                return ValueObjectSP();
+              }
+            }
+            child_valobj_sp =
+                valobj_sp->GetChildMemberWithName(child_name, true);
+            if (!child_valobj_sp) {
+              if (!no_synth_child) {
+                child_valobj_sp = valobj_sp->GetSyntheticValue();
+                if (child_valobj_sp)
+                  child_valobj_sp =
+                      child_valobj_sp->GetChildMemberWithName(child_name, true);
+              }
+
+              if (no_synth_child || !child_valobj_sp) {
+                // No child member with name "child_name"
+                if (synthetically_added_instance_object) {
+                  // We added a "this->" or "self->" to the beginning of the
+                  // expression
+                  // and this is the first pointer ivar access, so just return
+                  // the normal
+                  // error
+                  error.SetErrorStringWithFormat(
+                      "no variable or instance variable named '%s' found in "
+                      "this frame",
+                      name_const_string.GetCString());
+                } else {
+                  valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                  if (child_name) {
+                    error.SetErrorStringWithFormat(
+                        "\"%s\" is not a member of \"(%s) %s\"",
+                        child_name.GetCString(),
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                  } else {
+                    error.SetErrorStringWithFormat(
+                        "incomplete expression path after \"%s\" in \"%s\"",
+                        var_expr_path_strm.GetString().c_str(), var_expr_cstr);
+                  }
+                }
+                return ValueObjectSP();
+              }
+            }
+            synthetically_added_instance_object = false;
+            // Remove the child name from the path
+            var_path.erase(0, child_name.GetLength());
+            if (use_dynamic != eNoDynamicValues) {
+              ValueObjectSP dynamic_value_sp(
+                  child_valobj_sp->GetDynamicValue(use_dynamic));
+              if (dynamic_value_sp)
+                child_valobj_sp = dynamic_value_sp;
+            }
+          } break;
+
+          case '[':
+            // Array member access, or treating pointer as an array
+            if (var_path.size() > 2) // Need at least two brackets and a number
+            {
+              char *end = nullptr;
+              long child_index = ::strtol(&var_path[1], &end, 0);
+              if (end && *end == ']' &&
+                  *(end - 1) != '[') // this code forces an error in the case of
+                                     // arr[]. as bitfield[] is not a good
+                                     // syntax we're good to go
+              {
+                if (valobj_sp->GetCompilerType().IsPointerToScalarType() &&
+                    deref) {
+                  // what we have is *ptr[low]. the most similar C++ syntax is
+                  // to deref ptr
+                  // and extract bit low out of it. reading array item low
+                  // would be done by saying ptr[low], without a deref * sign
+                  Error error;
+                  ValueObjectSP temp(valobj_sp->Dereference(error));
+                  if (error.Fail()) {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "could not dereference \"(%s) %s\"",
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                    return ValueObjectSP();
+                  }
+                  valobj_sp = temp;
+                  deref = false;
+                } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
+                           deref) {
+                  // what we have is *arr[low]. the most similar C++ syntax is
+                  // to get arr[0]
+                  // (an operation that is equivalent to deref-ing arr)
+                  // and extract bit low out of it. reading array item low
+                  // would be done by saying arr[low], without a deref * sign
+                  Error error;
+                  ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
+                  if (error.Fail()) {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "could not get item 0 for \"(%s) %s\"",
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                    return ValueObjectSP();
+                  }
+                  valobj_sp = temp;
+                  deref = false;
+                }
+
+                bool is_incomplete_array = false;
+                if (valobj_sp->IsPointerType()) {
+                  bool is_objc_pointer = true;
+
+                  if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
+                      eLanguageTypeObjC)
+                    is_objc_pointer = false;
+                  else if (!valobj_sp->GetCompilerType().IsPointerType())
+                    is_objc_pointer = false;
+
+                  if (no_synth_child && is_objc_pointer) {
+                    error.SetErrorStringWithFormat(
+                        "\"(%s) %s\" is an Objective-C pointer, and cannot be "
+                        "subscripted",
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+
+                    return ValueObjectSP();
+                  } else if (is_objc_pointer) {
+                    // dereferencing ObjC variables is not valid.. so let's try
+                    // and recur to synthetic children
+                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
+                    if (!synthetic                 /* no synthetic */
+                        || synthetic == valobj_sp) /* synthetic is the same as
+                                                      the original object */
+                    {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "\"(%s) %s\" is not an array type",
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                    } else if (
+                        static_cast<uint32_t>(child_index) >=
+                        synthetic
+                            ->GetNumChildren() /* synthetic does not have that many values */) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "array index %ld is not valid for \"(%s) %s\"",
+                          child_index,
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                    } else {
+                      child_valobj_sp =
+                          synthetic->GetChildAtIndex(child_index, true);
+                      if (!child_valobj_sp) {
+                        valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                        error.SetErrorStringWithFormat(
+                            "array index %ld is not valid for \"(%s) %s\"",
+                            child_index, valobj_sp->GetTypeName().AsCString(
+                                             "<invalid type>"),
+                            var_expr_path_strm.GetString().c_str());
+                      }
+                    }
+                  } else {
+                    child_valobj_sp =
+                        valobj_sp->GetSyntheticArrayMember(child_index, true);
+                    if (!child_valobj_sp) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "failed to use pointer as array for index %ld for "
+                          "\"(%s) %s\"",
+                          child_index,
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                    }
+                  }
+                } else if (valobj_sp->GetCompilerType().IsArrayType(
+                               nullptr, nullptr, &is_incomplete_array)) {
+                  // Pass false to dynamic_value here so we can tell the
+                  // difference between
+                  // no dynamic value and no member of this type...
+                  child_valobj_sp =
+                      valobj_sp->GetChildAtIndex(child_index, true);
+                  if (!child_valobj_sp &&
+                      (is_incomplete_array || !no_synth_child))
+                    child_valobj_sp =
+                        valobj_sp->GetSyntheticArrayMember(child_index, true);
+
+                  if (!child_valobj_sp) {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "array index %ld is not valid for \"(%s) %s\"",
+                        child_index,
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                  }
+                } else if (valobj_sp->GetCompilerType().IsScalarType()) {
+                  // this is a bitfield asking to display just one bit
+                  child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
+                      child_index, child_index, true);
+                  if (!child_valobj_sp) {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
+                        child_index, child_index,
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                  }
+                } else {
+                  ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
+                  if (no_synth_child /* synthetic is forbidden */ ||
+                      !synthetic /* no synthetic */
+                      ||
+                      synthetic == valobj_sp) /* synthetic is the same as the
+                                                 original object */
+                  {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "\"(%s) %s\" is not an array type",
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                  } else if (
+                      static_cast<uint32_t>(child_index) >=
+                      synthetic
+                          ->GetNumChildren() /* synthetic does not have that many values */) {
+                    valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                    error.SetErrorStringWithFormat(
+                        "array index %ld is not valid for \"(%s) %s\"",
+                        child_index,
+                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                        var_expr_path_strm.GetString().c_str());
+                  } else {
+                    child_valobj_sp =
+                        synthetic->GetChildAtIndex(child_index, true);
+                    if (!child_valobj_sp) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "array index %ld is not valid for \"(%s) %s\"",
+                          child_index,
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                    }
+                  }
+                }
+
+                if (!child_valobj_sp) {
+                  // Invalid array index...
+                  return ValueObjectSP();
+                }
+
+                // Erase the array member specification '[%i]' where
+                // %i is the array index
+                var_path.erase(0, (end - var_path.c_str()) + 1);
+                separator_idx = var_path.find_first_of(".-[");
+                if (use_dynamic != eNoDynamicValues) {
+                  ValueObjectSP dynamic_value_sp(
+                      child_valobj_sp->GetDynamicValue(use_dynamic));
+                  if (dynamic_value_sp)
+                    child_valobj_sp = dynamic_value_sp;
+                }
+                // Break out early from the switch since we were
+                // able to find the child member
+                break;
+              } else if (end && *end == '-') {
+                // this is most probably a BitField, let's take a look
+                char *real_end = nullptr;
+                long final_index = ::strtol(end + 1, &real_end, 0);
+                bool expand_bitfield = true;
+                if (real_end && *real_end == ']') {
+                  // if the format given is [high-low], swap range
+                  if (child_index > final_index) {
+                    long temp = child_index;
+                    child_index = final_index;
+                    final_index = temp;
+                  }
+
+                  if (valobj_sp->GetCompilerType().IsPointerToScalarType() &&
+                      deref) {
+                    // what we have is *ptr[low-high]. the most similar C++
+                    // syntax is to deref ptr
+                    // and extract bits low thru high out of it. reading array
+                    // items low thru high
+                    // would be done by saying ptr[low-high], without a deref *
+                    // sign
+                    Error error;
+                    ValueObjectSP temp(valobj_sp->Dereference(error));
+                    if (error.Fail()) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "could not dereference \"(%s) %s\"",
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                      return ValueObjectSP();
+                    }
+                    valobj_sp = temp;
+                    deref = false;
+                  } else if (valobj_sp->GetCompilerType()
+                                 .IsArrayOfScalarType() &&
+                             deref) {
+                    // what we have is *arr[low-high]. the most similar C++
+                    // syntax is to get arr[0]
+                    // (an operation that is equivalent to deref-ing arr)
+                    // and extract bits low thru high out of it. reading array
+                    // items low thru high
+                    // would be done by saying arr[low-high], without a deref *
+                    // sign
+                    Error error;
+                    ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
+                    if (error.Fail()) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "could not get item 0 for \"(%s) %s\"",
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                      return ValueObjectSP();
+                    }
+                    valobj_sp = temp;
+                    deref = false;
+                  }
+                  /*else if (valobj_sp->IsArrayType() ||
+                  valobj_sp->IsPointerType())
+                  {
+                      child_valobj_sp =
+                  valobj_sp->GetSyntheticArrayRangeChild(child_index,
+                  final_index, true);
+                      expand_bitfield = false;
+                      if (!child_valobj_sp)
+                      {
+                          valobj_sp->GetExpressionPath (var_expr_path_strm,
+                  false);
+                          error.SetErrorStringWithFormat ("array range %i-%i is
+                  not valid for \"(%s) %s\"",
+                                                          child_index,
+                  final_index,
+                                                          valobj_sp->GetTypeName().AsCString("<invalid
+                  type>"),
+                                                          var_expr_path_strm.GetString().c_str());
+                      }
+                  }*/
+
+                  if (expand_bitfield) {
+                    child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
+                        child_index, final_index, true);
+                    if (!child_valobj_sp) {
+                      valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+                      error.SetErrorStringWithFormat(
+                          "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
+                          child_index, final_index,
+                          valobj_sp->GetTypeName().AsCString("<invalid type>"),
+                          var_expr_path_strm.GetString().c_str());
+                    }
+                  }
+                }
+
+                if (!child_valobj_sp) {
+                  // Invalid bitfield range...
+                  return ValueObjectSP();
+                }
+
+                // Erase the bitfield member specification '[%i-%i]' where
+                // %i is the index
+                var_path.erase(0, (real_end - var_path.c_str()) + 1);
+                separator_idx = var_path.find_first_of(".-[");
+                if (use_dynamic != eNoDynamicValues) {
+                  ValueObjectSP dynamic_value_sp(
+                      child_valobj_sp->GetDynamicValue(use_dynamic));
+                  if (dynamic_value_sp)
+                    child_valobj_sp = dynamic_value_sp;
+                }
+                // Break out early from the switch since we were
+                // able to find the child member
+                break;
+              }
+            } else {
+              error.SetErrorStringWithFormat(
+                  "invalid square bracket encountered after \"%s\" in \"%s\"",
+                  var_expr_path_strm.GetString().c_str(), var_path.c_str());
+            }
+            return ValueObjectSP();
+
+          default:
+            // Failure...
+            {
+              valobj_sp->GetExpressionPath(var_expr_path_strm, false);
+              error.SetErrorStringWithFormat(
+                  "unexpected char '%c' encountered after \"%s\" in \"%s\"",
+                  separator_type, var_expr_path_strm.GetString().c_str(),
+                  var_path.c_str());
+
+              return ValueObjectSP();
+            }
+          }
+
+          if (child_valobj_sp)
+            valobj_sp = child_valobj_sp;
+
+          if (var_path.empty())
+            break;
+        }
+        if (valobj_sp) {
+          if (deref) {
+            ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
+            valobj_sp = deref_valobj_sp;
+          } else if (address_of) {
+            ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
+            valobj_sp = address_of_valobj_sp;
+          }
+        }
+        return valobj_sp;
+      } else {
+        error.SetErrorStringWithFormat(
+            "no variable named '%s' found in this frame",
+            name_const_string.GetCString());
+      }
     }
-    if (use_dynamic != eNoDynamicValues && valobj_sp)
-    {
-        ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
-        if (dynamic_sp)
-            return dynamic_sp;
+  } else {
+    error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
+  }
+  return ValueObjectSP();
+}
+
+bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (!m_cfa_is_valid) {
+    m_frame_base_error.SetErrorString(
+        "No frame base available for this historical stack frame.");
+    return false;
+  }
+
+  if (m_flags.IsClear(GOT_FRAME_BASE)) {
+    if (m_sc.function) {
+      m_frame_base.Clear();
+      m_frame_base_error.Clear();
+
+      m_flags.Set(GOT_FRAME_BASE);
+      ExecutionContext exe_ctx(shared_from_this());
+      Value expr_value;
+      addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
+      if (m_sc.function->GetFrameBaseExpression().IsLocationList())
+        loclist_base_addr =
+            m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
+                exe_ctx.GetTargetPtr());
+
+      if (m_sc.function->GetFrameBaseExpression().Evaluate(
+              &exe_ctx, nullptr, nullptr, nullptr, loclist_base_addr, nullptr,
+              nullptr, expr_value, &m_frame_base_error) == false) {
+        // We should really have an error if evaluate returns, but in case
+        // we don't, lets set the error to something at least.
+        if (m_frame_base_error.Success())
+          m_frame_base_error.SetErrorString(
+              "Evaluation of the frame base expression failed.");
+      } else {
+        m_frame_base = expr_value.ResolveValue(&exe_ctx);
+      }
+    } else {
+      m_frame_base_error.SetErrorString("No function in symbol context.");
     }
-    return valobj_sp;
+  }
+
+  if (m_frame_base_error.Success())
+    frame_base = m_frame_base;
+
+  if (error_ptr)
+    *error_ptr = m_frame_base_error;
+  return m_frame_base_error.Success();
+}
+
+DWARFExpression *StackFrame::GetFrameBaseExpression(Error *error_ptr) {
+  if (!m_sc.function) {
+    if (error_ptr) {
+      error_ptr->SetErrorString("No function in symbol context.");
+    }
+    return nullptr;
+  }
+
+  return &m_sc.function->GetFrameBaseExpression();
+}
+
+RegisterContextSP StackFrame::GetRegisterContext() {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (!m_reg_context_sp) {
+    ThreadSP thread_sp(GetThread());
+    if (thread_sp)
+      m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
+  }
+  return m_reg_context_sp;
+}
+
+bool StackFrame::HasDebugInformation() {
+  GetSymbolContext(eSymbolContextLineEntry);
+  return m_sc.line_entry.IsValid();
 }
 
 ValueObjectSP
-StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    if (m_is_history_frame)
-        return ValueObjectSP();
-
-    // Check to make sure we aren't already tracking this variable?
-    ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
-    if (!valobj_sp)
-    {
-        // We aren't already tracking this global
-        VariableList *var_list = GetVariableList (true);
-        // If this frame has no variables, create a new list
-        if (var_list == nullptr)
-            m_variable_list_sp.reset (new VariableList());
-
-        // Add the global/static variable to this frame
-        m_variable_list_sp->AddVariable (variable_sp);
-
-        // Now make a value object for it so we can track its changes
-        valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
-    }
+StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp,
+                                           DynamicValueType use_dynamic) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  ValueObjectSP valobj_sp;
+  if (m_is_history_frame) {
     return valobj_sp;
-}
-
-bool
-StackFrame::IsInlined ()
-{
-    if (m_sc.block == nullptr)
-        GetSymbolContext (eSymbolContextBlock);
-    if (m_sc.block)
-        return m_sc.block->GetContainingInlinedBlock() != nullptr;
-    return false;
-}
-
-lldb::LanguageType
-StackFrame::GetLanguage ()
-{
-    CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
-    if (cu)
-        return cu->GetLanguage();
-    return lldb::eLanguageTypeUnknown;
-}
-
-lldb::LanguageType
-StackFrame::GuessLanguage ()
-{
-    LanguageType lang_type = GetLanguage();
-    
-    if (lang_type == eLanguageTypeUnknown)
-    {
-        Function *f = GetSymbolContext(eSymbolContextFunction).function;
-        if (f)
-        {
-            lang_type = f->GetMangled().GuessLanguage();
-        }
+  }
+  VariableList *var_list = GetVariableList(true);
+  if (var_list) {
+    // Make sure the variable is a frame variable
+    const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
+    const uint32_t num_variables = var_list->GetSize();
+    if (var_idx < num_variables) {
+      valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
+      if (!valobj_sp) {
+        if (m_variable_list_value_objects.GetSize() < num_variables)
+          m_variable_list_value_objects.Resize(num_variables);
+        valobj_sp = ValueObjectVariable::Create(this, variable_sp);
+        m_variable_list_value_objects.SetValueObjectAtIndex(var_idx, valobj_sp);
+      }
     }
-    
-    return lang_type;
+  }
+  if (use_dynamic != eNoDynamicValues && valobj_sp) {
+    ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
+    if (dynamic_sp)
+      return dynamic_sp;
+  }
+  return valobj_sp;
 }
 
-namespace
-{
-    std::pair<const Instruction::Operand *, int64_t>
-    GetBaseExplainingValue(const Instruction::Operand &operand,
-                           RegisterContext &register_context,
-                           lldb::addr_t value)
-    {
-        switch(operand.m_type)
-        {
-        case Instruction::Operand::Type::Dereference:
-        case Instruction::Operand::Type::Immediate:
-        case Instruction::Operand::Type::Invalid:
-        case Instruction::Operand::Type::Product:
-            // These are not currently interesting
-            return std::make_pair(nullptr, 0);
-        case Instruction::Operand::Type::Sum:
-            {
-                const Instruction::Operand *immediate_child = nullptr;
-                const Instruction::Operand *variable_child = nullptr;
-                if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate)
-                {
-                    immediate_child = &operand.m_children[0];
-                    variable_child = &operand.m_children[1];
-                }
-                else if (operand.m_children[1].m_type == Instruction::Operand::Type::Immediate)
-                {
-                    immediate_child = &operand.m_children[1];
-                    variable_child = &operand.m_children[0];
-                }
-                if (!immediate_child)
-                {
-                    return std::make_pair(nullptr, 0);
-                }
-                lldb::addr_t adjusted_value = value;
-                if (immediate_child->m_negative)
-                {
-                    adjusted_value += immediate_child->m_immediate;
-                }
-                else
-                {
-                    adjusted_value -= immediate_child->m_immediate;
-                }
-                std::pair<const Instruction::Operand *, int64_t> base_and_offset = GetBaseExplainingValue(*variable_child, register_context, adjusted_value);
-                if (!base_and_offset.first)
-                {
-                    return std::make_pair(nullptr, 0);
-                }
-                if (immediate_child->m_negative)
-                {
-                    base_and_offset.second -= immediate_child->m_immediate;
-                }
-                else
-                {
-                    base_and_offset.second += immediate_child->m_immediate;
-                }
-                return base_and_offset;
-            }
-        case Instruction::Operand::Type::Register:
-            {
-                const RegisterInfo *info = register_context.GetRegisterInfoByName(operand.m_register.AsCString());
-                if (!info)
-                {
-                    return std::make_pair(nullptr, 0);
-                }
-                RegisterValue reg_value;
-                if (!register_context.ReadRegister(info, reg_value))
-                {
-                    return std::make_pair(nullptr, 0);
-                }
-                if (reg_value.GetAsUInt64() == value)
-                {
-                    return std::make_pair(&operand, 0);
-                }
-                else
-                {
-                    return std::make_pair(nullptr, 0);
-                }
-            }
-        }
+ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp,
+                                              DynamicValueType use_dynamic) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  if (m_is_history_frame)
+    return ValueObjectSP();
+
+  // Check to make sure we aren't already tracking this variable?
+  ValueObjectSP valobj_sp(
+      GetValueObjectForFrameVariable(variable_sp, use_dynamic));
+  if (!valobj_sp) {
+    // We aren't already tracking this global
+    VariableList *var_list = GetVariableList(true);
+    // If this frame has no variables, create a new list
+    if (var_list == nullptr)
+      m_variable_list_sp.reset(new VariableList());
+
+    // Add the global/static variable to this frame
+    m_variable_list_sp->AddVariable(variable_sp);
+
+    // Now make a value object for it so we can track its changes
+    valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
+  }
+  return valobj_sp;
+}
+
+bool StackFrame::IsInlined() {
+  if (m_sc.block == nullptr)
+    GetSymbolContext(eSymbolContextBlock);
+  if (m_sc.block)
+    return m_sc.block->GetContainingInlinedBlock() != nullptr;
+  return false;
+}
+
+lldb::LanguageType StackFrame::GetLanguage() {
+  CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
+  if (cu)
+    return cu->GetLanguage();
+  return lldb::eLanguageTypeUnknown;
+}
+
+lldb::LanguageType StackFrame::GuessLanguage() {
+  LanguageType lang_type = GetLanguage();
+
+  if (lang_type == eLanguageTypeUnknown) {
+    Function *f = GetSymbolContext(eSymbolContextFunction).function;
+    if (f) {
+      lang_type = f->GetMangled().GuessLanguage();
     }
-    
-    std::pair<const Instruction::Operand *, int64_t>
-    GetBaseExplainingDereference(const Instruction::Operand &operand,
-                                 RegisterContext &register_context,
-                                 lldb::addr_t addr)
-    {
-        if (operand.m_type == Instruction::Operand::Type::Dereference)
-        {
-            return GetBaseExplainingValue(operand.m_children[0],
-                                          register_context,
-                                          addr);
-        }
-        return std::make_pair(nullptr, 0);
+  }
+
+  return lang_type;
+}
+
+namespace {
+std::pair<const Instruction::Operand *, int64_t>
+GetBaseExplainingValue(const Instruction::Operand &operand,
+                       RegisterContext &register_context, lldb::addr_t value) {
+  switch (operand.m_type) {
+  case Instruction::Operand::Type::Dereference:
+  case Instruction::Operand::Type::Immediate:
+  case Instruction::Operand::Type::Invalid:
+  case Instruction::Operand::Type::Product:
+    // These are not currently interesting
+    return std::make_pair(nullptr, 0);
+  case Instruction::Operand::Type::Sum: {
+    const Instruction::Operand *immediate_child = nullptr;
+    const Instruction::Operand *variable_child = nullptr;
+    if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
+      immediate_child = &operand.m_children[0];
+      variable_child = &operand.m_children[1];
+    } else if (operand.m_children[1].m_type ==
+               Instruction::Operand::Type::Immediate) {
+      immediate_child = &operand.m_children[1];
+      variable_child = &operand.m_children[0];
     }
+    if (!immediate_child) {
+      return std::make_pair(nullptr, 0);
+    }
+    lldb::addr_t adjusted_value = value;
+    if (immediate_child->m_negative) {
+      adjusted_value += immediate_child->m_immediate;
+    } else {
+      adjusted_value -= immediate_child->m_immediate;
+    }
+    std::pair<const Instruction::Operand *, int64_t> base_and_offset =
+        GetBaseExplainingValue(*variable_child, register_context,
+                               adjusted_value);
+    if (!base_and_offset.first) {
+      return std::make_pair(nullptr, 0);
+    }
+    if (immediate_child->m_negative) {
+      base_and_offset.second -= immediate_child->m_immediate;
+    } else {
+      base_and_offset.second += immediate_child->m_immediate;
+    }
+    return base_and_offset;
+  }
+  case Instruction::Operand::Type::Register: {
+    const RegisterInfo *info =
+        register_context.GetRegisterInfoByName(operand.m_register.AsCString());
+    if (!info) {
+      return std::make_pair(nullptr, 0);
+    }
+    RegisterValue reg_value;
+    if (!register_context.ReadRegister(info, reg_value)) {
+      return std::make_pair(nullptr, 0);
+    }
+    if (reg_value.GetAsUInt64() == value) {
+      return std::make_pair(&operand, 0);
+    } else {
+      return std::make_pair(nullptr, 0);
+    }
+  }
+  }
+}
+
+std::pair<const Instruction::Operand *, int64_t>
+GetBaseExplainingDereference(const Instruction::Operand &operand,
+                             RegisterContext &register_context,
+                             lldb::addr_t addr) {
+  if (operand.m_type == Instruction::Operand::Type::Dereference) {
+    return GetBaseExplainingValue(operand.m_children[0], register_context,
+                                  addr);
+  }
+  return std::make_pair(nullptr, 0);
+}
 };
 
-lldb::ValueObjectSP
-StackFrame::GuessValueForAddress(lldb::addr_t addr)
-{
-    TargetSP target_sp = CalculateTarget();
-    
-    const ArchSpec &target_arch = target_sp->GetArchitecture();
-    
-    AddressRange pc_range;
-    pc_range.GetBaseAddress() = GetFrameCodeAddress();
-    pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
-    
-    ExecutionContext exe_ctx (shared_from_this());
-    
-    const char *plugin_name = nullptr;
-    const char *flavor = nullptr;
-    const bool prefer_file_cache = false;
-    
-    DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch,
-                                                                     plugin_name,
-                                                                     flavor,
-                                                                     exe_ctx,
-                                                                     pc_range,
-                                                                     prefer_file_cache);
-    
-    if (!disassembler_sp->GetInstructionList().GetSize())
-    {
-        return ValueObjectSP();
-    }
-    
-    InstructionSP instruction_sp = disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
-    
-    llvm::SmallVector<Instruction::Operand, 3> operands;
-    
-    if (!instruction_sp->ParseOperands(operands))
-    {
-        return ValueObjectSP();
-    }
-    
-    RegisterContextSP register_context_sp = GetRegisterContext();
-    
-    if (!register_context_sp)
-    {
-        return ValueObjectSP();
-    }
-    
-    for (const Instruction::Operand &operand : operands)
-    {
-        std::pair<const Instruction::Operand *, int64_t>
-            base_and_offset = GetBaseExplainingDereference(operand, *register_context_sp, addr);
-        
-        if (!base_and_offset.first)
-        {
-            continue;
-        }
-        
-        switch (base_and_offset.first->m_type)
-        {
-        case Instruction::Operand::Type::Immediate:
-            {
-                lldb_private::Address addr;
-                if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate + base_and_offset.second, addr))
-                {
-                    TypeSystem *c_type_system = target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
-                    if (!c_type_system)
-                    {
-                        return ValueObjectSP();
-                    }
-                    else
-                    {
-                        CompilerType void_ptr_type = c_type_system->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar).GetPointerType();
-                        return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
-                    }
-                }
-                else
-                {
-                    return ValueObjectSP();
-                }
-                break;
-            }
-        case Instruction::Operand::Type::Register:
-            {
-                return GuessValueForRegisterAndOffset(base_and_offset.first->m_register, base_and_offset.second);
-            }
-        default:
-            return ValueObjectSP();
-        }
-        
-    }
+lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
+  TargetSP target_sp = CalculateTarget();
 
+  const ArchSpec &target_arch = target_sp->GetArchitecture();
+
+  AddressRange pc_range;
+  pc_range.GetBaseAddress() = GetFrameCodeAddress();
+  pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
+
+  ExecutionContext exe_ctx(shared_from_this());
+
+  const char *plugin_name = nullptr;
+  const char *flavor = nullptr;
+  const bool prefer_file_cache = false;
+
+  DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
+      target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
+
+  if (!disassembler_sp->GetInstructionList().GetSize()) {
     return ValueObjectSP();
-}
+  }
 
-namespace
-{
-    ValueObjectSP
-    GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, int64_t offset)
-    {
-        if (offset < 0 || uint64_t(offset) >= parent->GetByteSize())
-        {
-            return ValueObjectSP();
-        }
-        
-        if (parent->IsPointerOrReferenceType())
-        {
-            return parent;
-        }
-        
-        for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci)
-        {
-            const bool can_create = true;
-            ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
-            
-            if (!child_sp)
-            {
-                return ValueObjectSP();
-            }
-            
-            int64_t child_offset = child_sp->GetByteOffset();
-            int64_t child_size = child_sp->GetByteSize();
-            
-            if (offset >= child_offset &&
-                offset < (child_offset + child_size))
-            {
-                return GetValueForOffset(frame, child_sp, offset - child_offset);
-            }
-        }
-        
-        if (offset == 0)
-        {
-            return parent;
-        }
-        else
-        {
-            return ValueObjectSP();
-        }
+  InstructionSP instruction_sp =
+      disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
+
+  llvm::SmallVector<Instruction::Operand, 3> operands;
+
+  if (!instruction_sp->ParseOperands(operands)) {
+    return ValueObjectSP();
+  }
+
+  RegisterContextSP register_context_sp = GetRegisterContext();
+
+  if (!register_context_sp) {
+    return ValueObjectSP();
+  }
+
+  for (const Instruction::Operand &operand : operands) {
+    std::pair<const Instruction::Operand *, int64_t> base_and_offset =
+        GetBaseExplainingDereference(operand, *register_context_sp, addr);
+
+    if (!base_and_offset.first) {
+      continue;
     }
-    
-    ValueObjectSP
-    GetValueForDereferincingOffset(StackFrame &frame, ValueObjectSP &base, int64_t offset)
-    {
-        // base is a pointer to something
-        // offset is the thing to add to the pointer
-        // We return the most sensible ValueObject for the result of *(base+offset)
 
-        if (!base->IsPointerOrReferenceType())
-        {
-            return ValueObjectSP();
+    switch (base_and_offset.first->m_type) {
+    case Instruction::Operand::Type::Immediate: {
+      lldb_private::Address addr;
+      if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
+                                            base_and_offset.second,
+                                        addr)) {
+        TypeSystem *c_type_system =
+            target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
+        if (!c_type_system) {
+          return ValueObjectSP();
+        } else {
+          CompilerType void_ptr_type =
+              c_type_system
+                  ->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
+                  .GetPointerType();
+          return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
         }
-    
-        Error error;
-        ValueObjectSP pointee = base->Dereference(error);
-        
-        if (offset >= pointee->GetByteSize())
-        {
-            int64_t index = offset / pointee->GetByteSize();
-            offset = offset % pointee->GetByteSize();
-            const bool can_create = true;
-            pointee = base->GetSyntheticArrayMember(index, can_create);
-        }
-        
-        if (!pointee || error.Fail())
-        {
-            return ValueObjectSP();
-        }
-        
-        return GetValueForOffset(frame, pointee, offset);
-    }
-    
-    //------------------------------------------------------------------
-    /// Attempt to reconstruct the ValueObject for the address contained in a
-    /// given register plus an offset.
-    ///
-    /// @params [in] frame
-    ///   The current stack frame.
-    ///
-    /// @params [in] reg
-    ///   The register.
-    ///
-    /// @params [in] offset
-    ///   The offset from the register.
-    ///
-    /// @param [in] disassembler
-    ///   A disassembler containing instructions valid up to the current PC.
-    ///
-    /// @param [in] variables
-    ///   The variable list from the current frame,
-    ///
-    /// @param [in] pc
-    ///   The program counter for the instruction considered the 'user'.
-    ///
-    /// @return
-    ///   A string describing the base for the ExpressionPath.  This could be a
-    ///     variable, a register value, an argument, or a function return value.
-    ///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
-    //------------------------------------------------------------------
-    lldb::ValueObjectSP
-    DoGuessValueAt(StackFrame &frame, ConstString reg, int64_t offset, Disassembler &disassembler, VariableList &variables, const Address &pc)
-    {
-        // Example of operation for Intel:
-        //
-        // +14: movq   -0x8(%rbp), %rdi
-        // +18: movq   0x8(%rdi), %rdi
-        // +22: addl   0x4(%rdi), %eax
-        //
-        // f, a pointer to a struct, is known to be at -0x8(%rbp).
-        //
-        // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18 that assigns to rdi, and calls itself recursively for that dereference
-        //   DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at +14 that assigns to rdi, and calls itself recursively for that derefernece
-        //     DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the variable list.
-        //     Returns a ValueObject for f.  (That's what was stored at rbp-8 at +14)
-        //   Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8 at +18)
-        // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at rdi+4 at +22)
-        
-        // First, check the variable list to see if anything is at the specified location.
-        for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi)
-        {
-            VariableSP var_sp = variables.GetVariableAtIndex(vi);
-            DWARFExpression &dwarf_expression = var_sp->LocationExpression();
-            
-            const RegisterInfo *expression_reg;
-            int64_t expression_offset;
-            ExecutionContext exe_ctx;
-            
-            if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg, expression_offset))
-            {
-                if ((reg == ConstString(expression_reg->name) ||
-                     reg == ConstString(expression_reg->alt_name)) &&
-                    expression_offset == offset)
-                {
-                    return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
-                }
-            }
-        }
-        
-        bool is_in_return_register = false;
-        ABISP abi_sp = frame.CalculateProcess()->GetABI();
-        RegisterInfo return_register_info;
-
-        if (abi_sp)
-        {
-            const char *return_register_name;
-            const RegisterInfo *reg_info = nullptr;
-            if (abi_sp->GetPointerReturnRegister(return_register_name) &&
-                reg == ConstString(return_register_name) &&
-                (reg_info = frame.GetRegisterContext()->GetRegisterInfoByName(return_register_name)))
-            {
-                is_in_return_register = true;
-                return_register_info = *reg_info;
-            }
-        }
-        
-        const uint32_t current_inst = disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
-        if (current_inst == UINT32_MAX)
-        {
-            return ValueObjectSP();
-        }
-        
-        ValueObjectSP source_path;
-        
-        for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii)
-        {
-            // This is not an exact algorithm, and it sacrifices accuracy for generality.
-            // Recognizing "mov" and "ld" instructions –– and which are their source and
-            // destination operands -- is something the disassembler should do for us.
-            InstructionSP instruction_sp = disassembler.GetInstructionList().GetInstructionAtIndex(ii);
-            
-            if (is_in_return_register && instruction_sp->IsCall())
-            {
-                llvm::SmallVector<Instruction::Operand, 1> operands;
-                if (!instruction_sp->ParseOperands(operands) || operands.size() != 1)
-                {
-                    continue;
-                }
-                
-                switch (operands[0].m_type)
-                {
-                default:
-                    break;
-                case Instruction::Operand::Type::Immediate:
-                    {
-                        SymbolContext sc;
-                        Address load_address;
-                        if (!frame.CalculateTarget()->ResolveLoadAddress(operands[0].m_immediate, load_address))
-                        {
-                            break;
-                        }
-                        frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(load_address, eSymbolContextFunction, sc);
-                        if (!sc.function)
-                        {
-                            break;
-                        }
-                        CompilerType function_type = sc.function->GetCompilerType();
-                        if (!function_type.IsFunctionType())
-                        {
-                            break;
-                        }
-                        CompilerType return_type = function_type.GetFunctionReturnType();
-                        RegisterValue return_value;
-                        if (!frame.GetRegisterContext()->ReadRegister(&return_register_info, return_value))
-                        {
-                            break;
-                        }
-                        std::string name_str(sc.function->GetName().AsCString("<unknown function>"));
-                        name_str.append("()");
-                        Address return_value_address(return_value.GetAsUInt64());
-                        ValueObjectSP return_value_sp = ValueObjectMemory::Create(&frame, name_str.c_str(), return_value_address, return_type);
-                        return GetValueForDereferincingOffset(frame, return_value_sp, offset);
-                    }
-                }
-
-                continue;
-            }
-            
-            llvm::SmallVector<Instruction::Operand, 2> operands;
-            if (!instruction_sp->ParseOperands(operands) || operands.size() != 2)
-            {
-                continue;
-            }
-            
-            Instruction::Operand *register_operand = nullptr;
-            Instruction::Operand *origin_operand = nullptr;
-            if (operands[0].m_type == Instruction::Operand::Type::Register &&
-                operands[0].m_clobbered == true &&
-                operands[0].m_register == reg)
-            {
-                register_operand = &operands[0];
-                origin_operand = &operands[1];
-            }
-            else if (operands[1].m_type == Instruction::Operand::Type::Register &&
-                     operands[1].m_clobbered == true &&
-                     operands[1].m_register == reg)
-            {
-                register_operand = &operands[1];
-                origin_operand = &operands[0];
-            }
-            else
-            {
-                continue;
-            }
-            
-            // We have an origin operand.  Can we track its value down?
-            switch (origin_operand->m_type)
-            {
-            default:
-                break;
-            case Instruction::Operand::Type::Register:
-                source_path = DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler, variables, instruction_sp->GetAddress());
-                break;
-            case Instruction::Operand::Type::Dereference:
-                {
-                    const Instruction::Operand &pointer = origin_operand->m_children[0];
-                    switch (pointer.m_type)
-                    {
-                    default:
-                        break;
-                    case Instruction::Operand::Type::Register:
-                        source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler, variables, instruction_sp->GetAddress());
-                        if (source_path)
-                        {
-                            Error err;
-                            source_path = source_path->Dereference(err);
-                            if (!err.Success())
-                            {
-                                source_path.reset();
-                            }
-                        }
-                        break;
-                    case Instruction::Operand::Type::Sum:
-                        {
-                            const Instruction::Operand *origin_register = nullptr;
-                            const Instruction::Operand *origin_offset = nullptr;
-                            if (pointer.m_children.size() != 2)
-                            {
-                                break;
-                            }
-                            if (pointer.m_children[0].m_type == Instruction::Operand::Type::Register &&
-                                pointer.m_children[1].m_type == Instruction::Operand::Type::Immediate)
-                            {
-                                origin_register = &pointer.m_children[0];
-                                origin_offset = &pointer.m_children[1];
-                            }
-                            else if (pointer.m_children[1].m_type == Instruction::Operand::Type::Register &&
-                                     pointer.m_children[0].m_type == Instruction::Operand::Type::Immediate)
-                            {
-                                origin_register = &pointer.m_children[1];
-                                origin_offset = &pointer.m_children[0];
-                            }
-                            if (!origin_register)
-                            {
-                                break;
-                            }
-                            int64_t signed_origin_offset = origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate) : origin_offset->m_immediate;
-                            source_path = DoGuessValueAt(frame, origin_register->m_register, signed_origin_offset, disassembler, variables, instruction_sp->GetAddress());
-                            if (!source_path)
-                            {
-                                break;
-                            }
-                            source_path = GetValueForDereferincingOffset(frame, source_path, offset);
-                            break;
-                        }
-                    }
-                }
-            }
-            
-            if (source_path)
-            {
-                return source_path;
-            }
-        }
-        
+      } else {
         return ValueObjectSP();
+      }
+      break;
     }
+    case Instruction::Operand::Type::Register: {
+      return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
+                                            base_and_offset.second);
+    }
+    default:
+      return ValueObjectSP();
+    }
+  }
+
+  return ValueObjectSP();
 }
 
-lldb::ValueObjectSP
-StackFrame::GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
-{
-    TargetSP target_sp = CalculateTarget();
-    
-    const ArchSpec &target_arch = target_sp->GetArchitecture();
+namespace {
+ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
+                                int64_t offset) {
+  if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
+    return ValueObjectSP();
+  }
 
-    Block *frame_block = GetFrameBlock();
-    
-    if (!frame_block)
-    {
-        return ValueObjectSP();
+  if (parent->IsPointerOrReferenceType()) {
+    return parent;
+  }
+
+  for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) {
+    const bool can_create = true;
+    ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
+
+    if (!child_sp) {
+      return ValueObjectSP();
     }
 
-    Function *function = frame_block->CalculateSymbolContextFunction();
-    if (!function)
-    {
-        return ValueObjectSP();
+    int64_t child_offset = child_sp->GetByteOffset();
+    int64_t child_size = child_sp->GetByteSize();
+
+    if (offset >= child_offset && offset < (child_offset + child_size)) {
+      return GetValueForOffset(frame, child_sp, offset - child_offset);
     }
-    
-    AddressRange pc_range = function->GetAddressRange();
+  }
 
-    if (GetFrameCodeAddress().GetFileAddress() < pc_range.GetBaseAddress().GetFileAddress() ||
-        GetFrameCodeAddress().GetFileAddress() - pc_range.GetBaseAddress().GetFileAddress() >= pc_range.GetByteSize())
-    {
-        return ValueObjectSP();
+  if (offset == 0) {
+    return parent;
+  } else {
+    return ValueObjectSP();
+  }
+}
+
+ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
+                                             ValueObjectSP &base,
+                                             int64_t offset) {
+  // base is a pointer to something
+  // offset is the thing to add to the pointer
+  // We return the most sensible ValueObject for the result of *(base+offset)
+
+  if (!base->IsPointerOrReferenceType()) {
+    return ValueObjectSP();
+  }
+
+  Error error;
+  ValueObjectSP pointee = base->Dereference(error);
+
+  if (offset >= pointee->GetByteSize()) {
+    int64_t index = offset / pointee->GetByteSize();
+    offset = offset % pointee->GetByteSize();
+    const bool can_create = true;
+    pointee = base->GetSyntheticArrayMember(index, can_create);
+  }
+
+  if (!pointee || error.Fail()) {
+    return ValueObjectSP();
+  }
+
+  return GetValueForOffset(frame, pointee, offset);
+}
+
+//------------------------------------------------------------------
+/// Attempt to reconstruct the ValueObject for the address contained in a
+/// given register plus an offset.
+///
+/// @params [in] frame
+///   The current stack frame.
+///
+/// @params [in] reg
+///   The register.
+///
+/// @params [in] offset
+///   The offset from the register.
+///
+/// @param [in] disassembler
+///   A disassembler containing instructions valid up to the current PC.
+///
+/// @param [in] variables
+///   The variable list from the current frame,
+///
+/// @param [in] pc
+///   The program counter for the instruction considered the 'user'.
+///
+/// @return
+///   A string describing the base for the ExpressionPath.  This could be a
+///     variable, a register value, an argument, or a function return value.
+///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
+//------------------------------------------------------------------
+lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
+                                   int64_t offset, Disassembler &disassembler,
+                                   VariableList &variables, const Address &pc) {
+  // Example of operation for Intel:
+  //
+  // +14: movq   -0x8(%rbp), %rdi
+  // +18: movq   0x8(%rdi), %rdi
+  // +22: addl   0x4(%rdi), %eax
+  //
+  // f, a pointer to a struct, is known to be at -0x8(%rbp).
+  //
+  // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18
+  // that assigns to rdi, and calls itself recursively for that dereference
+  //   DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
+  //   +14 that assigns to rdi, and calls itself recursively for that
+  //   derefernece
+  //     DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
+  //     variable list.
+  //     Returns a ValueObject for f.  (That's what was stored at rbp-8 at +14)
+  //   Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
+  //   at +18)
+  // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
+  // rdi+4 at +22)
+
+  // First, check the variable list to see if anything is at the specified
+  // location.
+  for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) {
+    VariableSP var_sp = variables.GetVariableAtIndex(vi);
+    DWARFExpression &dwarf_expression = var_sp->LocationExpression();
+
+    const RegisterInfo *expression_reg;
+    int64_t expression_offset;
+    ExecutionContext exe_ctx;
+
+    if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg,
+                                                 expression_offset)) {
+      if ((reg == ConstString(expression_reg->name) ||
+           reg == ConstString(expression_reg->alt_name)) &&
+          expression_offset == offset) {
+        return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
+      }
     }
-    
-    ExecutionContext exe_ctx (shared_from_this());
-    
-    const char *plugin_name = nullptr;
-    const char *flavor = nullptr;
-    const bool prefer_file_cache = false;
-    DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch,
-                                                                     plugin_name,
-                                                                     flavor,
-                                                                     exe_ctx,
-                                                                     pc_range,
-                                                                     prefer_file_cache);
-    
-    if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize())
-    {
-        return ValueObjectSP();
+  }
+
+  bool is_in_return_register = false;
+  ABISP abi_sp = frame.CalculateProcess()->GetABI();
+  RegisterInfo return_register_info;
+
+  if (abi_sp) {
+    const char *return_register_name;
+    const RegisterInfo *reg_info = nullptr;
+    if (abi_sp->GetPointerReturnRegister(return_register_name) &&
+        reg == ConstString(return_register_name) &&
+        (reg_info = frame.GetRegisterContext()->GetRegisterInfoByName(
+             return_register_name))) {
+      is_in_return_register = true;
+      return_register_info = *reg_info;
     }
-    
-    const bool get_file_globals = false;
-    VariableList *variables = GetVariableList(get_file_globals);
-    
-    if (!variables)
-    {
-        return ValueObjectSP();
-    }
-    
-    return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables, GetFrameCodeAddress());
-}
+  }
 
-TargetSP
-StackFrame::CalculateTarget ()
-{
-    TargetSP target_sp;
-    ThreadSP thread_sp(GetThread());
-    if (thread_sp)
-    {
-        ProcessSP process_sp (thread_sp->CalculateProcess());
-        if (process_sp)
-            target_sp = process_sp->CalculateTarget();
-    }
-    return target_sp;
-}
+  const uint32_t current_inst =
+      disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
+  if (current_inst == UINT32_MAX) {
+    return ValueObjectSP();
+  }
 
-ProcessSP
-StackFrame::CalculateProcess ()
-{
-    ProcessSP process_sp;
-    ThreadSP thread_sp(GetThread());
-    if (thread_sp)
-        process_sp = thread_sp->CalculateProcess();
-    return process_sp;
-}
+  ValueObjectSP source_path;
 
-ThreadSP
-StackFrame::CalculateThread ()
-{
-    return GetThread();
-}
+  for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
+    // This is not an exact algorithm, and it sacrifices accuracy for
+    // generality.
+    // Recognizing "mov" and "ld" instructions –– and which are their source and
+    // destination operands -- is something the disassembler should do for us.
+    InstructionSP instruction_sp =
+        disassembler.GetInstructionList().GetInstructionAtIndex(ii);
 
-StackFrameSP
-StackFrame::CalculateStackFrame ()
-{
-    return shared_from_this();
-}
+    if (is_in_return_register && instruction_sp->IsCall()) {
+      llvm::SmallVector<Instruction::Operand, 1> operands;
+      if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
+        continue;
+      }
 
-void
-StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
-{
-    exe_ctx.SetContext (shared_from_this());
-}
-
-void
-StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
-{
-    if (strm == nullptr)
-        return;
-
-    GetSymbolContext(eSymbolContextEverything);
-    ExecutionContext exe_ctx (shared_from_this());
-    StreamString s;
-    
-    if (frame_marker)
-        s.PutCString(frame_marker);
-
-    const FormatEntity::Entry *frame_format = nullptr;
-    Target *target = exe_ctx.GetTargetPtr();
-    if (target)
-        frame_format = target->GetDebugger().GetFrameFormat();
-    if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false))
-    {
-        strm->Write(s.GetData(), s.GetSize());
-    }
-    else
-    {
-        Dump (strm, true, false);
-        strm->EOL();
-    }
-}
-
-void
-StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
-{
-    if (strm == nullptr)
-        return;
-
-    if (show_frame_index)
-        strm->Printf("frame #%u: ", m_frame_index);
-    ExecutionContext exe_ctx (shared_from_this());
-    Target *target = exe_ctx.GetTargetPtr();
-    strm->Printf("0x%0*" PRIx64 " ",
-                 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
-                 GetFrameCodeAddress().GetLoadAddress(target));
-    GetSymbolContext(eSymbolContextEverything);
-    const bool show_module = true;
-    const bool show_inline = true;
-    const bool show_function_arguments = true;
-    const bool show_function_name = true;
-    m_sc.DumpStopContext (strm, 
-                          exe_ctx.GetBestExecutionContextScope(), 
-                          GetFrameCodeAddress(), 
-                          show_fullpaths, 
-                          show_module, 
-                          show_inline,
-                          show_function_arguments,
-                          show_function_name);
-}
-
-void
-StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
-    m_variable_list_sp = prev_frame.m_variable_list_sp;
-    m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
-    if (!m_disassembly.GetString().empty())
-        m_disassembly.GetString().swap (m_disassembly.GetString());
-}
-
-void
-StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-    assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
-    m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
-    assert (GetThread() == curr_frame.GetThread());
-    m_frame_index = curr_frame.m_frame_index;
-    m_concrete_frame_index = curr_frame.m_concrete_frame_index;
-    m_reg_context_sp = curr_frame.m_reg_context_sp;
-    m_frame_code_addr = curr_frame.m_frame_code_addr;
-    assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
-    assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
-    assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
-    assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function);
-    m_sc = curr_frame.m_sc;
-    m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
-    m_flags.Set (m_sc.GetResolvedMask());
-    m_frame_base.Clear();
-    m_frame_base_error.Clear();
-}
-    
-bool
-StackFrame::HasCachedData () const
-{
-    if (m_variable_list_sp)
-        return true;
-    if (m_variable_list_value_objects.GetSize() > 0)
-        return true;
-    if (!m_disassembly.GetString().empty())
-        return true;
-    return false;
-}
-
-bool
-StackFrame::GetStatus (Stream& strm,
-                       bool show_frame_info,
-                       bool show_source,
-                       const char *frame_marker)
-{
-    
-    if (show_frame_info)
-    {
-        strm.Indent();
-        DumpUsingSettingsFormat (&strm, frame_marker);
-    }
-    
-    if (show_source)
-    {
-        ExecutionContext exe_ctx (shared_from_this());
-        bool have_source = false, have_debuginfo = false;
-        Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
-        Target *target = exe_ctx.GetTargetPtr();
-        if (target)
-        {
-            Debugger &debugger = target->GetDebugger();
-            const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
-            const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
-            disasm_display = debugger.GetStopDisassemblyDisplay ();
-
-            GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
-            if (m_sc.comp_unit && m_sc.line_entry.IsValid())
-            {
-                have_debuginfo = true;
-                if (source_lines_before > 0 || source_lines_after > 0)
-                {
-                    size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
-                                                                                      m_sc.line_entry.line,
-                                                                                      source_lines_before,
-                                                                                      source_lines_after,
-                                                                                      "->",
-                                                                                      &strm);
-                    if (num_lines != 0)
-                        have_source = true;
-                    // TODO: Give here a one time warning if source file is missing.
-                }
-            }
-            switch (disasm_display)
-            {
-            case Debugger::eStopDisassemblyTypeNever:
-                break;
-
-            case Debugger::eStopDisassemblyTypeNoDebugInfo:
-                if (have_debuginfo)
-                    break;
-                LLVM_FALLTHROUGH;
-
-            case Debugger::eStopDisassemblyTypeNoSource:
-                if (have_source)
-                    break;
-                LLVM_FALLTHROUGH;
-
-            case Debugger::eStopDisassemblyTypeAlways:
-                if (target)
-                {
-                    const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
-                    if (disasm_lines > 0)
-                    {
-                        const ArchSpec &target_arch = target->GetArchitecture();
-                        AddressRange pc_range;
-                        pc_range.GetBaseAddress() = GetFrameCodeAddress();
-                        pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
-                        const char *plugin_name = nullptr;
-                        const char *flavor = nullptr;
-                        Disassembler::Disassemble (target->GetDebugger(),
-                                                   target_arch,
-                                                   plugin_name,
-                                                   flavor,
-                                                   exe_ctx,
-                                                   pc_range,
-                                                   disasm_lines,
-                                                   0,
-                                                   Disassembler::eOptionMarkPCAddress,
-                                                   strm);
-                    }
-                }
-                break;
-            }
+      switch (operands[0].m_type) {
+      default:
+        break;
+      case Instruction::Operand::Type::Immediate: {
+        SymbolContext sc;
+        Address load_address;
+        if (!frame.CalculateTarget()->ResolveLoadAddress(
+                operands[0].m_immediate, load_address)) {
+          break;
         }
+        frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
+            load_address, eSymbolContextFunction, sc);
+        if (!sc.function) {
+          break;
+        }
+        CompilerType function_type = sc.function->GetCompilerType();
+        if (!function_type.IsFunctionType()) {
+          break;
+        }
+        CompilerType return_type = function_type.GetFunctionReturnType();
+        RegisterValue return_value;
+        if (!frame.GetRegisterContext()->ReadRegister(&return_register_info,
+                                                      return_value)) {
+          break;
+        }
+        std::string name_str(
+            sc.function->GetName().AsCString("<unknown function>"));
+        name_str.append("()");
+        Address return_value_address(return_value.GetAsUInt64());
+        ValueObjectSP return_value_sp = ValueObjectMemory::Create(
+            &frame, name_str.c_str(), return_value_address, return_type);
+        return GetValueForDereferincingOffset(frame, return_value_sp, offset);
+      }
+      }
+
+      continue;
     }
+
+    llvm::SmallVector<Instruction::Operand, 2> operands;
+    if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
+      continue;
+    }
+
+    Instruction::Operand *register_operand = nullptr;
+    Instruction::Operand *origin_operand = nullptr;
+    if (operands[0].m_type == Instruction::Operand::Type::Register &&
+        operands[0].m_clobbered == true && operands[0].m_register == reg) {
+      register_operand = &operands[0];
+      origin_operand = &operands[1];
+    } else if (operands[1].m_type == Instruction::Operand::Type::Register &&
+               operands[1].m_clobbered == true &&
+               operands[1].m_register == reg) {
+      register_operand = &operands[1];
+      origin_operand = &operands[0];
+    } else {
+      continue;
+    }
+
+    // We have an origin operand.  Can we track its value down?
+    switch (origin_operand->m_type) {
+    default:
+      break;
+    case Instruction::Operand::Type::Register:
+      source_path =
+          DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler,
+                         variables, instruction_sp->GetAddress());
+      break;
+    case Instruction::Operand::Type::Dereference: {
+      const Instruction::Operand &pointer = origin_operand->m_children[0];
+      switch (pointer.m_type) {
+      default:
+        break;
+      case Instruction::Operand::Type::Register:
+        source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler,
+                                     variables, instruction_sp->GetAddress());
+        if (source_path) {
+          Error err;
+          source_path = source_path->Dereference(err);
+          if (!err.Success()) {
+            source_path.reset();
+          }
+        }
+        break;
+      case Instruction::Operand::Type::Sum: {
+        const Instruction::Operand *origin_register = nullptr;
+        const Instruction::Operand *origin_offset = nullptr;
+        if (pointer.m_children.size() != 2) {
+          break;
+        }
+        if (pointer.m_children[0].m_type ==
+                Instruction::Operand::Type::Register &&
+            pointer.m_children[1].m_type ==
+                Instruction::Operand::Type::Immediate) {
+          origin_register = &pointer.m_children[0];
+          origin_offset = &pointer.m_children[1];
+        } else if (pointer.m_children[1].m_type ==
+                       Instruction::Operand::Type::Register &&
+                   pointer.m_children[0].m_type ==
+                       Instruction::Operand::Type::Immediate) {
+          origin_register = &pointer.m_children[1];
+          origin_offset = &pointer.m_children[0];
+        }
+        if (!origin_register) {
+          break;
+        }
+        int64_t signed_origin_offset =
+            origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate)
+                                      : origin_offset->m_immediate;
+        source_path = DoGuessValueAt(frame, origin_register->m_register,
+                                     signed_origin_offset, disassembler,
+                                     variables, instruction_sp->GetAddress());
+        if (!source_path) {
+          break;
+        }
+        source_path =
+            GetValueForDereferincingOffset(frame, source_path, offset);
+        break;
+      }
+      }
+    }
+    }
+
+    if (source_path) {
+      return source_path;
+    }
+  }
+
+  return ValueObjectSP();
+}
+}
+
+lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
+                                                               int64_t offset) {
+  TargetSP target_sp = CalculateTarget();
+
+  const ArchSpec &target_arch = target_sp->GetArchitecture();
+
+  Block *frame_block = GetFrameBlock();
+
+  if (!frame_block) {
+    return ValueObjectSP();
+  }
+
+  Function *function = frame_block->CalculateSymbolContextFunction();
+  if (!function) {
+    return ValueObjectSP();
+  }
+
+  AddressRange pc_range = function->GetAddressRange();
+
+  if (GetFrameCodeAddress().GetFileAddress() <
+          pc_range.GetBaseAddress().GetFileAddress() ||
+      GetFrameCodeAddress().GetFileAddress() -
+              pc_range.GetBaseAddress().GetFileAddress() >=
+          pc_range.GetByteSize()) {
+    return ValueObjectSP();
+  }
+
+  ExecutionContext exe_ctx(shared_from_this());
+
+  const char *plugin_name = nullptr;
+  const char *flavor = nullptr;
+  const bool prefer_file_cache = false;
+  DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
+      target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
+
+  if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
+    return ValueObjectSP();
+  }
+
+  const bool get_file_globals = false;
+  VariableList *variables = GetVariableList(get_file_globals);
+
+  if (!variables) {
+    return ValueObjectSP();
+  }
+
+  return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
+                        GetFrameCodeAddress());
+}
+
+TargetSP StackFrame::CalculateTarget() {
+  TargetSP target_sp;
+  ThreadSP thread_sp(GetThread());
+  if (thread_sp) {
+    ProcessSP process_sp(thread_sp->CalculateProcess());
+    if (process_sp)
+      target_sp = process_sp->CalculateTarget();
+  }
+  return target_sp;
+}
+
+ProcessSP StackFrame::CalculateProcess() {
+  ProcessSP process_sp;
+  ThreadSP thread_sp(GetThread());
+  if (thread_sp)
+    process_sp = thread_sp->CalculateProcess();
+  return process_sp;
+}
+
+ThreadSP StackFrame::CalculateThread() { return GetThread(); }
+
+StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
+
+void StackFrame::CalculateExecutionContext(ExecutionContext &exe_ctx) {
+  exe_ctx.SetContext(shared_from_this());
+}
+
+void StackFrame::DumpUsingSettingsFormat(Stream *strm,
+                                         const char *frame_marker) {
+  if (strm == nullptr)
+    return;
+
+  GetSymbolContext(eSymbolContextEverything);
+  ExecutionContext exe_ctx(shared_from_this());
+  StreamString s;
+
+  if (frame_marker)
+    s.PutCString(frame_marker);
+
+  const FormatEntity::Entry *frame_format = nullptr;
+  Target *target = exe_ctx.GetTargetPtr();
+  if (target)
+    frame_format = target->GetDebugger().GetFrameFormat();
+  if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx,
+                                           nullptr, nullptr, false, false)) {
+    strm->Write(s.GetData(), s.GetSize());
+  } else {
+    Dump(strm, true, false);
+    strm->EOL();
+  }
+}
+
+void StackFrame::Dump(Stream *strm, bool show_frame_index,
+                      bool show_fullpaths) {
+  if (strm == nullptr)
+    return;
+
+  if (show_frame_index)
+    strm->Printf("frame #%u: ", m_frame_index);
+  ExecutionContext exe_ctx(shared_from_this());
+  Target *target = exe_ctx.GetTargetPtr();
+  strm->Printf("0x%0*" PRIx64 " ",
+               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
+                      : 16,
+               GetFrameCodeAddress().GetLoadAddress(target));
+  GetSymbolContext(eSymbolContextEverything);
+  const bool show_module = true;
+  const bool show_inline = true;
+  const bool show_function_arguments = true;
+  const bool show_function_name = true;
+  m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
+                       GetFrameCodeAddress(), show_fullpaths, show_module,
+                       show_inline, show_function_arguments,
+                       show_function_name);
+}
+
+void StackFrame::UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  assert(GetStackID() ==
+         prev_frame.GetStackID()); // TODO: remove this after some testing
+  m_variable_list_sp = prev_frame.m_variable_list_sp;
+  m_variable_list_value_objects.Swap(prev_frame.m_variable_list_value_objects);
+  if (!m_disassembly.GetString().empty())
+    m_disassembly.GetString().swap(m_disassembly.GetString());
+}
+
+void StackFrame::UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  assert(GetStackID() ==
+         curr_frame.GetStackID());     // TODO: remove this after some testing
+  m_id.SetPC(curr_frame.m_id.GetPC()); // Update the Stack ID PC value
+  assert(GetThread() == curr_frame.GetThread());
+  m_frame_index = curr_frame.m_frame_index;
+  m_concrete_frame_index = curr_frame.m_concrete_frame_index;
+  m_reg_context_sp = curr_frame.m_reg_context_sp;
+  m_frame_code_addr = curr_frame.m_frame_code_addr;
+  assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
+         m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
+  assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
+         m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
+  assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
+         m_sc.comp_unit == curr_frame.m_sc.comp_unit);
+  assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
+         m_sc.function == curr_frame.m_sc.function);
+  m_sc = curr_frame.m_sc;
+  m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
+  m_flags.Set(m_sc.GetResolvedMask());
+  m_frame_base.Clear();
+  m_frame_base_error.Clear();
+}
+
+bool StackFrame::HasCachedData() const {
+  if (m_variable_list_sp)
     return true;
+  if (m_variable_list_value_objects.GetSize() > 0)
+    return true;
+  if (!m_disassembly.GetString().empty())
+    return true;
+  return false;
+}
+
+bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
+                           const char *frame_marker) {
+
+  if (show_frame_info) {
+    strm.Indent();
+    DumpUsingSettingsFormat(&strm, frame_marker);
+  }
+
+  if (show_source) {
+    ExecutionContext exe_ctx(shared_from_this());
+    bool have_source = false, have_debuginfo = false;
+    Debugger::StopDisassemblyType disasm_display =
+        Debugger::eStopDisassemblyTypeNever;
+    Target *target = exe_ctx.GetTargetPtr();
+    if (target) {
+      Debugger &debugger = target->GetDebugger();
+      const uint32_t source_lines_before =
+          debugger.GetStopSourceLineCount(true);
+      const uint32_t source_lines_after =
+          debugger.GetStopSourceLineCount(false);
+      disasm_display = debugger.GetStopDisassemblyDisplay();
+
+      GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
+      if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
+        have_debuginfo = true;
+        if (source_lines_before > 0 || source_lines_after > 0) {
+          size_t num_lines =
+              target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
+                  m_sc.line_entry.file, m_sc.line_entry.line,
+                  source_lines_before, source_lines_after, "->", &strm);
+          if (num_lines != 0)
+            have_source = true;
+          // TODO: Give here a one time warning if source file is missing.
+        }
+      }
+      switch (disasm_display) {
+      case Debugger::eStopDisassemblyTypeNever:
+        break;
+
+      case Debugger::eStopDisassemblyTypeNoDebugInfo:
+        if (have_debuginfo)
+          break;
+        LLVM_FALLTHROUGH;
+
+      case Debugger::eStopDisassemblyTypeNoSource:
+        if (have_source)
+          break;
+        LLVM_FALLTHROUGH;
+
+      case Debugger::eStopDisassemblyTypeAlways:
+        if (target) {
+          const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
+          if (disasm_lines > 0) {
+            const ArchSpec &target_arch = target->GetArchitecture();
+            AddressRange pc_range;
+            pc_range.GetBaseAddress() = GetFrameCodeAddress();
+            pc_range.SetByteSize(disasm_lines *
+                                 target_arch.GetMaximumOpcodeByteSize());
+            const char *plugin_name = nullptr;
+            const char *flavor = nullptr;
+            Disassembler::Disassemble(target->GetDebugger(), target_arch,
+                                      plugin_name, flavor, exe_ctx, pc_range,
+                                      disasm_lines, 0,
+                                      Disassembler::eOptionMarkPCAddress, strm);
+          }
+        }
+        break;
+      }
+    }
+  }
+  return true;
 }
