//===-- 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/lldb-python.h"

#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/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/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 ()
{
    // 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 ()
{
    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 ()
{
    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()
{
    // 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)
{
    m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
    m_id.SetSymbolContextScope (symbol_scope);
}

const Address&
StackFrame::GetFrameCodeAddress()
{
    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()))
                {
                    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)
{
    // 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 ()
{
    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)
{
    // 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);
        }


        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)
{
    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, 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)
{
    // 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,
                                     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);
            
            bool synthetically_added_instance_object = false;

            if (var_sp)
            {
                var_path.erase (0, name_const_string.GetLength ());
            }
            else if (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)
            {
                valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
                if (!valobj_sp)
                    return 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->GetClangType().GetTypeInfo (NULL);
                            if ((pointer_type_flags & ClangASTType::eTypeIsObjC) &&
                                (pointer_type_flags & ClangASTType::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->GetClangType().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->GetClangType().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->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC)
                                        is_objc_pointer = false;
                                    else if (!valobj_sp->GetClangType().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->GetSyntheticArrayMemberFromPointer (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->GetClangType().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->GetClangType().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->GetClangType().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->GetClangType().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)
{
    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 ()
{
    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)
{
    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)
{
    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;
}

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 char *frame_format = NULL;
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
        frame_format = target->GetDebugger().GetFrameFormat();
    if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
    {
        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;
    m_sc.DumpStopContext (strm, 
                          exe_ctx.GetBestExecutionContextScope(), 
                          GetFrameCodeAddress(), 
                          show_fullpaths, 
                          show_module, 
                          show_inline);
}

void
StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
{
    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)
{
    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;
        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_source = true;
                if (source_lines_before > 0 || source_lines_after > 0)
                {
                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
                                                                                      m_sc.line_entry.line,
                                                                                      source_lines_before,
                                                                                      source_lines_after,
                                                                                      "->",
                                                                                      &strm);
                }
            }
            switch (disasm_display)
            {
            case Debugger::eStopDisassemblyTypeNever:
                break;
                
            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;
}

