//===-- 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, 
                        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 (),
    m_id (pc, cfa, NULL),
    m_frame_code_addr (pc),
    m_sc (),
    m_flags (),
    m_frame_base (),
    m_frame_base_error (),
    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 ());
    }
}

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_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_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;
}

void
StackFrame::ChangePC (addr_t pc)
{
    m_frame_code_addr.SetRawAddress(pc);
    m_sc.Clear(false);
    m_flags.Reset(0);
    ThreadSP thread_sp (GetThread());
    if (thread_sp)
        thread_sp->ClearStackFrames ();
}

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 alreday 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)
{
    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)
{

    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 (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 (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_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;
    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)
{
    // 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)
{
    if (strm == NULL)
        return;

    GetSymbolContext(eSymbolContextEverything);
    ExecutionContext exe_ctx (shared_from_this());
    StreamString s;
    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)
{
    
    if (show_frame_info)
    {
        strm.Indent();
        DumpUsingSettingsFormat (&strm);
    }
    
    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 ();

            if (source_lines_before > 0 || source_lines_after > 0)
            {
                GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);

                if (m_sc.comp_unit && m_sc.line_entry.IsValid())
                {
                    have_source = true;
                    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;
}

