//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/StackFrame.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

// 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)

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, NULL),
    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 (Mutex::eMutexTypeRecursive)
{
    // 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 == false)
    {
        m_id.SetCFA (m_frame_index);
    }

    if (sc_ptr != NULL)
    {
        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),
    m_concrete_frame_index (unwind_frame_index),    
    m_reg_context_sp (reg_context_sp),
    m_id (pc, cfa, NULL),
    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 (Mutex::eMutexTypeRecursive)
{
    if (sc_ptr != NULL)
    {
        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);
    }
}

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, NULL),
    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 (Mutex::eMutexTypeRecursive)
{
    if (sc_ptr != NULL)
    {
        m_sc = *sc_ptr;
        m_flags.Set(m_sc.GetResolvedMask ());
    }
    
    if (m_sc.target_sp.get() == NULL && 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();
        }
    }
}


//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
StackFrame::~StackFrame()
{
}

StackID&
StackFrame::GetStackID()
{
    Mutex::Locker locker(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 == NULL)
            {
                // 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 NULL 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;
}

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)
{
    Mutex::Locker locker(m_mutex);
    m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
    m_id.SetSymbolContextScope (symbol_scope);
}

const Address&
StackFrame::GetFrameCodeAddress()
{
    Mutex::Locker locker(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);
                    }
                }
            }
        }
    }
    return m_frame_code_addr;
}

bool
StackFrame::ChangePC (addr_t pc)
{
    Mutex::Locker locker(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 ()
{
    Mutex::Locker locker(m_mutex);
    if (m_disassembly.GetSize() == 0)
    {
        ExecutionContext exe_ctx (shared_from_this());
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
        {
            const char *plugin_name = NULL;
            const char *flavor = NULL;
            Disassembler::Disassemble (target->GetDebugger(),
                                       target->GetArchitecture(),
                                       plugin_name,
                                       flavor,
                                       exe_ctx,
                                       0,
                                       0,
                                       0,
                                       m_disassembly);
        }
        if (m_disassembly.GetSize() == 0)
            return NULL;
    }
    return m_disassembly.GetData();
}

Block *
StackFrame::GetFrameBlock ()
{
    if (m_sc.block == NULL && 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 withing any inlined function blocks
            // with so we want to use the top most function block.
            return &m_sc.function->GetBlock (false);
        }
    }    
    return NULL;
}

//----------------------------------------------------------------------
// Get the symbol context if we already haven't done so by resolving the
// PC address as much as possible. This way when we pass around a
// 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)
{
    Mutex::Locker locker(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 == NULL)  
                    m_sc.comp_unit = sc.comp_unit;
                if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)  
                    m_sc.function = sc.function;
                if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)  
                    m_sc.block = sc.block;
                if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)  
                    m_sc.symbol = sc.symbol;
                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
                {
                    m_sc.line_entry = sc.line_entry;
                    if (m_sc.target_sp)
                    {
                        // Be sure to apply and file remappings to our file and line
                        // entries when handing out a line entry
                        FileSpec new_file_spec;
                        if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
                            m_sc.line_entry.file = new_file_spec;
                    }
                }
            }
        }
        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)
{
    Mutex::Locker locker(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 v->IsInScope(this); },
                                              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;
        }
    }
    
    return m_variable_list_sp.get();
}

VariableListSP
StackFrame::GetInScopeVariableList (bool get_file_globals)
{
    Mutex::Locker locker(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);

    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](Variable* v) { return v->IsInScope(this); },
                                     var_list_sp.get());
    }
                     
    if (m_sc.comp_unit)
    {
        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 (NULL);
                            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 '-'
                        // Fall through
                    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 == false)
                                {
                                    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 = NULL;
                            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.get() == NULL /* 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 (NULL, NULL, &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 == false))
                                        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.get() == NULL /* 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 = NULL;
                                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);
    }
    return ValueObjectSP();
}

bool
StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
{
    Mutex::Locker locker(m_mutex);
    if (m_cfa_is_valid == false)
    {
        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, NULL, NULL, NULL, loclist_base_addr, NULL, 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();
}

RegisterContextSP
StackFrame::GetRegisterContext ()
{
    Mutex::Locker locker(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)
{
    Mutex::Locker locker(m_mutex);
    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.get() == NULL)
            {
                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);
            }
        }
    }
    if (use_dynamic != eNoDynamicValues && valobj_sp)
    {
        ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
        if (dynamic_sp)
            return dynamic_sp;
    }
    return valobj_sp;
}

ValueObjectSP
StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
{
    Mutex::Locker locker(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 == NULL)
            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 == NULL)
        GetSymbolContext (eSymbolContextBlock);
    if (m_sc.block)
        return m_sc.block->GetContainingInlinedBlock() != NULL;
    return false;
}

lldb::LanguageType
StackFrame::GetLanguage ()
{
    CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
    if (cu)
        return cu->GetLanguage();
    return lldb::eLanguageTypeUnknown;
}

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 == NULL)
        return;

    GetSymbolContext(eSymbolContextEverything);
    ExecutionContext exe_ctx (shared_from_this());
    StreamString s;
    
    if (frame_marker)
        s.PutCString(frame_marker);

    const FormatEntity::Entry *frame_format = NULL;
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
        frame_format = target->GetDebugger().GetFrameFormat();
    if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, NULL, NULL, 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 == NULL)
        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)
{
    Mutex::Locker locker(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)
{
    Mutex::Locker locker(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.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
    assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
    assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
    assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || 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.get())
        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;
                // Fall through to next case

            case Debugger::eStopDisassemblyTypeNoSource:
                if (have_source)
                    break;
                // Fall through to next case

            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 = NULL;
                        const char *flavor = NULL;
                        Disassembler::Disassemble (target->GetDebugger(),
                                                   target_arch,
                                                   plugin_name,
                                                   flavor,
                                                   exe_ctx,
                                                   pc_range,
                                                   disasm_lines,
                                                   0,
                                                   Disassembler::eOptionMarkPCAddress,
                                                   strm);
                    }
                }
                break;
            }
        }
    }
    return true;
}

