130fdc8d8SChris Lattner //===-- StackFrame.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner // C Includes 1530fdc8d8SChris Lattner // C++ Includes 1630fdc8d8SChris Lattner // Other libraries and framework includes 1730fdc8d8SChris Lattner // Project includes 1830fdc8d8SChris Lattner #include "lldb/Core/Module.h" 190603aa9dSGreg Clayton #include "lldb/Core/Debugger.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 2130fdc8d8SChris Lattner #include "lldb/Core/Value.h" 22288bdf9cSGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 2354979cddSGreg Clayton #include "lldb/Core/ValueObjectConstResult.h" 241f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 2530fdc8d8SChris Lattner #include "lldb/Symbol/Function.h" 261f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 271f746071SGreg Clayton #include "lldb/Symbol/SymbolContextScope.h" 28288bdf9cSGreg Clayton #include "lldb/Symbol/VariableList.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3130fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 3230fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits 3930fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol 4030fdc8d8SChris Lattner // context (m_sc) already. 4159e8fc1cSGreg Clayton #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) 426dadd508SGreg Clayton #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1) 4359e8fc1cSGreg Clayton #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) 4459e8fc1cSGreg Clayton #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) 457c0962dcSSean Callanan #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) 4630fdc8d8SChris Lattner 47d9e416c0SGreg Clayton StackFrame::StackFrame (const ThreadSP &thread_sp, 48d9e416c0SGreg Clayton user_id_t frame_idx, 494d122c40SGreg Clayton user_id_t unwind_frame_index, 504d122c40SGreg Clayton addr_t cfa, 5199618476SJason Molenda bool cfa_is_valid, 524d122c40SGreg Clayton addr_t pc, 5399618476SJason Molenda uint32_t stop_id, 5499618476SJason Molenda bool stop_id_is_valid, 5599618476SJason Molenda bool is_history_frame, 568f7180b1SGreg Clayton const SymbolContext *sc_ptr) : 57d9e416c0SGreg Clayton m_thread_wp (thread_sp), 581b72fcb7SGreg Clayton m_frame_index (frame_idx), 595ccbd294SGreg Clayton m_concrete_frame_index (unwind_frame_index), 6030fdc8d8SChris Lattner m_reg_context_sp (), 616dadd508SGreg Clayton m_id (pc, cfa, NULL), 62e72dfb32SGreg Clayton m_frame_code_addr (pc), 6330fdc8d8SChris Lattner m_sc (), 6430fdc8d8SChris Lattner m_flags (), 6530fdc8d8SChris Lattner m_frame_base (), 6630fdc8d8SChris Lattner m_frame_base_error (), 6799618476SJason Molenda m_cfa_is_valid (cfa_is_valid), 6899618476SJason Molenda m_stop_id (stop_id), 6999618476SJason Molenda m_stop_id_is_valid (stop_id_is_valid), 7099618476SJason Molenda m_is_history_frame (is_history_frame), 7130fdc8d8SChris Lattner m_variable_list_sp (), 721a65ae11SGreg Clayton m_variable_list_value_objects (), 736a354705SJason Molenda m_disassembly (), 746a354705SJason Molenda m_mutex (Mutex::eMutexTypeRecursive) 7530fdc8d8SChris Lattner { 7699618476SJason Molenda // If we don't have a CFA value, use the frame index for our StackID so that recursive 7799618476SJason Molenda // functions properly aren't confused with one another on a history stack. 7899618476SJason Molenda if (m_is_history_frame && m_cfa_is_valid == false) 7999618476SJason Molenda { 8099618476SJason Molenda m_id.SetCFA (m_frame_index); 8199618476SJason Molenda } 8299618476SJason Molenda 8330fdc8d8SChris Lattner if (sc_ptr != NULL) 841b72fcb7SGreg Clayton { 8530fdc8d8SChris Lattner m_sc = *sc_ptr; 861b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask ()); 871b72fcb7SGreg Clayton } 8830fdc8d8SChris Lattner } 8930fdc8d8SChris Lattner 90d9e416c0SGreg Clayton StackFrame::StackFrame (const ThreadSP &thread_sp, 91d9e416c0SGreg Clayton user_id_t frame_idx, 924d122c40SGreg Clayton user_id_t unwind_frame_index, 931b72fcb7SGreg Clayton const RegisterContextSP ®_context_sp, 944d122c40SGreg Clayton addr_t cfa, 954d122c40SGreg Clayton addr_t pc, 968f7180b1SGreg Clayton const SymbolContext *sc_ptr) : 97d9e416c0SGreg Clayton m_thread_wp (thread_sp), 981b72fcb7SGreg Clayton m_frame_index (frame_idx), 995ccbd294SGreg Clayton m_concrete_frame_index (unwind_frame_index), 10030fdc8d8SChris Lattner m_reg_context_sp (reg_context_sp), 1016dadd508SGreg Clayton m_id (pc, cfa, NULL), 102e72dfb32SGreg Clayton m_frame_code_addr (pc), 10330fdc8d8SChris Lattner m_sc (), 10430fdc8d8SChris Lattner m_flags (), 10530fdc8d8SChris Lattner m_frame_base (), 10630fdc8d8SChris Lattner m_frame_base_error (), 10799618476SJason Molenda m_cfa_is_valid (true), 10899618476SJason Molenda m_stop_id (0), 10999618476SJason Molenda m_stop_id_is_valid (false), 11099618476SJason Molenda m_is_history_frame (false), 11130fdc8d8SChris Lattner m_variable_list_sp (), 1121a65ae11SGreg Clayton m_variable_list_value_objects (), 1136a354705SJason Molenda m_disassembly (), 1146a354705SJason Molenda m_mutex (Mutex::eMutexTypeRecursive) 11530fdc8d8SChris Lattner { 11630fdc8d8SChris Lattner if (sc_ptr != NULL) 1171b72fcb7SGreg Clayton { 11830fdc8d8SChris Lattner m_sc = *sc_ptr; 1191b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask ()); 1201b72fcb7SGreg Clayton } 1211b72fcb7SGreg Clayton 1221b72fcb7SGreg Clayton if (reg_context_sp && !m_sc.target_sp) 1231b72fcb7SGreg Clayton { 124d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 125d9e416c0SGreg Clayton if (m_sc.target_sp) 1261b72fcb7SGreg Clayton m_flags.Set (eSymbolContextTarget); 1271b72fcb7SGreg Clayton } 1281b72fcb7SGreg Clayton } 1291b72fcb7SGreg Clayton 130d9e416c0SGreg Clayton StackFrame::StackFrame (const ThreadSP &thread_sp, 131d9e416c0SGreg Clayton user_id_t frame_idx, 1324d122c40SGreg Clayton user_id_t unwind_frame_index, 1331b72fcb7SGreg Clayton const RegisterContextSP ®_context_sp, 1344d122c40SGreg Clayton addr_t cfa, 1351b72fcb7SGreg Clayton const Address& pc_addr, 1368f7180b1SGreg Clayton const SymbolContext *sc_ptr) : 137d9e416c0SGreg Clayton m_thread_wp (thread_sp), 1381b72fcb7SGreg Clayton m_frame_index (frame_idx), 1395ccbd294SGreg Clayton m_concrete_frame_index (unwind_frame_index), 1401b72fcb7SGreg Clayton m_reg_context_sp (reg_context_sp), 1411ac04c30SGreg Clayton m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL), 14212fc3e0fSGreg Clayton m_frame_code_addr (pc_addr), 1431b72fcb7SGreg Clayton m_sc (), 1441b72fcb7SGreg Clayton m_flags (), 1451b72fcb7SGreg Clayton m_frame_base (), 1461b72fcb7SGreg Clayton m_frame_base_error (), 14799618476SJason Molenda m_cfa_is_valid (true), 14899618476SJason Molenda m_stop_id (0), 14999618476SJason Molenda m_stop_id_is_valid (false), 15099618476SJason Molenda m_is_history_frame (false), 1511b72fcb7SGreg Clayton m_variable_list_sp (), 1521a65ae11SGreg Clayton m_variable_list_value_objects (), 1536a354705SJason Molenda m_disassembly (), 1546a354705SJason Molenda m_mutex (Mutex::eMutexTypeRecursive) 1551b72fcb7SGreg Clayton { 1561b72fcb7SGreg Clayton if (sc_ptr != NULL) 1571b72fcb7SGreg Clayton { 1581b72fcb7SGreg Clayton m_sc = *sc_ptr; 1591b72fcb7SGreg Clayton m_flags.Set(m_sc.GetResolvedMask ()); 1601b72fcb7SGreg Clayton } 1611b72fcb7SGreg Clayton 1621b72fcb7SGreg Clayton if (m_sc.target_sp.get() == NULL && reg_context_sp) 1631b72fcb7SGreg Clayton { 164d9e416c0SGreg Clayton m_sc.target_sp = reg_context_sp->CalculateTarget(); 165d9e416c0SGreg Clayton if (m_sc.target_sp) 1661b72fcb7SGreg Clayton m_flags.Set (eSymbolContextTarget); 1671b72fcb7SGreg Clayton } 1681b72fcb7SGreg Clayton 169e72dfb32SGreg Clayton ModuleSP pc_module_sp (pc_addr.GetModule()); 170e72dfb32SGreg Clayton if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) 1711b72fcb7SGreg Clayton { 172e72dfb32SGreg Clayton if (pc_module_sp) 1731b72fcb7SGreg Clayton { 174e72dfb32SGreg Clayton m_sc.module_sp = pc_module_sp; 1751b72fcb7SGreg Clayton m_flags.Set (eSymbolContextModule); 1761b72fcb7SGreg Clayton } 177ffc1d667SGreg Clayton else 178ffc1d667SGreg Clayton { 179ffc1d667SGreg Clayton m_sc.module_sp.reset(); 180ffc1d667SGreg Clayton } 1811b72fcb7SGreg Clayton } 18230fdc8d8SChris Lattner } 18330fdc8d8SChris Lattner 18430fdc8d8SChris Lattner 18530fdc8d8SChris Lattner //---------------------------------------------------------------------- 18630fdc8d8SChris Lattner // Destructor 18730fdc8d8SChris Lattner //---------------------------------------------------------------------- 18830fdc8d8SChris Lattner StackFrame::~StackFrame() 18930fdc8d8SChris Lattner { 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner 19230fdc8d8SChris Lattner StackID& 19330fdc8d8SChris Lattner StackFrame::GetStackID() 19430fdc8d8SChris Lattner { 1956a354705SJason Molenda Mutex::Locker locker(m_mutex); 1966dadd508SGreg Clayton // Make sure we have resolved the StackID object's symbol context scope if 1976dadd508SGreg Clayton // we already haven't looked it up. 19859e8fc1cSGreg Clayton 19959e8fc1cSGreg Clayton if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) 20059e8fc1cSGreg Clayton { 2012cad65a5SGreg Clayton if (m_id.GetSymbolContextScope ()) 20259e8fc1cSGreg Clayton { 20395897c6aSGreg Clayton // We already have a symbol context scope, we just don't have our 20495897c6aSGreg Clayton // flag bit set. 20559e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 20659e8fc1cSGreg Clayton } 20759e8fc1cSGreg Clayton else 20859e8fc1cSGreg Clayton { 20995897c6aSGreg Clayton // Calculate the frame block and use this for the stack ID symbol 21095897c6aSGreg Clayton // context scope if we have one. 21195897c6aSGreg Clayton SymbolContextScope *scope = GetFrameBlock (); 21295897c6aSGreg Clayton if (scope == NULL) 21359e8fc1cSGreg Clayton { 21495897c6aSGreg Clayton // We don't have a block, so use the symbol 21595897c6aSGreg Clayton if (m_flags.IsClear (eSymbolContextSymbol)) 21659e8fc1cSGreg Clayton GetSymbolContext (eSymbolContextSymbol); 21795897c6aSGreg Clayton 21895897c6aSGreg Clayton // It is ok if m_sc.symbol is NULL here 21995897c6aSGreg Clayton scope = m_sc.symbol; 22059e8fc1cSGreg Clayton } 22195897c6aSGreg Clayton // Set the symbol context scope (the accessor will set the 22295897c6aSGreg Clayton // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags). 22395897c6aSGreg Clayton SetSymbolContextScope (scope); 22459e8fc1cSGreg Clayton } 22559e8fc1cSGreg Clayton } 22630fdc8d8SChris Lattner return m_id; 22730fdc8d8SChris Lattner } 22830fdc8d8SChris Lattner 229513c6bb8SJim Ingham uint32_t 230513c6bb8SJim Ingham StackFrame::GetFrameIndex () const 231513c6bb8SJim Ingham { 232513c6bb8SJim Ingham ThreadSP thread_sp = GetThread(); 233513c6bb8SJim Ingham if (thread_sp) 234b57e4a1bSJason Molenda return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index); 235513c6bb8SJim Ingham else 236513c6bb8SJim Ingham return m_frame_index; 237513c6bb8SJim Ingham } 238513c6bb8SJim Ingham 23959e8fc1cSGreg Clayton void 24059e8fc1cSGreg Clayton StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) 24159e8fc1cSGreg Clayton { 2426a354705SJason Molenda Mutex::Locker locker(m_mutex); 24359e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); 24459e8fc1cSGreg Clayton m_id.SetSymbolContextScope (symbol_scope); 24559e8fc1cSGreg Clayton } 24659e8fc1cSGreg Clayton 24734132754SGreg Clayton const Address& 2489da7bd07SGreg Clayton StackFrame::GetFrameCodeAddress() 24930fdc8d8SChris Lattner { 2506a354705SJason Molenda Mutex::Locker locker(m_mutex); 25159e8fc1cSGreg Clayton if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) 25230fdc8d8SChris Lattner { 25359e8fc1cSGreg Clayton m_flags.Set (RESOLVED_FRAME_CODE_ADDR); 25430fdc8d8SChris Lattner 25530fdc8d8SChris Lattner // Resolve the PC into a temporary address because if ResolveLoadAddress 25630fdc8d8SChris Lattner // fails to resolve the address, it will clear the address object... 257d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 258d9e416c0SGreg Clayton if (thread_sp) 259d9e416c0SGreg Clayton { 260d9e416c0SGreg Clayton TargetSP target_sp (thread_sp->CalculateTarget()); 261d9e416c0SGreg Clayton if (target_sp) 262d9e416c0SGreg Clayton { 263d9e416c0SGreg Clayton if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get())) 26430fdc8d8SChris Lattner { 265e72dfb32SGreg Clayton ModuleSP module_sp (m_frame_code_addr.GetModule()); 266e72dfb32SGreg Clayton if (module_sp) 26730fdc8d8SChris Lattner { 268e72dfb32SGreg Clayton m_sc.module_sp = module_sp; 26930fdc8d8SChris Lattner m_flags.Set(eSymbolContextModule); 27030fdc8d8SChris Lattner } 27130fdc8d8SChris Lattner } 27230fdc8d8SChris Lattner } 27330fdc8d8SChris Lattner } 274d9e416c0SGreg Clayton } 27512fc3e0fSGreg Clayton return m_frame_code_addr; 27630fdc8d8SChris Lattner } 27730fdc8d8SChris Lattner 27899618476SJason Molenda bool 27930fdc8d8SChris Lattner StackFrame::ChangePC (addr_t pc) 28030fdc8d8SChris Lattner { 2816a354705SJason Molenda Mutex::Locker locker(m_mutex); 28299618476SJason Molenda // We can't change the pc value of a history stack frame - it is immutable. 28399618476SJason Molenda if (m_is_history_frame) 28499618476SJason Molenda return false; 285e72dfb32SGreg Clayton m_frame_code_addr.SetRawAddress(pc); 28672310355SGreg Clayton m_sc.Clear(false); 28773b472d4SGreg Clayton m_flags.Reset(0); 288d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 289d9e416c0SGreg Clayton if (thread_sp) 290d9e416c0SGreg Clayton thread_sp->ClearStackFrames (); 29199618476SJason Molenda return true; 29230fdc8d8SChris Lattner } 29330fdc8d8SChris Lattner 29430fdc8d8SChris Lattner const char * 29530fdc8d8SChris Lattner StackFrame::Disassemble () 29630fdc8d8SChris Lattner { 2976a354705SJason Molenda Mutex::Locker locker(m_mutex); 29830fdc8d8SChris Lattner if (m_disassembly.GetSize() == 0) 29930fdc8d8SChris Lattner { 300d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 301d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 302d9e416c0SGreg Clayton if (target) 303d9e416c0SGreg Clayton { 3040f063ba6SJim Ingham const char *plugin_name = NULL; 3050f063ba6SJim Ingham const char *flavor = NULL; 306d9e416c0SGreg Clayton Disassembler::Disassemble (target->GetDebugger(), 307d9e416c0SGreg Clayton target->GetArchitecture(), 3080f063ba6SJim Ingham plugin_name, 3090f063ba6SJim Ingham flavor, 31030fdc8d8SChris Lattner exe_ctx, 31130fdc8d8SChris Lattner 0, 31237023b06SJim Ingham 0, 3131da6f9d7SGreg Clayton 0, 31430fdc8d8SChris Lattner m_disassembly); 315d9e416c0SGreg Clayton } 31630fdc8d8SChris Lattner if (m_disassembly.GetSize() == 0) 31730fdc8d8SChris Lattner return NULL; 31830fdc8d8SChris Lattner } 31930fdc8d8SChris Lattner return m_disassembly.GetData(); 32030fdc8d8SChris Lattner } 32130fdc8d8SChris Lattner 32295897c6aSGreg Clayton Block * 32395897c6aSGreg Clayton StackFrame::GetFrameBlock () 32495897c6aSGreg Clayton { 32595897c6aSGreg Clayton if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock)) 32695897c6aSGreg Clayton GetSymbolContext (eSymbolContextBlock); 32795897c6aSGreg Clayton 32895897c6aSGreg Clayton if (m_sc.block) 32995897c6aSGreg Clayton { 33095897c6aSGreg Clayton Block *inline_block = m_sc.block->GetContainingInlinedBlock(); 33195897c6aSGreg Clayton if (inline_block) 33295897c6aSGreg Clayton { 33395897c6aSGreg Clayton // Use the block with the inlined function info 33495897c6aSGreg Clayton // as the frame block we want this frame to have only the variables 33595897c6aSGreg Clayton // for the inlined function and its non-inlined block child blocks. 33695897c6aSGreg Clayton return inline_block; 33795897c6aSGreg Clayton } 33895897c6aSGreg Clayton else 33995897c6aSGreg Clayton { 34095897c6aSGreg Clayton // This block is not contained withing any inlined function blocks 34195897c6aSGreg Clayton // with so we want to use the top most function block. 34295897c6aSGreg Clayton return &m_sc.function->GetBlock (false); 34395897c6aSGreg Clayton } 34495897c6aSGreg Clayton } 34595897c6aSGreg Clayton return NULL; 34695897c6aSGreg Clayton } 34795897c6aSGreg Clayton 34830fdc8d8SChris Lattner //---------------------------------------------------------------------- 34930fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the 35030fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a 35130fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as 35230fdc8d8SChris Lattner // possible and no one will ever have to look things up manually. 35330fdc8d8SChris Lattner //---------------------------------------------------------------------- 35430fdc8d8SChris Lattner const SymbolContext& 35530fdc8d8SChris Lattner StackFrame::GetSymbolContext (uint32_t resolve_scope) 35630fdc8d8SChris Lattner { 3576a354705SJason Molenda Mutex::Locker locker(m_mutex); 35830fdc8d8SChris Lattner // Copy our internal symbol context into "sc". 35973b472d4SGreg Clayton if ((m_flags.Get() & resolve_scope) != resolve_scope) 36030fdc8d8SChris Lattner { 36175a0333bSGreg Clayton uint32_t resolved = 0; 36275a0333bSGreg Clayton 36375a0333bSGreg Clayton // If the target was requested add that: 36475a0333bSGreg Clayton if (!m_sc.target_sp) 36575a0333bSGreg Clayton { 36675a0333bSGreg Clayton m_sc.target_sp = CalculateTarget(); 36775a0333bSGreg Clayton if (m_sc.target_sp) 36875a0333bSGreg Clayton resolved |= eSymbolContextTarget; 36975a0333bSGreg Clayton } 37075a0333bSGreg Clayton 37175a0333bSGreg Clayton 372aaa0ba31SBruce Mitchener // Resolve our PC to section offset if we haven't already done so 37330fdc8d8SChris Lattner // and if we don't have a module. The resolved address section will 37430fdc8d8SChris Lattner // contain the module to which it belongs 37559e8fc1cSGreg Clayton if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) 3769da7bd07SGreg Clayton GetFrameCodeAddress(); 37730fdc8d8SChris Lattner 37830fdc8d8SChris Lattner // If this is not frame zero, then we need to subtract 1 from the PC 37930fdc8d8SChris Lattner // value when doing address lookups since the PC will be on the 38030fdc8d8SChris Lattner // instruction following the function call instruction... 38130fdc8d8SChris Lattner 3829da7bd07SGreg Clayton Address lookup_addr(GetFrameCodeAddress()); 3831b72fcb7SGreg Clayton if (m_frame_index > 0 && lookup_addr.IsValid()) 38430fdc8d8SChris Lattner { 38530fdc8d8SChris Lattner addr_t offset = lookup_addr.GetOffset(); 38630fdc8d8SChris Lattner if (offset > 0) 38730fdc8d8SChris Lattner lookup_addr.SetOffset(offset - 1); 38830fdc8d8SChris Lattner } 38930fdc8d8SChris Lattner 3909da7bd07SGreg Clayton 39130fdc8d8SChris Lattner if (m_sc.module_sp) 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner // We have something in our stack frame symbol context, lets check 39430fdc8d8SChris Lattner // if we haven't already tried to lookup one of those things. If we 39530fdc8d8SChris Lattner // haven't then we will do the query. 3961b72fcb7SGreg Clayton 3971b72fcb7SGreg Clayton uint32_t actual_resolve_scope = 0; 3981b72fcb7SGreg Clayton 3991b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextCompUnit) 4001b72fcb7SGreg Clayton { 4011b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextCompUnit)) 4021b72fcb7SGreg Clayton { 4031b72fcb7SGreg Clayton if (m_sc.comp_unit) 4049da7bd07SGreg Clayton resolved |= eSymbolContextCompUnit; 4051b72fcb7SGreg Clayton else 4061b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextCompUnit; 4071b72fcb7SGreg Clayton } 4081b72fcb7SGreg Clayton } 4091b72fcb7SGreg Clayton 4101b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextFunction) 4111b72fcb7SGreg Clayton { 4121b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextFunction)) 4131b72fcb7SGreg Clayton { 4141b72fcb7SGreg Clayton if (m_sc.function) 4159da7bd07SGreg Clayton resolved |= eSymbolContextFunction; 4161b72fcb7SGreg Clayton else 4171b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextFunction; 4181b72fcb7SGreg Clayton } 4191b72fcb7SGreg Clayton } 4201b72fcb7SGreg Clayton 4211b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextBlock) 4221b72fcb7SGreg Clayton { 4231b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextBlock)) 4241b72fcb7SGreg Clayton { 4251b72fcb7SGreg Clayton if (m_sc.block) 4269da7bd07SGreg Clayton resolved |= eSymbolContextBlock; 4271b72fcb7SGreg Clayton else 4281b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextBlock; 4291b72fcb7SGreg Clayton } 4301b72fcb7SGreg Clayton } 4311b72fcb7SGreg Clayton 4321b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextSymbol) 4331b72fcb7SGreg Clayton { 4341b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextSymbol)) 4351b72fcb7SGreg Clayton { 4361b72fcb7SGreg Clayton if (m_sc.symbol) 4379da7bd07SGreg Clayton resolved |= eSymbolContextSymbol; 4381b72fcb7SGreg Clayton else 4391b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextSymbol; 4401b72fcb7SGreg Clayton } 4411b72fcb7SGreg Clayton } 4421b72fcb7SGreg Clayton 4431b72fcb7SGreg Clayton if (resolve_scope & eSymbolContextLineEntry) 4441b72fcb7SGreg Clayton { 4451b72fcb7SGreg Clayton if (m_flags.IsClear (eSymbolContextLineEntry)) 4461b72fcb7SGreg Clayton { 4471b72fcb7SGreg Clayton if (m_sc.line_entry.IsValid()) 4489da7bd07SGreg Clayton resolved |= eSymbolContextLineEntry; 4491b72fcb7SGreg Clayton else 4501b72fcb7SGreg Clayton actual_resolve_scope |= eSymbolContextLineEntry; 4511b72fcb7SGreg Clayton } 4521b72fcb7SGreg Clayton } 4531b72fcb7SGreg Clayton 4541b72fcb7SGreg Clayton if (actual_resolve_scope) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner // We might be resolving less information than what is already 45730fdc8d8SChris Lattner // in our current symbol context so resolve into a temporary 45830fdc8d8SChris Lattner // symbol context "sc" so we don't clear out data we have 45930fdc8d8SChris Lattner // already found in "m_sc" 46030fdc8d8SChris Lattner SymbolContext sc; 46130fdc8d8SChris Lattner // Set flags that indicate what we have tried to resolve 4629da7bd07SGreg Clayton resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); 4631b72fcb7SGreg Clayton // Only replace what we didn't already have as we may have 4641b72fcb7SGreg Clayton // information for an inlined function scope that won't match 4651b72fcb7SGreg Clayton // what a standard lookup by address would match 4669da7bd07SGreg Clayton if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) 4679da7bd07SGreg Clayton m_sc.comp_unit = sc.comp_unit; 4689da7bd07SGreg Clayton if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) 4699da7bd07SGreg Clayton m_sc.function = sc.function; 4709da7bd07SGreg Clayton if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) 4719da7bd07SGreg Clayton m_sc.block = sc.block; 4729da7bd07SGreg Clayton if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) 4739da7bd07SGreg Clayton m_sc.symbol = sc.symbol; 4749da7bd07SGreg Clayton if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) 47575a0333bSGreg Clayton { 4769da7bd07SGreg Clayton m_sc.line_entry = sc.line_entry; 47775a0333bSGreg Clayton if (m_sc.target_sp) 47875a0333bSGreg Clayton { 47975a0333bSGreg Clayton // Be sure to apply and file remappings to our file and line 48075a0333bSGreg Clayton // entries when handing out a line entry 48175a0333bSGreg Clayton FileSpec new_file_spec; 48275a0333bSGreg Clayton if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec)) 48375a0333bSGreg Clayton m_sc.line_entry.file = new_file_spec; 48475a0333bSGreg Clayton } 48575a0333bSGreg Clayton } 48630fdc8d8SChris Lattner } 48730fdc8d8SChris Lattner } 48830fdc8d8SChris Lattner else 48930fdc8d8SChris Lattner { 49030fdc8d8SChris Lattner // If we don't have a module, then we can't have the compile unit, 49130fdc8d8SChris Lattner // function, block, line entry or symbol, so we can safely call 49230fdc8d8SChris Lattner // ResolveSymbolContextForAddress with our symbol context member m_sc. 4939da7bd07SGreg Clayton if (m_sc.target_sp) 494f4be227dSSean Callanan { 49575a0333bSGreg Clayton resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); 496f4be227dSSean Callanan } 4979da7bd07SGreg Clayton } 49830fdc8d8SChris Lattner 49930fdc8d8SChris Lattner // Update our internal flags so we remember what we have tried to locate so 50030fdc8d8SChris Lattner // we don't have to keep trying when more calls to this function are made. 5019da7bd07SGreg Clayton // We might have dug up more information that was requested (for example 5029da7bd07SGreg Clayton // if we were asked to only get the block, we will have gotten the 5039da7bd07SGreg Clayton // compile unit, and function) so set any additional bits that we resolved 5049da7bd07SGreg Clayton m_flags.Set (resolve_scope | resolved); 50530fdc8d8SChris Lattner } 50630fdc8d8SChris Lattner 50730fdc8d8SChris Lattner // Return the symbol context with everything that was possible to resolve 50830fdc8d8SChris Lattner // resolved. 50930fdc8d8SChris Lattner return m_sc; 51030fdc8d8SChris Lattner } 51130fdc8d8SChris Lattner 51230fdc8d8SChris Lattner 51330fdc8d8SChris Lattner VariableList * 514288bdf9cSGreg Clayton StackFrame::GetVariableList (bool get_file_globals) 51530fdc8d8SChris Lattner { 5166a354705SJason Molenda Mutex::Locker locker(m_mutex); 51730fdc8d8SChris Lattner if (m_flags.IsClear(RESOLVED_VARIABLES)) 51830fdc8d8SChris Lattner { 51930fdc8d8SChris Lattner m_flags.Set(RESOLVED_VARIABLES); 52030fdc8d8SChris Lattner 52195897c6aSGreg Clayton Block *frame_block = GetFrameBlock(); 522288bdf9cSGreg Clayton 52395897c6aSGreg Clayton if (frame_block) 52430fdc8d8SChris Lattner { 52595897c6aSGreg Clayton const bool get_child_variables = true; 52695897c6aSGreg Clayton const bool can_create = true; 527c662ec8bSGreg Clayton const bool stop_if_child_block_is_inlined_function = true; 528c662ec8bSGreg Clayton m_variable_list_sp.reset(new VariableList()); 529c662ec8bSGreg Clayton frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get()); 53030fdc8d8SChris Lattner } 5317c0962dcSSean Callanan } 532288bdf9cSGreg Clayton 5337c0962dcSSean Callanan if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && 5347c0962dcSSean Callanan get_file_globals) 53595897c6aSGreg Clayton { 5367c0962dcSSean Callanan m_flags.Set(RESOLVED_GLOBAL_VARIABLES); 5377c0962dcSSean Callanan 53895897c6aSGreg Clayton if (m_flags.IsClear (eSymbolContextCompUnit)) 53995897c6aSGreg Clayton GetSymbolContext (eSymbolContextCompUnit); 54095897c6aSGreg Clayton 54195897c6aSGreg Clayton if (m_sc.comp_unit) 542288bdf9cSGreg Clayton { 543288bdf9cSGreg Clayton VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 544288bdf9cSGreg Clayton if (m_variable_list_sp) 545288bdf9cSGreg Clayton m_variable_list_sp->AddVariables (global_variable_list_sp.get()); 546288bdf9cSGreg Clayton else 547288bdf9cSGreg Clayton m_variable_list_sp = global_variable_list_sp; 548288bdf9cSGreg Clayton } 54930fdc8d8SChris Lattner } 5507c0962dcSSean Callanan 55130fdc8d8SChris Lattner return m_variable_list_sp.get(); 55230fdc8d8SChris Lattner } 55330fdc8d8SChris Lattner 554d41f032aSGreg Clayton VariableListSP 555d41f032aSGreg Clayton StackFrame::GetInScopeVariableList (bool get_file_globals) 556d41f032aSGreg Clayton { 5576a354705SJason Molenda Mutex::Locker locker(m_mutex); 55899618476SJason Molenda // We can't fetch variable information for a history stack frame. 55999618476SJason Molenda if (m_is_history_frame) 56099618476SJason Molenda return VariableListSP(); 56199618476SJason Molenda 562d41f032aSGreg Clayton VariableListSP var_list_sp(new VariableList); 563d41f032aSGreg Clayton GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock); 564d41f032aSGreg Clayton 565d41f032aSGreg Clayton if (m_sc.block) 566d41f032aSGreg Clayton { 567d41f032aSGreg Clayton const bool can_create = true; 568d41f032aSGreg Clayton const bool get_parent_variables = true; 569d41f032aSGreg Clayton const bool stop_if_block_is_inlined_function = true; 570d41f032aSGreg Clayton m_sc.block->AppendVariables (can_create, 571d41f032aSGreg Clayton get_parent_variables, 572d41f032aSGreg Clayton stop_if_block_is_inlined_function, 573d41f032aSGreg Clayton var_list_sp.get()); 574d41f032aSGreg Clayton } 575d41f032aSGreg Clayton 576d41f032aSGreg Clayton if (m_sc.comp_unit) 577d41f032aSGreg Clayton { 578d41f032aSGreg Clayton VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true)); 579d41f032aSGreg Clayton if (global_variable_list_sp) 580d41f032aSGreg Clayton var_list_sp->AddVariables (global_variable_list_sp.get()); 581d41f032aSGreg Clayton } 582d41f032aSGreg Clayton 583d41f032aSGreg Clayton return var_list_sp; 584d41f032aSGreg Clayton } 585d41f032aSGreg Clayton 586d41f032aSGreg Clayton 5878b2fe6dcSGreg Clayton ValueObjectSP 5882837b766SJim Ingham StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, 5894d122c40SGreg Clayton DynamicValueType use_dynamic, 5902837b766SJim Ingham uint32_t options, 5914d122c40SGreg Clayton VariableSP &var_sp, 5922837b766SJim Ingham Error &error) 5938b2fe6dcSGreg Clayton { 59499618476SJason Molenda // We can't fetch variable information for a history stack frame. 59599618476SJason Molenda if (m_is_history_frame) 59699618476SJason Molenda return ValueObjectSP(); 59754979cddSGreg Clayton 59854979cddSGreg Clayton if (var_expr_cstr && var_expr_cstr[0]) 59954979cddSGreg Clayton { 6006d5e68eaSGreg Clayton const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; 6016d5e68eaSGreg Clayton const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; 60227b625e1SEnrico Granata const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; 60358ad3344SEnrico Granata //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0; 60454979cddSGreg Clayton error.Clear(); 6058b2fe6dcSGreg Clayton bool deref = false; 6068b2fe6dcSGreg Clayton bool address_of = false; 6078b2fe6dcSGreg Clayton ValueObjectSP valobj_sp; 6088b2fe6dcSGreg Clayton const bool get_file_globals = true; 609d41f032aSGreg Clayton // When looking up a variable for an expression, we need only consider the 610d41f032aSGreg Clayton // variables that are in scope. 611d41f032aSGreg Clayton VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals)); 612d41f032aSGreg Clayton VariableList *variable_list = var_list_sp.get(); 6138b2fe6dcSGreg Clayton 6148b2fe6dcSGreg Clayton if (variable_list) 6158b2fe6dcSGreg Clayton { 6168b2fe6dcSGreg Clayton // If first character is a '*', then show pointer contents 61754979cddSGreg Clayton const char *var_expr = var_expr_cstr; 6188b2fe6dcSGreg Clayton if (var_expr[0] == '*') 6198b2fe6dcSGreg Clayton { 6208b2fe6dcSGreg Clayton deref = true; 6218b2fe6dcSGreg Clayton var_expr++; // Skip the '*' 6228b2fe6dcSGreg Clayton } 6238b2fe6dcSGreg Clayton else if (var_expr[0] == '&') 6248b2fe6dcSGreg Clayton { 6258b2fe6dcSGreg Clayton address_of = true; 6268b2fe6dcSGreg Clayton var_expr++; // Skip the '&' 6278b2fe6dcSGreg Clayton } 6288b2fe6dcSGreg Clayton 6298b2fe6dcSGreg Clayton std::string var_path (var_expr); 63054979cddSGreg Clayton size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}"); 63154979cddSGreg Clayton StreamString var_expr_path_strm; 6328b2fe6dcSGreg Clayton 6338b2fe6dcSGreg Clayton ConstString name_const_string; 6348b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 6358b2fe6dcSGreg Clayton name_const_string.SetCString (var_path.c_str()); 6368b2fe6dcSGreg Clayton else 6378b2fe6dcSGreg Clayton name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 6388b2fe6dcSGreg Clayton 6392837b766SJim Ingham var_sp = variable_list->FindVariable(name_const_string); 640685c88c5SGreg Clayton 641685c88c5SGreg Clayton bool synthetically_added_instance_object = false; 642685c88c5SGreg Clayton 643685c88c5SGreg Clayton if (var_sp) 644685c88c5SGreg Clayton { 645685c88c5SGreg Clayton var_path.erase (0, name_const_string.GetLength ()); 646685c88c5SGreg Clayton } 647685c88c5SGreg Clayton else if (options & eExpressionPathOptionsAllowDirectIVarAccess) 648685c88c5SGreg Clayton { 649685c88c5SGreg Clayton // Check for direct ivars access which helps us with implicit 650685c88c5SGreg Clayton // access to ivars with the "this->" or "self->" 651685c88c5SGreg Clayton GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock); 652685c88c5SGreg Clayton lldb::LanguageType method_language = eLanguageTypeUnknown; 653685c88c5SGreg Clayton bool is_instance_method = false; 654685c88c5SGreg Clayton ConstString method_object_name; 655685c88c5SGreg Clayton if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name)) 656685c88c5SGreg Clayton { 657685c88c5SGreg Clayton if (is_instance_method && method_object_name) 658685c88c5SGreg Clayton { 659685c88c5SGreg Clayton var_sp = variable_list->FindVariable(method_object_name); 660685c88c5SGreg Clayton if (var_sp) 661685c88c5SGreg Clayton { 662685c88c5SGreg Clayton separator_idx = 0; 663685c88c5SGreg Clayton var_path.insert(0, "->"); 664685c88c5SGreg Clayton synthetically_added_instance_object = true; 665685c88c5SGreg Clayton } 666685c88c5SGreg Clayton } 667685c88c5SGreg Clayton } 668685c88c5SGreg Clayton } 669685c88c5SGreg Clayton 6708b2fe6dcSGreg Clayton if (var_sp) 6718b2fe6dcSGreg Clayton { 6722837b766SJim Ingham valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic); 67378a685aaSJim Ingham if (!valobj_sp) 67478a685aaSJim Ingham return valobj_sp; 6758b2fe6dcSGreg Clayton 6768b2fe6dcSGreg Clayton // We are dumping at least one child 6778b2fe6dcSGreg Clayton while (separator_idx != std::string::npos) 6788b2fe6dcSGreg Clayton { 6798b2fe6dcSGreg Clayton // Calculate the next separator index ahead of time 6808b2fe6dcSGreg Clayton ValueObjectSP child_valobj_sp; 6818b2fe6dcSGreg Clayton const char separator_type = var_path[0]; 6828b2fe6dcSGreg Clayton switch (separator_type) 6838b2fe6dcSGreg Clayton { 6848b2fe6dcSGreg Clayton 6858b2fe6dcSGreg Clayton case '-': 6868b2fe6dcSGreg Clayton if (var_path.size() >= 2 && var_path[1] != '>') 6878b2fe6dcSGreg Clayton return ValueObjectSP(); 6888b2fe6dcSGreg Clayton 6896d5e68eaSGreg Clayton if (no_fragile_ivar) 6906d5e68eaSGreg Clayton { 6916d5e68eaSGreg Clayton // Make sure we aren't trying to deref an objective 6926d5e68eaSGreg Clayton // C ivar if this is not allowed 69357ee3067SGreg Clayton const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL); 69457ee3067SGreg Clayton if ((pointer_type_flags & ClangASTType::eTypeIsObjC) && 69557ee3067SGreg Clayton (pointer_type_flags & ClangASTType::eTypeIsPointer)) 6966d5e68eaSGreg Clayton { 6976d5e68eaSGreg Clayton // This was an objective C object pointer and 6986d5e68eaSGreg Clayton // it was requested we skip any fragile ivars 6996d5e68eaSGreg Clayton // so return nothing here 7006d5e68eaSGreg Clayton return ValueObjectSP(); 7016d5e68eaSGreg Clayton } 7026d5e68eaSGreg Clayton } 7038b2fe6dcSGreg Clayton var_path.erase (0, 1); // Remove the '-' 7048b2fe6dcSGreg Clayton // Fall through 7058b2fe6dcSGreg Clayton case '.': 7068b2fe6dcSGreg Clayton { 70754979cddSGreg Clayton const bool expr_is_ptr = var_path[0] == '>'; 7088b2fe6dcSGreg Clayton 7098b2fe6dcSGreg Clayton var_path.erase (0, 1); // Remove the '.' or '>' 7108b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 7118b2fe6dcSGreg Clayton ConstString child_name; 7128b2fe6dcSGreg Clayton if (separator_idx == std::string::npos) 7138b2fe6dcSGreg Clayton child_name.SetCString (var_path.c_str()); 7148b2fe6dcSGreg Clayton else 7158b2fe6dcSGreg Clayton child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 7168b2fe6dcSGreg Clayton 71754979cddSGreg Clayton if (check_ptr_vs_member) 71854979cddSGreg Clayton { 71954979cddSGreg Clayton // We either have a pointer type and need to verify 72054979cddSGreg Clayton // valobj_sp is a pointer, or we have a member of a 72154979cddSGreg Clayton // class/union/struct being accessed with the . syntax 72254979cddSGreg Clayton // and need to verify we don't have a pointer. 72354979cddSGreg Clayton const bool actual_is_ptr = valobj_sp->IsPointerType (); 72454979cddSGreg Clayton 72554979cddSGreg Clayton if (actual_is_ptr != expr_is_ptr) 72654979cddSGreg Clayton { 72754979cddSGreg Clayton // Incorrect use of "." with a pointer, or "->" with 72854979cddSGreg Clayton // a class/union/struct instance or reference. 7296beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 73054979cddSGreg Clayton if (actual_is_ptr) 73154979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?", 73254979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 73354979cddSGreg Clayton child_name.GetCString(), 73454979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 73554979cddSGreg Clayton var_path.c_str()); 73654979cddSGreg Clayton else 73754979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?", 73854979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 73954979cddSGreg Clayton child_name.GetCString(), 74054979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 74154979cddSGreg Clayton var_path.c_str()); 74254979cddSGreg Clayton return ValueObjectSP(); 74354979cddSGreg Clayton } 74454979cddSGreg Clayton } 7458b2fe6dcSGreg Clayton child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 7468b2fe6dcSGreg Clayton if (!child_valobj_sp) 7478b2fe6dcSGreg Clayton { 7488c9d3560SEnrico Granata if (no_synth_child == false) 74986cc9829SEnrico Granata { 75086cc9829SEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticValue(); 75186cc9829SEnrico Granata if (child_valobj_sp) 75286cc9829SEnrico Granata child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true); 75386cc9829SEnrico Granata } 7548c9d3560SEnrico Granata 7558c9d3560SEnrico Granata if (no_synth_child || !child_valobj_sp) 7568c9d3560SEnrico Granata { 7578b2fe6dcSGreg Clayton // No child member with name "child_name" 758685c88c5SGreg Clayton if (synthetically_added_instance_object) 759685c88c5SGreg Clayton { 760685c88c5SGreg Clayton // We added a "this->" or "self->" to the beginning of the expression 761685c88c5SGreg Clayton // and this is the first pointer ivar access, so just return the normal 762685c88c5SGreg Clayton // error 763685c88c5SGreg Clayton error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame", 764685c88c5SGreg Clayton name_const_string.GetCString()); 765685c88c5SGreg Clayton } 766685c88c5SGreg Clayton else 767685c88c5SGreg Clayton { 7686beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 76954979cddSGreg Clayton if (child_name) 77054979cddSGreg Clayton { 77154979cddSGreg Clayton error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"", 77254979cddSGreg Clayton child_name.GetCString(), 77354979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 77454979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 77554979cddSGreg Clayton } 77654979cddSGreg Clayton else 77754979cddSGreg Clayton { 77854979cddSGreg Clayton error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"", 77954979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 78054979cddSGreg Clayton var_expr_cstr); 78154979cddSGreg Clayton } 782685c88c5SGreg Clayton } 7838b2fe6dcSGreg Clayton return ValueObjectSP(); 7848b2fe6dcSGreg Clayton } 7858c9d3560SEnrico Granata } 786685c88c5SGreg Clayton synthetically_added_instance_object = false; 7878b2fe6dcSGreg Clayton // Remove the child name from the path 7888b2fe6dcSGreg Clayton var_path.erase(0, child_name.GetLength()); 7894d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 79078a685aaSJim Ingham { 7912837b766SJim Ingham ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 79278a685aaSJim Ingham if (dynamic_value_sp) 79378a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 79478a685aaSJim Ingham } 7958b2fe6dcSGreg Clayton } 7968b2fe6dcSGreg Clayton break; 7978b2fe6dcSGreg Clayton 7988b2fe6dcSGreg Clayton case '[': 7998b2fe6dcSGreg Clayton // Array member access, or treating pointer as an array 8008b2fe6dcSGreg Clayton if (var_path.size() > 2) // Need at least two brackets and a number 8018b2fe6dcSGreg Clayton { 8028b2fe6dcSGreg Clayton char *end = NULL; 8031a65ae11SGreg Clayton long child_index = ::strtol (&var_path[1], &end, 0); 8049fc1944eSEnrico Granata if (end && *end == ']' 8059fc1944eSEnrico Granata && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go 8068b2fe6dcSGreg Clayton { 80757ee3067SGreg Clayton if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) 8089fc1944eSEnrico Granata { 8099fc1944eSEnrico Granata // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr 8109fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 8119fc1944eSEnrico Granata // would be done by saying ptr[low], without a deref * sign 8129fc1944eSEnrico Granata Error error; 8139fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 8149fc1944eSEnrico Granata if (error.Fail()) 8159fc1944eSEnrico Granata { 8169fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8179fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 8189fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 8199fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 8209fc1944eSEnrico Granata return ValueObjectSP(); 8219fc1944eSEnrico Granata } 8229fc1944eSEnrico Granata valobj_sp = temp; 8239fc1944eSEnrico Granata deref = false; 8249fc1944eSEnrico Granata } 82557ee3067SGreg Clayton else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) 8269fc1944eSEnrico Granata { 8279fc1944eSEnrico Granata // what we have is *arr[low]. the most similar C++ syntax is to get arr[0] 8289fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 8299fc1944eSEnrico Granata // and extract bit low out of it. reading array item low 8309fc1944eSEnrico Granata // would be done by saying arr[low], without a deref * sign 8319fc1944eSEnrico Granata Error error; 8329fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 8339fc1944eSEnrico Granata if (error.Fail()) 8349fc1944eSEnrico Granata { 8359fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8369fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 8379fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 8389fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 8399fc1944eSEnrico Granata return ValueObjectSP(); 8409fc1944eSEnrico Granata } 8419fc1944eSEnrico Granata valobj_sp = temp; 8429fc1944eSEnrico Granata deref = false; 8439fc1944eSEnrico Granata } 8448b2fe6dcSGreg Clayton 8454ef877f5SGreg Clayton bool is_incomplete_array = false; 8468b2fe6dcSGreg Clayton if (valobj_sp->IsPointerType ()) 8478b2fe6dcSGreg Clayton { 848226b70c1SSean Callanan bool is_objc_pointer = true; 849226b70c1SSean Callanan 85057ee3067SGreg Clayton if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC) 851226b70c1SSean Callanan is_objc_pointer = false; 85257ee3067SGreg Clayton else if (!valobj_sp->GetClangType().IsPointerType()) 853226b70c1SSean Callanan is_objc_pointer = false; 854226b70c1SSean Callanan 855226b70c1SSean Callanan if (no_synth_child && is_objc_pointer) 856226b70c1SSean Callanan { 857226b70c1SSean Callanan error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted", 858226b70c1SSean Callanan valobj_sp->GetTypeName().AsCString("<invalid type>"), 859226b70c1SSean Callanan var_expr_path_strm.GetString().c_str()); 860226b70c1SSean Callanan 861226b70c1SSean Callanan return ValueObjectSP(); 862226b70c1SSean Callanan } 863226b70c1SSean Callanan else if (is_objc_pointer) 86427b625e1SEnrico Granata { 86527b625e1SEnrico Granata // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children 86686cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 86727b625e1SEnrico Granata if (synthetic.get() == NULL /* no synthetic */ 86827b625e1SEnrico Granata || synthetic == valobj_sp) /* synthetic is the same as the original object */ 86927b625e1SEnrico Granata { 87027b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 87127b625e1SEnrico Granata error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 87227b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 87327b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 87427b625e1SEnrico Granata } 8753985c8c6SSaleem Abdulrasool else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 87627b625e1SEnrico Granata { 87727b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8787e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 87927b625e1SEnrico Granata child_index, 88027b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 88127b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 88227b625e1SEnrico Granata } 88327b625e1SEnrico Granata else 88427b625e1SEnrico Granata { 88527b625e1SEnrico Granata child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 88627b625e1SEnrico Granata if (!child_valobj_sp) 88727b625e1SEnrico Granata { 88827b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 8897e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 89027b625e1SEnrico Granata child_index, 89127b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 89227b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 89327b625e1SEnrico Granata } 89427b625e1SEnrico Granata } 89527b625e1SEnrico Granata } 89627b625e1SEnrico Granata else 89727b625e1SEnrico Granata { 8988b2fe6dcSGreg Clayton child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); 89954979cddSGreg Clayton if (!child_valobj_sp) 90054979cddSGreg Clayton { 9016beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9027e589a60SJason Molenda error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"", 90354979cddSGreg Clayton child_index, 90454979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 90554979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 90654979cddSGreg Clayton } 90754979cddSGreg Clayton } 90827b625e1SEnrico Granata } 90957ee3067SGreg Clayton else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array)) 91054979cddSGreg Clayton { 91178a685aaSJim Ingham // Pass false to dynamic_value here so we can tell the difference between 91278a685aaSJim Ingham // no dynamic value and no member of this type... 91354979cddSGreg Clayton child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 9144ef877f5SGreg Clayton if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false)) 9154ef877f5SGreg Clayton child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true); 9164ef877f5SGreg Clayton 91754979cddSGreg Clayton if (!child_valobj_sp) 91854979cddSGreg Clayton { 9196beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9207e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 92154979cddSGreg Clayton child_index, 92254979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 92354979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 92454979cddSGreg Clayton } 9258b2fe6dcSGreg Clayton } 92657ee3067SGreg Clayton else if (valobj_sp->GetClangType().IsScalarType()) 9279fc1944eSEnrico Granata { 9289fc1944eSEnrico Granata // this is a bitfield asking to display just one bit 9299fc1944eSEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true); 9309fc1944eSEnrico Granata if (!child_valobj_sp) 9319fc1944eSEnrico Granata { 9329fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9337e589a60SJason Molenda error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 9349fc1944eSEnrico Granata child_index, child_index, 9359fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 9369fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 9379fc1944eSEnrico Granata } 9389fc1944eSEnrico Granata } 9398b2fe6dcSGreg Clayton else 9408b2fe6dcSGreg Clayton { 94186cc9829SEnrico Granata ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(); 94227b625e1SEnrico Granata if (no_synth_child /* synthetic is forbidden */ || 94327b625e1SEnrico Granata synthetic.get() == NULL /* no synthetic */ 94427b625e1SEnrico Granata || synthetic == valobj_sp) /* synthetic is the same as the original object */ 94527b625e1SEnrico Granata { 9466beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 94754979cddSGreg Clayton error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", 94854979cddSGreg Clayton valobj_sp->GetTypeName().AsCString("<invalid type>"), 94954979cddSGreg Clayton var_expr_path_strm.GetString().c_str()); 9508b2fe6dcSGreg Clayton } 9513985c8c6SSaleem Abdulrasool else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */) 95227b625e1SEnrico Granata { 95327b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9547e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 95527b625e1SEnrico Granata child_index, 95627b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 95727b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 95827b625e1SEnrico Granata } 95927b625e1SEnrico Granata else 96027b625e1SEnrico Granata { 96127b625e1SEnrico Granata child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); 96227b625e1SEnrico Granata if (!child_valobj_sp) 96327b625e1SEnrico Granata { 96427b625e1SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 9657e589a60SJason Molenda error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"", 96627b625e1SEnrico Granata child_index, 96727b625e1SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 96827b625e1SEnrico Granata var_expr_path_strm.GetString().c_str()); 96927b625e1SEnrico Granata } 97027b625e1SEnrico Granata } 97127b625e1SEnrico Granata } 9728b2fe6dcSGreg Clayton 9738b2fe6dcSGreg Clayton if (!child_valobj_sp) 9748b2fe6dcSGreg Clayton { 9758b2fe6dcSGreg Clayton // Invalid array index... 9768b2fe6dcSGreg Clayton return ValueObjectSP(); 9778b2fe6dcSGreg Clayton } 9788b2fe6dcSGreg Clayton 9798b2fe6dcSGreg Clayton // Erase the array member specification '[%i]' where 9808b2fe6dcSGreg Clayton // %i is the array index 9818b2fe6dcSGreg Clayton var_path.erase(0, (end - var_path.c_str()) + 1); 9828b2fe6dcSGreg Clayton separator_idx = var_path.find_first_of(".-["); 9834d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 98478a685aaSJim Ingham { 9852837b766SJim Ingham ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 98678a685aaSJim Ingham if (dynamic_value_sp) 98778a685aaSJim Ingham child_valobj_sp = dynamic_value_sp; 98878a685aaSJim Ingham } 9898b2fe6dcSGreg Clayton // Break out early from the switch since we were 9908b2fe6dcSGreg Clayton // able to find the child member 9918b2fe6dcSGreg Clayton break; 9928b2fe6dcSGreg Clayton } 9939fc1944eSEnrico Granata else if (end && *end == '-') 9949fc1944eSEnrico Granata { 9959fc1944eSEnrico Granata // this is most probably a BitField, let's take a look 9969fc1944eSEnrico Granata char *real_end = NULL; 9979fc1944eSEnrico Granata long final_index = ::strtol (end+1, &real_end, 0); 998d64d0bc0SEnrico Granata bool expand_bitfield = true; 9999fc1944eSEnrico Granata if (real_end && *real_end == ']') 10009fc1944eSEnrico Granata { 10019fc1944eSEnrico Granata // if the format given is [high-low], swap range 10029fc1944eSEnrico Granata if (child_index > final_index) 10039fc1944eSEnrico Granata { 10049fc1944eSEnrico Granata long temp = child_index; 10059fc1944eSEnrico Granata child_index = final_index; 10069fc1944eSEnrico Granata final_index = temp; 10079fc1944eSEnrico Granata } 10089fc1944eSEnrico Granata 100957ee3067SGreg Clayton if (valobj_sp->GetClangType().IsPointerToScalarType() && deref) 10109fc1944eSEnrico Granata { 10119fc1944eSEnrico Granata // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr 10129fc1944eSEnrico Granata // and extract bits low thru high out of it. reading array items low thru high 10139fc1944eSEnrico Granata // would be done by saying ptr[low-high], without a deref * sign 10149fc1944eSEnrico Granata Error error; 10159fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->Dereference(error)); 10169fc1944eSEnrico Granata if (error.Fail()) 10179fc1944eSEnrico Granata { 10189fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10199fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"", 10209fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10219fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10229fc1944eSEnrico Granata return ValueObjectSP(); 10239fc1944eSEnrico Granata } 10249fc1944eSEnrico Granata valobj_sp = temp; 10259fc1944eSEnrico Granata deref = false; 10269fc1944eSEnrico Granata } 102757ee3067SGreg Clayton else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref) 10289fc1944eSEnrico Granata { 10299fc1944eSEnrico Granata // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0] 10309fc1944eSEnrico Granata // (an operation that is equivalent to deref-ing arr) 10319fc1944eSEnrico Granata // and extract bits low thru high out of it. reading array items low thru high 10329fc1944eSEnrico Granata // would be done by saying arr[low-high], without a deref * sign 10339fc1944eSEnrico Granata Error error; 10349fc1944eSEnrico Granata ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true)); 10359fc1944eSEnrico Granata if (error.Fail()) 10369fc1944eSEnrico Granata { 10379fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10389fc1944eSEnrico Granata error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"", 10399fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10409fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10419fc1944eSEnrico Granata return ValueObjectSP(); 10429fc1944eSEnrico Granata } 10439fc1944eSEnrico Granata valobj_sp = temp; 10449fc1944eSEnrico Granata deref = false; 10459fc1944eSEnrico Granata } 1046d64d0bc0SEnrico Granata /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType()) 1047d64d0bc0SEnrico Granata { 1048d64d0bc0SEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true); 1049d64d0bc0SEnrico Granata expand_bitfield = false; 1050d64d0bc0SEnrico Granata if (!child_valobj_sp) 1051d64d0bc0SEnrico Granata { 1052d64d0bc0SEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 1053d64d0bc0SEnrico Granata error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"", 1054d64d0bc0SEnrico Granata child_index, final_index, 1055d64d0bc0SEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 1056d64d0bc0SEnrico Granata var_expr_path_strm.GetString().c_str()); 1057d64d0bc0SEnrico Granata } 1058d64d0bc0SEnrico Granata }*/ 10599fc1944eSEnrico Granata 1060d64d0bc0SEnrico Granata if (expand_bitfield) 1061d64d0bc0SEnrico Granata { 10629fc1944eSEnrico Granata child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); 10639fc1944eSEnrico Granata if (!child_valobj_sp) 10649fc1944eSEnrico Granata { 10659fc1944eSEnrico Granata valobj_sp->GetExpressionPath (var_expr_path_strm, false); 10667e589a60SJason Molenda error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"", 10679fc1944eSEnrico Granata child_index, final_index, 10689fc1944eSEnrico Granata valobj_sp->GetTypeName().AsCString("<invalid type>"), 10699fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str()); 10709fc1944eSEnrico Granata } 10719fc1944eSEnrico Granata } 1072d64d0bc0SEnrico Granata } 10739fc1944eSEnrico Granata 10749fc1944eSEnrico Granata if (!child_valobj_sp) 10759fc1944eSEnrico Granata { 10769fc1944eSEnrico Granata // Invalid bitfield range... 10779fc1944eSEnrico Granata return ValueObjectSP(); 10789fc1944eSEnrico Granata } 10799fc1944eSEnrico Granata 10809fc1944eSEnrico Granata // Erase the bitfield member specification '[%i-%i]' where 10819fc1944eSEnrico Granata // %i is the index 10829fc1944eSEnrico Granata var_path.erase(0, (real_end - var_path.c_str()) + 1); 10839fc1944eSEnrico Granata separator_idx = var_path.find_first_of(".-["); 10844d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues) 10859fc1944eSEnrico Granata { 10869fc1944eSEnrico Granata ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic)); 10879fc1944eSEnrico Granata if (dynamic_value_sp) 10889fc1944eSEnrico Granata child_valobj_sp = dynamic_value_sp; 10899fc1944eSEnrico Granata } 10909fc1944eSEnrico Granata // Break out early from the switch since we were 10919fc1944eSEnrico Granata // able to find the child member 10929fc1944eSEnrico Granata break; 10939fc1944eSEnrico Granata 10949fc1944eSEnrico Granata } 10959fc1944eSEnrico Granata } 10969fc1944eSEnrico Granata else 10979fc1944eSEnrico Granata { 10989fc1944eSEnrico Granata error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"", 10999fc1944eSEnrico Granata var_expr_path_strm.GetString().c_str(), 11009fc1944eSEnrico Granata var_path.c_str()); 11018b2fe6dcSGreg Clayton } 11028b2fe6dcSGreg Clayton return ValueObjectSP(); 11038b2fe6dcSGreg Clayton 11048b2fe6dcSGreg Clayton default: 11058b2fe6dcSGreg Clayton // Failure... 110654979cddSGreg Clayton { 11076beaaa68SGreg Clayton valobj_sp->GetExpressionPath (var_expr_path_strm, false); 110854979cddSGreg Clayton error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"", 110954979cddSGreg Clayton separator_type, 111054979cddSGreg Clayton var_expr_path_strm.GetString().c_str(), 111154979cddSGreg Clayton var_path.c_str()); 111254979cddSGreg Clayton 11138b2fe6dcSGreg Clayton return ValueObjectSP(); 11148b2fe6dcSGreg Clayton } 111554979cddSGreg Clayton } 11168b2fe6dcSGreg Clayton 11178b2fe6dcSGreg Clayton if (child_valobj_sp) 11188b2fe6dcSGreg Clayton valobj_sp = child_valobj_sp; 11198b2fe6dcSGreg Clayton 11208b2fe6dcSGreg Clayton if (var_path.empty()) 11218b2fe6dcSGreg Clayton break; 11228b2fe6dcSGreg Clayton 11238b2fe6dcSGreg Clayton } 11248b2fe6dcSGreg Clayton if (valobj_sp) 11258b2fe6dcSGreg Clayton { 11268b2fe6dcSGreg Clayton if (deref) 11278b2fe6dcSGreg Clayton { 1128af67cecdSGreg Clayton ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error)); 11298b2fe6dcSGreg Clayton valobj_sp = deref_valobj_sp; 11308b2fe6dcSGreg Clayton } 11318b2fe6dcSGreg Clayton else if (address_of) 11328b2fe6dcSGreg Clayton { 113354979cddSGreg Clayton ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error)); 11348b2fe6dcSGreg Clayton valobj_sp = address_of_valobj_sp; 11358b2fe6dcSGreg Clayton } 11368b2fe6dcSGreg Clayton } 11378b2fe6dcSGreg Clayton return valobj_sp; 11388b2fe6dcSGreg Clayton } 113954979cddSGreg Clayton else 114054979cddSGreg Clayton { 11412837b766SJim Ingham error.SetErrorStringWithFormat("no variable named '%s' found in this frame", 11422837b766SJim Ingham name_const_string.GetCString()); 114354979cddSGreg Clayton } 114454979cddSGreg Clayton } 114554979cddSGreg Clayton } 114654979cddSGreg Clayton else 114754979cddSGreg Clayton { 114854979cddSGreg Clayton error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr); 11498b2fe6dcSGreg Clayton } 11508b2fe6dcSGreg Clayton return ValueObjectSP(); 11518b2fe6dcSGreg Clayton } 115230fdc8d8SChris Lattner 115330fdc8d8SChris Lattner bool 115430fdc8d8SChris Lattner StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) 115530fdc8d8SChris Lattner { 11566a354705SJason Molenda Mutex::Locker locker(m_mutex); 115799618476SJason Molenda if (m_cfa_is_valid == false) 115899618476SJason Molenda { 115999618476SJason Molenda m_frame_base_error.SetErrorString("No frame base available for this historical stack frame."); 116099618476SJason Molenda return false; 116199618476SJason Molenda } 116299618476SJason Molenda 116330fdc8d8SChris Lattner if (m_flags.IsClear(GOT_FRAME_BASE)) 116430fdc8d8SChris Lattner { 116530fdc8d8SChris Lattner if (m_sc.function) 116630fdc8d8SChris Lattner { 116730fdc8d8SChris Lattner m_frame_base.Clear(); 116830fdc8d8SChris Lattner m_frame_base_error.Clear(); 116930fdc8d8SChris Lattner 117030fdc8d8SChris Lattner m_flags.Set(GOT_FRAME_BASE); 1171d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 117230fdc8d8SChris Lattner Value expr_value; 1173016a95ebSGreg Clayton addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; 1174016a95ebSGreg Clayton if (m_sc.function->GetFrameBaseExpression().IsLocationList()) 1175d9e416c0SGreg Clayton loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr()); 1176016a95ebSGreg Clayton 117757ee3067SGreg Clayton if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) 117830fdc8d8SChris Lattner { 117930fdc8d8SChris Lattner // We should really have an error if evaluate returns, but in case 118030fdc8d8SChris Lattner // we don't, lets set the error to something at least. 118130fdc8d8SChris Lattner if (m_frame_base_error.Success()) 118230fdc8d8SChris Lattner m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed."); 118330fdc8d8SChris Lattner } 118430fdc8d8SChris Lattner else 118530fdc8d8SChris Lattner { 118657ee3067SGreg Clayton m_frame_base = expr_value.ResolveValue(&exe_ctx); 118730fdc8d8SChris Lattner } 118830fdc8d8SChris Lattner } 118930fdc8d8SChris Lattner else 119030fdc8d8SChris Lattner { 119130fdc8d8SChris Lattner m_frame_base_error.SetErrorString ("No function in symbol context."); 119230fdc8d8SChris Lattner } 119330fdc8d8SChris Lattner } 119430fdc8d8SChris Lattner 119530fdc8d8SChris Lattner if (m_frame_base_error.Success()) 119630fdc8d8SChris Lattner frame_base = m_frame_base; 119730fdc8d8SChris Lattner 119830fdc8d8SChris Lattner if (error_ptr) 119930fdc8d8SChris Lattner *error_ptr = m_frame_base_error; 120030fdc8d8SChris Lattner return m_frame_base_error.Success(); 120130fdc8d8SChris Lattner } 120230fdc8d8SChris Lattner 12035ccbd294SGreg Clayton RegisterContextSP 120430fdc8d8SChris Lattner StackFrame::GetRegisterContext () 120530fdc8d8SChris Lattner { 12066a354705SJason Molenda Mutex::Locker locker(m_mutex); 12075ccbd294SGreg Clayton if (!m_reg_context_sp) 1208d9e416c0SGreg Clayton { 1209d9e416c0SGreg Clayton ThreadSP thread_sp (GetThread()); 1210d9e416c0SGreg Clayton if (thread_sp) 1211d9e416c0SGreg Clayton m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this); 1212d9e416c0SGreg Clayton } 12135ccbd294SGreg Clayton return m_reg_context_sp; 121430fdc8d8SChris Lattner } 121530fdc8d8SChris Lattner 121630fdc8d8SChris Lattner bool 121730fdc8d8SChris Lattner StackFrame::HasDebugInformation () 121830fdc8d8SChris Lattner { 121930fdc8d8SChris Lattner GetSymbolContext (eSymbolContextLineEntry); 122030fdc8d8SChris Lattner return m_sc.line_entry.IsValid(); 122130fdc8d8SChris Lattner } 122230fdc8d8SChris Lattner 1223288bdf9cSGreg Clayton 1224288bdf9cSGreg Clayton ValueObjectSP 12254d122c40SGreg Clayton StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 122630fdc8d8SChris Lattner { 12276a354705SJason Molenda Mutex::Locker locker(m_mutex); 1228288bdf9cSGreg Clayton ValueObjectSP valobj_sp; 122999618476SJason Molenda if (m_is_history_frame) 123099618476SJason Molenda { 123199618476SJason Molenda return valobj_sp; 123299618476SJason Molenda } 1233288bdf9cSGreg Clayton VariableList *var_list = GetVariableList (true); 1234288bdf9cSGreg Clayton if (var_list) 1235288bdf9cSGreg Clayton { 1236288bdf9cSGreg Clayton // Make sure the variable is a frame variable 1237288bdf9cSGreg Clayton const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get()); 1238288bdf9cSGreg Clayton const uint32_t num_variables = var_list->GetSize(); 1239288bdf9cSGreg Clayton if (var_idx < num_variables) 1240288bdf9cSGreg Clayton { 1241288bdf9cSGreg Clayton valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx); 1242288bdf9cSGreg Clayton if (valobj_sp.get() == NULL) 1243288bdf9cSGreg Clayton { 1244288bdf9cSGreg Clayton if (m_variable_list_value_objects.GetSize() < num_variables) 1245288bdf9cSGreg Clayton m_variable_list_value_objects.Resize(num_variables); 124658b59f95SJim Ingham valobj_sp = ValueObjectVariable::Create (this, variable_sp); 1247288bdf9cSGreg Clayton m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp); 1248288bdf9cSGreg Clayton } 1249288bdf9cSGreg Clayton } 1250288bdf9cSGreg Clayton } 12514d122c40SGreg Clayton if (use_dynamic != eNoDynamicValues && valobj_sp) 125278a685aaSJim Ingham { 12532837b766SJim Ingham ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic); 125478a685aaSJim Ingham if (dynamic_sp) 125578a685aaSJim Ingham return dynamic_sp; 125678a685aaSJim Ingham } 1257288bdf9cSGreg Clayton return valobj_sp; 1258288bdf9cSGreg Clayton } 1259288bdf9cSGreg Clayton 1260288bdf9cSGreg Clayton ValueObjectSP 12614d122c40SGreg Clayton StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic) 1262288bdf9cSGreg Clayton { 12636a354705SJason Molenda Mutex::Locker locker(m_mutex); 126499618476SJason Molenda if (m_is_history_frame) 126599618476SJason Molenda return ValueObjectSP(); 126699618476SJason Molenda 1267288bdf9cSGreg Clayton // Check to make sure we aren't already tracking this variable? 126878a685aaSJim Ingham ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); 1269288bdf9cSGreg Clayton if (!valobj_sp) 1270288bdf9cSGreg Clayton { 1271288bdf9cSGreg Clayton // We aren't already tracking this global 1272288bdf9cSGreg Clayton VariableList *var_list = GetVariableList (true); 1273288bdf9cSGreg Clayton // If this frame has no variables, create a new list 1274288bdf9cSGreg Clayton if (var_list == NULL) 1275288bdf9cSGreg Clayton m_variable_list_sp.reset (new VariableList()); 1276288bdf9cSGreg Clayton 1277288bdf9cSGreg Clayton // Add the global/static variable to this frame 1278288bdf9cSGreg Clayton m_variable_list_sp->AddVariable (variable_sp); 1279288bdf9cSGreg Clayton 1280288bdf9cSGreg Clayton // Now make a value object for it so we can track its changes 128178a685aaSJim Ingham valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); 1282288bdf9cSGreg Clayton } 1283288bdf9cSGreg Clayton return valobj_sp; 128430fdc8d8SChris Lattner } 128530fdc8d8SChris Lattner 12866b8379c4SJim Ingham bool 12876b8379c4SJim Ingham StackFrame::IsInlined () 12886b8379c4SJim Ingham { 128959e8fc1cSGreg Clayton if (m_sc.block == NULL) 129059e8fc1cSGreg Clayton GetSymbolContext (eSymbolContextBlock); 129159e8fc1cSGreg Clayton if (m_sc.block) 129259e8fc1cSGreg Clayton return m_sc.block->GetContainingInlinedBlock() != NULL; 129359e8fc1cSGreg Clayton return false; 12946b8379c4SJim Ingham } 12956b8379c4SJim Ingham 1296d9e416c0SGreg Clayton TargetSP 129730fdc8d8SChris Lattner StackFrame::CalculateTarget () 129830fdc8d8SChris Lattner { 1299d9e416c0SGreg Clayton TargetSP target_sp; 1300d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1301d9e416c0SGreg Clayton if (thread_sp) 1302d9e416c0SGreg Clayton { 1303d9e416c0SGreg Clayton ProcessSP process_sp (thread_sp->CalculateProcess()); 1304d9e416c0SGreg Clayton if (process_sp) 1305d9e416c0SGreg Clayton target_sp = process_sp->CalculateTarget(); 1306d9e416c0SGreg Clayton } 1307d9e416c0SGreg Clayton return target_sp; 130830fdc8d8SChris Lattner } 130930fdc8d8SChris Lattner 1310d9e416c0SGreg Clayton ProcessSP 131130fdc8d8SChris Lattner StackFrame::CalculateProcess () 131230fdc8d8SChris Lattner { 1313d9e416c0SGreg Clayton ProcessSP process_sp; 1314d9e416c0SGreg Clayton ThreadSP thread_sp(GetThread()); 1315d9e416c0SGreg Clayton if (thread_sp) 1316d9e416c0SGreg Clayton process_sp = thread_sp->CalculateProcess(); 1317d9e416c0SGreg Clayton return process_sp; 131830fdc8d8SChris Lattner } 131930fdc8d8SChris Lattner 1320d9e416c0SGreg Clayton ThreadSP 132130fdc8d8SChris Lattner StackFrame::CalculateThread () 132230fdc8d8SChris Lattner { 1323d9e416c0SGreg Clayton return GetThread(); 132430fdc8d8SChris Lattner } 132530fdc8d8SChris Lattner 1326b57e4a1bSJason Molenda StackFrameSP 1327b57e4a1bSJason Molenda StackFrame::CalculateStackFrame () 132830fdc8d8SChris Lattner { 1329d9e416c0SGreg Clayton return shared_from_this(); 133030fdc8d8SChris Lattner } 133130fdc8d8SChris Lattner 133230fdc8d8SChris Lattner 133330fdc8d8SChris Lattner void 13340603aa9dSGreg Clayton StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx) 133530fdc8d8SChris Lattner { 1336d9e416c0SGreg Clayton exe_ctx.SetContext (shared_from_this()); 133730fdc8d8SChris Lattner } 133830fdc8d8SChris Lattner 133930fdc8d8SChris Lattner void 13408ec10efcSJim Ingham StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker) 13410603aa9dSGreg Clayton { 13420603aa9dSGreg Clayton if (strm == NULL) 13430603aa9dSGreg Clayton return; 13440603aa9dSGreg Clayton 13450603aa9dSGreg Clayton GetSymbolContext(eSymbolContextEverything); 1346d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 13470603aa9dSGreg Clayton StreamString s; 13488ec10efcSJim Ingham 13498ec10efcSJim Ingham if (frame_marker) 13508ec10efcSJim Ingham s.PutCString(frame_marker); 13518ec10efcSJim Ingham 1352d9e416c0SGreg Clayton const char *frame_format = NULL; 1353d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1354d9e416c0SGreg Clayton if (target) 1355d9e416c0SGreg Clayton frame_format = target->GetDebugger().GetFrameFormat(); 1356c3ce7f27SMichael Sartain if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s)) 13570603aa9dSGreg Clayton { 13580603aa9dSGreg Clayton strm->Write(s.GetData(), s.GetSize()); 13590603aa9dSGreg Clayton } 13600603aa9dSGreg Clayton else 13610603aa9dSGreg Clayton { 13620603aa9dSGreg Clayton Dump (strm, true, false); 13630603aa9dSGreg Clayton strm->EOL(); 13640603aa9dSGreg Clayton } 13650603aa9dSGreg Clayton } 13660603aa9dSGreg Clayton 13670603aa9dSGreg Clayton void 13686dadd508SGreg Clayton StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths) 136930fdc8d8SChris Lattner { 137030fdc8d8SChris Lattner if (strm == NULL) 137130fdc8d8SChris Lattner return; 137230fdc8d8SChris Lattner 137330fdc8d8SChris Lattner if (show_frame_index) 13741b72fcb7SGreg Clayton strm->Printf("frame #%u: ", m_frame_index); 1375d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 1376d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 1377d01b2953SDaniel Malea strm->Printf("0x%0*" PRIx64 " ", 1378d9e416c0SGreg Clayton target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16, 1379d9e416c0SGreg Clayton GetFrameCodeAddress().GetLoadAddress(target)); 13809da7bd07SGreg Clayton GetSymbolContext(eSymbolContextEverything); 13811b72fcb7SGreg Clayton const bool show_module = true; 13821b72fcb7SGreg Clayton const bool show_inline = true; 1383*aff1b357SJason Molenda const bool show_function_arguments = true; 1384d9e416c0SGreg Clayton m_sc.DumpStopContext (strm, 1385d9e416c0SGreg Clayton exe_ctx.GetBestExecutionContextScope(), 1386d9e416c0SGreg Clayton GetFrameCodeAddress(), 1387d9e416c0SGreg Clayton show_fullpaths, 1388d9e416c0SGreg Clayton show_module, 1389*aff1b357SJason Molenda show_inline, 1390*aff1b357SJason Molenda show_function_arguments); 139130fdc8d8SChris Lattner } 139230fdc8d8SChris Lattner 13935082c5fdSGreg Clayton void 1394b57e4a1bSJason Molenda StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) 13955082c5fdSGreg Clayton { 13966a354705SJason Molenda Mutex::Locker locker(m_mutex); 139759e8fc1cSGreg Clayton assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing 1398b57e4a1bSJason Molenda m_variable_list_sp = prev_frame.m_variable_list_sp; 1399b57e4a1bSJason Molenda m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects); 140068275d5eSGreg Clayton if (!m_disassembly.GetString().empty()) 140168275d5eSGreg Clayton m_disassembly.GetString().swap (m_disassembly.GetString()); 14025082c5fdSGreg Clayton } 140368275d5eSGreg Clayton 140468275d5eSGreg Clayton 140559e8fc1cSGreg Clayton void 1406b57e4a1bSJason Molenda StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) 140759e8fc1cSGreg Clayton { 14086a354705SJason Molenda Mutex::Locker locker(m_mutex); 140959e8fc1cSGreg Clayton assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing 1410b57e4a1bSJason Molenda m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value 1411b57e4a1bSJason Molenda assert (GetThread() == curr_frame.GetThread()); 1412b57e4a1bSJason Molenda m_frame_index = curr_frame.m_frame_index; 1413b57e4a1bSJason Molenda m_concrete_frame_index = curr_frame.m_concrete_frame_index; 1414b57e4a1bSJason Molenda m_reg_context_sp = curr_frame.m_reg_context_sp; 1415b57e4a1bSJason Molenda m_frame_code_addr = curr_frame.m_frame_code_addr; 1416b57e4a1bSJason Molenda 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()); 1417b57e4a1bSJason Molenda 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()); 1418b57e4a1bSJason Molenda assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); 1419b57e4a1bSJason Molenda assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); 1420b57e4a1bSJason Molenda m_sc = curr_frame.m_sc; 142159e8fc1cSGreg Clayton m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); 142259e8fc1cSGreg Clayton m_flags.Set (m_sc.GetResolvedMask()); 142359e8fc1cSGreg Clayton m_frame_base.Clear(); 142459e8fc1cSGreg Clayton m_frame_base_error.Clear(); 142559e8fc1cSGreg Clayton } 1426e4284b71SJim Ingham 1427f23bf743SJason Molenda 14287260f620SGreg Clayton bool 1429b57e4a1bSJason Molenda StackFrame::HasCachedData () const 1430b57e4a1bSJason Molenda { 1431b57e4a1bSJason Molenda if (m_variable_list_sp.get()) 1432b57e4a1bSJason Molenda return true; 1433b57e4a1bSJason Molenda if (m_variable_list_value_objects.GetSize() > 0) 1434b57e4a1bSJason Molenda return true; 1435b57e4a1bSJason Molenda if (!m_disassembly.GetString().empty()) 1436b57e4a1bSJason Molenda return true; 1437b57e4a1bSJason Molenda return false; 1438b57e4a1bSJason Molenda } 1439b57e4a1bSJason Molenda 1440b57e4a1bSJason Molenda bool 14417260f620SGreg Clayton StackFrame::GetStatus (Stream& strm, 14427260f620SGreg Clayton bool show_frame_info, 14438ec10efcSJim Ingham bool show_source, 14448ec10efcSJim Ingham const char *frame_marker) 14457260f620SGreg Clayton { 144653eb7ad2SGreg Clayton 14477260f620SGreg Clayton if (show_frame_info) 14487260f620SGreg Clayton { 14497260f620SGreg Clayton strm.Indent(); 14508ec10efcSJim Ingham DumpUsingSettingsFormat (&strm, frame_marker); 14517260f620SGreg Clayton } 14527260f620SGreg Clayton 14537260f620SGreg Clayton if (show_source) 14547260f620SGreg Clayton { 1455d9e416c0SGreg Clayton ExecutionContext exe_ctx (shared_from_this()); 1456e372b98dSGreg Clayton bool have_source = false; 145767cc0636SGreg Clayton Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever; 1458d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 145953eb7ad2SGreg Clayton if (target) 146053eb7ad2SGreg Clayton { 146153eb7ad2SGreg Clayton Debugger &debugger = target->GetDebugger(); 146253eb7ad2SGreg Clayton const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true); 146353eb7ad2SGreg Clayton const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false); 146453eb7ad2SGreg Clayton disasm_display = debugger.GetStopDisassemblyDisplay (); 146553eb7ad2SGreg Clayton 14667260f620SGreg Clayton GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry); 14677260f620SGreg Clayton if (m_sc.comp_unit && m_sc.line_entry.IsValid()) 14687260f620SGreg Clayton { 14697cd81c55SJason Molenda have_source = true; 14706d1fbc9cSTodd Fiala if (source_lines_before > 0 || source_lines_after > 0) 14716d1fbc9cSTodd Fiala { 14727cd81c55SJason Molenda target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file, 14737260f620SGreg Clayton m_sc.line_entry.line, 1474d9e416c0SGreg Clayton source_lines_before, 1475d9e416c0SGreg Clayton source_lines_after, 14767260f620SGreg Clayton "->", 14777cd81c55SJason Molenda &strm); 1478e372b98dSGreg Clayton } 1479e372b98dSGreg Clayton } 1480e372b98dSGreg Clayton switch (disasm_display) 1481e372b98dSGreg Clayton { 148267cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNever: 1483e372b98dSGreg Clayton break; 1484e372b98dSGreg Clayton 148567cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeNoSource: 1486e372b98dSGreg Clayton if (have_source) 1487e372b98dSGreg Clayton break; 1488e372b98dSGreg Clayton // Fall through to next case 148967cc0636SGreg Clayton case Debugger::eStopDisassemblyTypeAlways: 1490d9e416c0SGreg Clayton if (target) 1491e372b98dSGreg Clayton { 149253eb7ad2SGreg Clayton const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); 1493e372b98dSGreg Clayton if (disasm_lines > 0) 1494e372b98dSGreg Clayton { 1495d9e416c0SGreg Clayton const ArchSpec &target_arch = target->GetArchitecture(); 1496e372b98dSGreg Clayton AddressRange pc_range; 1497e372b98dSGreg Clayton pc_range.GetBaseAddress() = GetFrameCodeAddress(); 1498e372b98dSGreg Clayton pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize()); 14990f063ba6SJim Ingham const char *plugin_name = NULL; 15000f063ba6SJim Ingham const char *flavor = NULL; 1501d9e416c0SGreg Clayton Disassembler::Disassemble (target->GetDebugger(), 1502e372b98dSGreg Clayton target_arch, 15030f063ba6SJim Ingham plugin_name, 15040f063ba6SJim Ingham flavor, 1505e372b98dSGreg Clayton exe_ctx, 1506e372b98dSGreg Clayton pc_range, 1507e372b98dSGreg Clayton disasm_lines, 1508e372b98dSGreg Clayton 0, 1509e372b98dSGreg Clayton Disassembler::eOptionMarkPCAddress, 1510e372b98dSGreg Clayton strm); 1511e372b98dSGreg Clayton } 1512e372b98dSGreg Clayton } 1513e372b98dSGreg Clayton break; 15147260f620SGreg Clayton } 15157260f620SGreg Clayton } 151653eb7ad2SGreg Clayton } 15177260f620SGreg Clayton return true; 15187260f620SGreg Clayton } 15197260f620SGreg Clayton 1520