1254721Semaste//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Target/StackFrame.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Core/Module.h"
19254721Semaste#include "lldb/Core/Debugger.h"
20254721Semaste#include "lldb/Core/Disassembler.h"
21254721Semaste#include "lldb/Core/Value.h"
22254721Semaste#include "lldb/Core/ValueObjectVariable.h"
23254721Semaste#include "lldb/Core/ValueObjectConstResult.h"
24254721Semaste#include "lldb/Symbol/CompileUnit.h"
25254721Semaste#include "lldb/Symbol/Function.h"
26254721Semaste#include "lldb/Symbol/Symbol.h"
27254721Semaste#include "lldb/Symbol/SymbolContextScope.h"
28254721Semaste#include "lldb/Symbol/VariableList.h"
29254721Semaste#include "lldb/Target/ExecutionContext.h"
30254721Semaste#include "lldb/Target/Process.h"
31254721Semaste#include "lldb/Target/RegisterContext.h"
32254721Semaste#include "lldb/Target/Target.h"
33254721Semaste#include "lldb/Target/Thread.h"
34254721Semaste
35254721Semasteusing namespace lldb;
36254721Semasteusing namespace lldb_private;
37254721Semaste
38254721Semaste// The first bits in the flags are reserved for the SymbolContext::Scope bits
39254721Semaste// so we know if we have tried to look up information in our internal symbol
40254721Semaste// context (m_sc) already.
41254721Semaste#define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
42254721Semaste#define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
43254721Semaste#define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
44254721Semaste#define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
45254721Semaste#define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
46254721Semaste
47254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp,
48254721Semaste                        user_id_t frame_idx,
49254721Semaste                        user_id_t unwind_frame_index,
50254721Semaste                        addr_t cfa,
51263363Semaste                        bool cfa_is_valid,
52254721Semaste                        addr_t pc,
53263363Semaste                        uint32_t stop_id,
54263363Semaste                        bool stop_id_is_valid,
55263363Semaste                        bool is_history_frame,
56254721Semaste                        const SymbolContext *sc_ptr) :
57254721Semaste    m_thread_wp (thread_sp),
58254721Semaste    m_frame_index (frame_idx),
59254721Semaste    m_concrete_frame_index (unwind_frame_index),
60254721Semaste    m_reg_context_sp (),
61254721Semaste    m_id (pc, cfa, NULL),
62254721Semaste    m_frame_code_addr (pc),
63254721Semaste    m_sc (),
64254721Semaste    m_flags (),
65254721Semaste    m_frame_base (),
66254721Semaste    m_frame_base_error (),
67263363Semaste    m_cfa_is_valid (cfa_is_valid),
68263363Semaste    m_stop_id  (stop_id),
69263363Semaste    m_stop_id_is_valid (stop_id_is_valid),
70263363Semaste    m_is_history_frame (is_history_frame),
71254721Semaste    m_variable_list_sp (),
72254721Semaste    m_variable_list_value_objects (),
73254721Semaste    m_disassembly ()
74254721Semaste{
75263363Semaste    // If we don't have a CFA value, use the frame index for our StackID so that recursive
76263363Semaste    // functions properly aren't confused with one another on a history stack.
77263363Semaste    if (m_is_history_frame && m_cfa_is_valid == false)
78263363Semaste    {
79263363Semaste        m_id.SetCFA (m_frame_index);
80263363Semaste    }
81263363Semaste
82254721Semaste    if (sc_ptr != NULL)
83254721Semaste    {
84254721Semaste        m_sc = *sc_ptr;
85254721Semaste        m_flags.Set(m_sc.GetResolvedMask ());
86254721Semaste    }
87254721Semaste}
88254721Semaste
89254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp,
90254721Semaste                        user_id_t frame_idx,
91254721Semaste                        user_id_t unwind_frame_index,
92254721Semaste                        const RegisterContextSP &reg_context_sp,
93254721Semaste                        addr_t cfa,
94254721Semaste                        addr_t pc,
95254721Semaste                        const SymbolContext *sc_ptr) :
96254721Semaste    m_thread_wp (thread_sp),
97254721Semaste    m_frame_index (frame_idx),
98254721Semaste    m_concrete_frame_index (unwind_frame_index),
99254721Semaste    m_reg_context_sp (reg_context_sp),
100254721Semaste    m_id (pc, cfa, NULL),
101254721Semaste    m_frame_code_addr (pc),
102254721Semaste    m_sc (),
103254721Semaste    m_flags (),
104254721Semaste    m_frame_base (),
105254721Semaste    m_frame_base_error (),
106263363Semaste    m_cfa_is_valid (true),
107263363Semaste    m_stop_id  (0),
108263363Semaste    m_stop_id_is_valid (false),
109263363Semaste    m_is_history_frame (false),
110254721Semaste    m_variable_list_sp (),
111254721Semaste    m_variable_list_value_objects (),
112254721Semaste    m_disassembly ()
113254721Semaste{
114254721Semaste    if (sc_ptr != NULL)
115254721Semaste    {
116254721Semaste        m_sc = *sc_ptr;
117254721Semaste        m_flags.Set(m_sc.GetResolvedMask ());
118254721Semaste    }
119254721Semaste
120254721Semaste    if (reg_context_sp && !m_sc.target_sp)
121254721Semaste    {
122254721Semaste        m_sc.target_sp = reg_context_sp->CalculateTarget();
123254721Semaste        if (m_sc.target_sp)
124254721Semaste            m_flags.Set (eSymbolContextTarget);
125254721Semaste    }
126254721Semaste}
127254721Semaste
128254721SemasteStackFrame::StackFrame (const ThreadSP &thread_sp,
129254721Semaste                        user_id_t frame_idx,
130254721Semaste                        user_id_t unwind_frame_index,
131254721Semaste                        const RegisterContextSP &reg_context_sp,
132254721Semaste                        addr_t cfa,
133254721Semaste                        const Address& pc_addr,
134254721Semaste                        const SymbolContext *sc_ptr) :
135254721Semaste    m_thread_wp (thread_sp),
136254721Semaste    m_frame_index (frame_idx),
137254721Semaste    m_concrete_frame_index (unwind_frame_index),
138254721Semaste    m_reg_context_sp (reg_context_sp),
139254721Semaste    m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
140254721Semaste    m_frame_code_addr (pc_addr),
141254721Semaste    m_sc (),
142254721Semaste    m_flags (),
143254721Semaste    m_frame_base (),
144254721Semaste    m_frame_base_error (),
145263363Semaste    m_cfa_is_valid (true),
146263363Semaste    m_stop_id  (0),
147263363Semaste    m_stop_id_is_valid (false),
148263363Semaste    m_is_history_frame (false),
149254721Semaste    m_variable_list_sp (),
150254721Semaste    m_variable_list_value_objects (),
151254721Semaste    m_disassembly ()
152254721Semaste{
153254721Semaste    if (sc_ptr != NULL)
154254721Semaste    {
155254721Semaste        m_sc = *sc_ptr;
156254721Semaste        m_flags.Set(m_sc.GetResolvedMask ());
157254721Semaste    }
158254721Semaste
159254721Semaste    if (m_sc.target_sp.get() == NULL && reg_context_sp)
160254721Semaste    {
161254721Semaste        m_sc.target_sp = reg_context_sp->CalculateTarget();
162254721Semaste        if (m_sc.target_sp)
163254721Semaste            m_flags.Set (eSymbolContextTarget);
164254721Semaste    }
165254721Semaste
166254721Semaste    ModuleSP pc_module_sp (pc_addr.GetModule());
167254721Semaste    if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
168254721Semaste    {
169254721Semaste        if (pc_module_sp)
170254721Semaste        {
171254721Semaste            m_sc.module_sp = pc_module_sp;
172254721Semaste            m_flags.Set (eSymbolContextModule);
173254721Semaste        }
174254721Semaste        else
175254721Semaste        {
176254721Semaste            m_sc.module_sp.reset();
177254721Semaste        }
178254721Semaste    }
179254721Semaste}
180254721Semaste
181254721Semaste
182254721Semaste//----------------------------------------------------------------------
183254721Semaste// Destructor
184254721Semaste//----------------------------------------------------------------------
185254721SemasteStackFrame::~StackFrame()
186254721Semaste{
187254721Semaste}
188254721Semaste
189254721SemasteStackID&
190254721SemasteStackFrame::GetStackID()
191254721Semaste{
192254721Semaste    // Make sure we have resolved the StackID object's symbol context scope if
193254721Semaste    // we already haven't looked it up.
194254721Semaste
195254721Semaste    if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
196254721Semaste    {
197254721Semaste        if (m_id.GetSymbolContextScope ())
198254721Semaste        {
199254721Semaste            // We already have a symbol context scope, we just don't have our
200254721Semaste            // flag bit set.
201254721Semaste            m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
202254721Semaste        }
203254721Semaste        else
204254721Semaste        {
205254721Semaste            // Calculate the frame block and use this for the stack ID symbol
206254721Semaste            // context scope if we have one.
207254721Semaste            SymbolContextScope *scope = GetFrameBlock ();
208254721Semaste            if (scope == NULL)
209254721Semaste            {
210254721Semaste                // We don't have a block, so use the symbol
211254721Semaste                if (m_flags.IsClear (eSymbolContextSymbol))
212254721Semaste                    GetSymbolContext (eSymbolContextSymbol);
213254721Semaste
214254721Semaste                // It is ok if m_sc.symbol is NULL here
215254721Semaste                scope = m_sc.symbol;
216254721Semaste            }
217254721Semaste            // Set the symbol context scope (the accessor will set the
218254721Semaste            // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
219254721Semaste            SetSymbolContextScope (scope);
220254721Semaste        }
221254721Semaste    }
222254721Semaste    return m_id;
223254721Semaste}
224254721Semaste
225254721Semasteuint32_t
226254721SemasteStackFrame::GetFrameIndex () const
227254721Semaste{
228254721Semaste    ThreadSP thread_sp = GetThread();
229254721Semaste    if (thread_sp)
230254721Semaste        return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
231254721Semaste    else
232254721Semaste        return m_frame_index;
233254721Semaste}
234254721Semaste
235254721Semastevoid
236254721SemasteStackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
237254721Semaste{
238254721Semaste    m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
239254721Semaste    m_id.SetSymbolContextScope (symbol_scope);
240254721Semaste}
241254721Semaste
242254721Semasteconst Address&
243254721SemasteStackFrame::GetFrameCodeAddress()
244254721Semaste{
245254721Semaste    if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
246254721Semaste    {
247254721Semaste        m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
248254721Semaste
249254721Semaste        // Resolve the PC into a temporary address because if ResolveLoadAddress
250254721Semaste        // fails to resolve the address, it will clear the address object...
251254721Semaste        ThreadSP thread_sp (GetThread());
252254721Semaste        if (thread_sp)
253254721Semaste        {
254254721Semaste            TargetSP target_sp (thread_sp->CalculateTarget());
255254721Semaste            if (target_sp)
256254721Semaste            {
257254721Semaste                if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get()))
258254721Semaste                {
259254721Semaste                    ModuleSP module_sp (m_frame_code_addr.GetModule());
260254721Semaste                    if (module_sp)
261254721Semaste                    {
262254721Semaste                        m_sc.module_sp = module_sp;
263254721Semaste                        m_flags.Set(eSymbolContextModule);
264254721Semaste                    }
265254721Semaste                }
266254721Semaste            }
267254721Semaste        }
268254721Semaste    }
269254721Semaste    return m_frame_code_addr;
270254721Semaste}
271254721Semaste
272263363Semastebool
273254721SemasteStackFrame::ChangePC (addr_t pc)
274254721Semaste{
275263363Semaste    // We can't change the pc value of a history stack frame - it is immutable.
276263363Semaste    if (m_is_history_frame)
277263363Semaste        return false;
278254721Semaste    m_frame_code_addr.SetRawAddress(pc);
279254721Semaste    m_sc.Clear(false);
280254721Semaste    m_flags.Reset(0);
281254721Semaste    ThreadSP thread_sp (GetThread());
282254721Semaste    if (thread_sp)
283254721Semaste        thread_sp->ClearStackFrames ();
284263363Semaste    return true;
285254721Semaste}
286254721Semaste
287254721Semasteconst char *
288254721SemasteStackFrame::Disassemble ()
289254721Semaste{
290254721Semaste    if (m_disassembly.GetSize() == 0)
291254721Semaste    {
292254721Semaste        ExecutionContext exe_ctx (shared_from_this());
293254721Semaste        Target *target = exe_ctx.GetTargetPtr();
294254721Semaste        if (target)
295254721Semaste        {
296254721Semaste            const char *plugin_name = NULL;
297254721Semaste            const char *flavor = NULL;
298254721Semaste            Disassembler::Disassemble (target->GetDebugger(),
299254721Semaste                                       target->GetArchitecture(),
300254721Semaste                                       plugin_name,
301254721Semaste                                       flavor,
302254721Semaste                                       exe_ctx,
303254721Semaste                                       0,
304254721Semaste                                       0,
305254721Semaste                                       0,
306254721Semaste                                       m_disassembly);
307254721Semaste        }
308254721Semaste        if (m_disassembly.GetSize() == 0)
309254721Semaste            return NULL;
310254721Semaste    }
311254721Semaste    return m_disassembly.GetData();
312254721Semaste}
313254721Semaste
314254721SemasteBlock *
315254721SemasteStackFrame::GetFrameBlock ()
316254721Semaste{
317254721Semaste    if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
318254721Semaste        GetSymbolContext (eSymbolContextBlock);
319254721Semaste
320254721Semaste    if (m_sc.block)
321254721Semaste    {
322254721Semaste        Block *inline_block = m_sc.block->GetContainingInlinedBlock();
323254721Semaste        if (inline_block)
324254721Semaste        {
325254721Semaste            // Use the block with the inlined function info
326254721Semaste            // as the frame block we want this frame to have only the variables
327254721Semaste            // for the inlined function and its non-inlined block child blocks.
328254721Semaste            return inline_block;
329254721Semaste        }
330254721Semaste        else
331254721Semaste        {
332254721Semaste            // This block is not contained withing any inlined function blocks
333254721Semaste            // with so we want to use the top most function block.
334254721Semaste            return &m_sc.function->GetBlock (false);
335254721Semaste        }
336254721Semaste    }
337254721Semaste    return NULL;
338254721Semaste}
339254721Semaste
340254721Semaste//----------------------------------------------------------------------
341254721Semaste// Get the symbol context if we already haven't done so by resolving the
342254721Semaste// PC address as much as possible. This way when we pass around a
343254721Semaste// StackFrame object, everyone will have as much information as
344254721Semaste// possible and no one will ever have to look things up manually.
345254721Semaste//----------------------------------------------------------------------
346254721Semasteconst SymbolContext&
347254721SemasteStackFrame::GetSymbolContext (uint32_t resolve_scope)
348254721Semaste{
349254721Semaste    // Copy our internal symbol context into "sc".
350254721Semaste    if ((m_flags.Get() & resolve_scope) != resolve_scope)
351254721Semaste    {
352254721Semaste        uint32_t resolved = 0;
353254721Semaste
354254721Semaste        // If the target was requested add that:
355254721Semaste        if (!m_sc.target_sp)
356254721Semaste        {
357254721Semaste            m_sc.target_sp = CalculateTarget();
358254721Semaste            if (m_sc.target_sp)
359254721Semaste                resolved |= eSymbolContextTarget;
360254721Semaste        }
361254721Semaste
362254721Semaste
363254721Semaste        // Resolve our PC to section offset if we haven't alreday done so
364254721Semaste        // and if we don't have a module. The resolved address section will
365254721Semaste        // contain the module to which it belongs
366254721Semaste        if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
367254721Semaste            GetFrameCodeAddress();
368254721Semaste
369254721Semaste        // If this is not frame zero, then we need to subtract 1 from the PC
370254721Semaste        // value when doing address lookups since the PC will be on the
371254721Semaste        // instruction following the function call instruction...
372254721Semaste
373254721Semaste        Address lookup_addr(GetFrameCodeAddress());
374254721Semaste        if (m_frame_index > 0 && lookup_addr.IsValid())
375254721Semaste        {
376254721Semaste            addr_t offset = lookup_addr.GetOffset();
377254721Semaste            if (offset > 0)
378254721Semaste                lookup_addr.SetOffset(offset - 1);
379254721Semaste        }
380254721Semaste
381254721Semaste
382254721Semaste        if (m_sc.module_sp)
383254721Semaste        {
384254721Semaste            // We have something in our stack frame symbol context, lets check
385254721Semaste            // if we haven't already tried to lookup one of those things. If we
386254721Semaste            // haven't then we will do the query.
387254721Semaste
388254721Semaste            uint32_t actual_resolve_scope = 0;
389254721Semaste
390254721Semaste            if (resolve_scope & eSymbolContextCompUnit)
391254721Semaste            {
392254721Semaste                if (m_flags.IsClear (eSymbolContextCompUnit))
393254721Semaste                {
394254721Semaste                    if (m_sc.comp_unit)
395254721Semaste                        resolved |= eSymbolContextCompUnit;
396254721Semaste                    else
397254721Semaste                        actual_resolve_scope |= eSymbolContextCompUnit;
398254721Semaste                }
399254721Semaste            }
400254721Semaste
401254721Semaste            if (resolve_scope & eSymbolContextFunction)
402254721Semaste            {
403254721Semaste                if (m_flags.IsClear (eSymbolContextFunction))
404254721Semaste                {
405254721Semaste                    if (m_sc.function)
406254721Semaste                        resolved |= eSymbolContextFunction;
407254721Semaste                    else
408254721Semaste                        actual_resolve_scope |= eSymbolContextFunction;
409254721Semaste                }
410254721Semaste            }
411254721Semaste
412254721Semaste            if (resolve_scope & eSymbolContextBlock)
413254721Semaste            {
414254721Semaste                if (m_flags.IsClear (eSymbolContextBlock))
415254721Semaste                {
416254721Semaste                    if (m_sc.block)
417254721Semaste                        resolved |= eSymbolContextBlock;
418254721Semaste                    else
419254721Semaste                        actual_resolve_scope |= eSymbolContextBlock;
420254721Semaste                }
421254721Semaste            }
422254721Semaste
423254721Semaste            if (resolve_scope & eSymbolContextSymbol)
424254721Semaste            {
425254721Semaste                if (m_flags.IsClear (eSymbolContextSymbol))
426254721Semaste                {
427254721Semaste                    if (m_sc.symbol)
428254721Semaste                        resolved |= eSymbolContextSymbol;
429254721Semaste                    else
430254721Semaste                        actual_resolve_scope |= eSymbolContextSymbol;
431254721Semaste                }
432254721Semaste            }
433254721Semaste
434254721Semaste            if (resolve_scope & eSymbolContextLineEntry)
435254721Semaste            {
436254721Semaste                if (m_flags.IsClear (eSymbolContextLineEntry))
437254721Semaste                {
438254721Semaste                    if (m_sc.line_entry.IsValid())
439254721Semaste                        resolved |= eSymbolContextLineEntry;
440254721Semaste                    else
441254721Semaste                        actual_resolve_scope |= eSymbolContextLineEntry;
442254721Semaste                }
443254721Semaste            }
444254721Semaste
445254721Semaste            if (actual_resolve_scope)
446254721Semaste            {
447254721Semaste                // We might be resolving less information than what is already
448254721Semaste                // in our current symbol context so resolve into a temporary
449254721Semaste                // symbol context "sc" so we don't clear out data we have
450254721Semaste                // already found in "m_sc"
451254721Semaste                SymbolContext sc;
452254721Semaste                // Set flags that indicate what we have tried to resolve
453254721Semaste                resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
454254721Semaste                // Only replace what we didn't already have as we may have
455254721Semaste                // information for an inlined function scope that won't match
456254721Semaste                // what a standard lookup by address would match
457254721Semaste                if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
458254721Semaste                    m_sc.comp_unit = sc.comp_unit;
459254721Semaste                if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
460254721Semaste                    m_sc.function = sc.function;
461254721Semaste                if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
462254721Semaste                    m_sc.block = sc.block;
463254721Semaste                if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
464254721Semaste                    m_sc.symbol = sc.symbol;
465254721Semaste                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
466254721Semaste                {
467254721Semaste                    m_sc.line_entry = sc.line_entry;
468254721Semaste                    if (m_sc.target_sp)
469254721Semaste                    {
470254721Semaste                        // Be sure to apply and file remappings to our file and line
471254721Semaste                        // entries when handing out a line entry
472254721Semaste                        FileSpec new_file_spec;
473254721Semaste                        if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
474254721Semaste                            m_sc.line_entry.file = new_file_spec;
475254721Semaste                    }
476254721Semaste                }
477254721Semaste            }
478254721Semaste        }
479254721Semaste        else
480254721Semaste        {
481254721Semaste            // If we don't have a module, then we can't have the compile unit,
482254721Semaste            // function, block, line entry or symbol, so we can safely call
483254721Semaste            // ResolveSymbolContextForAddress with our symbol context member m_sc.
484254721Semaste            if (m_sc.target_sp)
485254721Semaste            {
486254721Semaste                resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
487254721Semaste            }
488254721Semaste        }
489254721Semaste
490254721Semaste        // Update our internal flags so we remember what we have tried to locate so
491254721Semaste        // we don't have to keep trying when more calls to this function are made.
492254721Semaste        // We might have dug up more information that was requested (for example
493254721Semaste        // if we were asked to only get the block, we will have gotten the
494254721Semaste        // compile unit, and function) so set any additional bits that we resolved
495254721Semaste        m_flags.Set (resolve_scope | resolved);
496254721Semaste    }
497254721Semaste
498254721Semaste    // Return the symbol context with everything that was possible to resolve
499254721Semaste    // resolved.
500254721Semaste    return m_sc;
501254721Semaste}
502254721Semaste
503254721Semaste
504254721SemasteVariableList *
505254721SemasteStackFrame::GetVariableList (bool get_file_globals)
506254721Semaste{
507254721Semaste    if (m_flags.IsClear(RESOLVED_VARIABLES))
508254721Semaste    {
509254721Semaste        m_flags.Set(RESOLVED_VARIABLES);
510254721Semaste
511254721Semaste        Block *frame_block = GetFrameBlock();
512254721Semaste
513254721Semaste        if (frame_block)
514254721Semaste        {
515254721Semaste            const bool get_child_variables = true;
516254721Semaste            const bool can_create = true;
517254721Semaste            const bool stop_if_child_block_is_inlined_function = true;
518254721Semaste            m_variable_list_sp.reset(new VariableList());
519254721Semaste            frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
520254721Semaste        }
521254721Semaste    }
522254721Semaste
523254721Semaste    if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
524254721Semaste        get_file_globals)
525254721Semaste    {
526254721Semaste        m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
527254721Semaste
528254721Semaste        if (m_flags.IsClear (eSymbolContextCompUnit))
529254721Semaste            GetSymbolContext (eSymbolContextCompUnit);
530254721Semaste
531254721Semaste        if (m_sc.comp_unit)
532254721Semaste        {
533254721Semaste            VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
534254721Semaste            if (m_variable_list_sp)
535254721Semaste                m_variable_list_sp->AddVariables (global_variable_list_sp.get());
536254721Semaste            else
537254721Semaste                m_variable_list_sp = global_variable_list_sp;
538254721Semaste        }
539254721Semaste    }
540254721Semaste
541254721Semaste    return m_variable_list_sp.get();
542254721Semaste}
543254721Semaste
544254721SemasteVariableListSP
545254721SemasteStackFrame::GetInScopeVariableList (bool get_file_globals)
546254721Semaste{
547263363Semaste    // We can't fetch variable information for a history stack frame.
548263363Semaste    if (m_is_history_frame)
549263363Semaste        return VariableListSP();
550263363Semaste
551254721Semaste    VariableListSP var_list_sp(new VariableList);
552254721Semaste    GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
553254721Semaste
554254721Semaste    if (m_sc.block)
555254721Semaste    {
556254721Semaste        const bool can_create = true;
557254721Semaste        const bool get_parent_variables = true;
558254721Semaste        const bool stop_if_block_is_inlined_function = true;
559254721Semaste        m_sc.block->AppendVariables (can_create,
560254721Semaste                                     get_parent_variables,
561254721Semaste                                     stop_if_block_is_inlined_function,
562254721Semaste                                     var_list_sp.get());
563254721Semaste    }
564254721Semaste
565254721Semaste    if (m_sc.comp_unit)
566254721Semaste    {
567254721Semaste        VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
568254721Semaste        if (global_variable_list_sp)
569254721Semaste            var_list_sp->AddVariables (global_variable_list_sp.get());
570254721Semaste    }
571254721Semaste
572254721Semaste    return var_list_sp;
573254721Semaste}
574254721Semaste
575254721Semaste
576254721SemasteValueObjectSP
577254721SemasteStackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
578254721Semaste                                               DynamicValueType use_dynamic,
579254721Semaste                                               uint32_t options,
580254721Semaste                                               VariableSP &var_sp,
581254721Semaste                                               Error &error)
582254721Semaste{
583263363Semaste    // We can't fetch variable information for a history stack frame.
584263363Semaste    if (m_is_history_frame)
585263363Semaste        return ValueObjectSP();
586254721Semaste
587254721Semaste    if (var_expr_cstr && var_expr_cstr[0])
588254721Semaste    {
589254721Semaste        const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
590254721Semaste        const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
591254721Semaste        const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
592254721Semaste        //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
593254721Semaste        error.Clear();
594254721Semaste        bool deref = false;
595254721Semaste        bool address_of = false;
596254721Semaste        ValueObjectSP valobj_sp;
597254721Semaste        const bool get_file_globals = true;
598254721Semaste        // When looking up a variable for an expression, we need only consider the
599254721Semaste        // variables that are in scope.
600254721Semaste        VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
601254721Semaste        VariableList *variable_list = var_list_sp.get();
602254721Semaste
603254721Semaste        if (variable_list)
604254721Semaste        {
605254721Semaste            // If first character is a '*', then show pointer contents
606254721Semaste            const char *var_expr = var_expr_cstr;
607254721Semaste            if (var_expr[0] == '*')
608254721Semaste            {
609254721Semaste                deref = true;
610254721Semaste                var_expr++; // Skip the '*'
611254721Semaste            }
612254721Semaste            else if (var_expr[0] == '&')
613254721Semaste            {
614254721Semaste                address_of = true;
615254721Semaste                var_expr++; // Skip the '&'
616254721Semaste            }
617254721Semaste
618254721Semaste            std::string var_path (var_expr);
619254721Semaste            size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
620254721Semaste            StreamString var_expr_path_strm;
621254721Semaste
622254721Semaste            ConstString name_const_string;
623254721Semaste            if (separator_idx == std::string::npos)
624254721Semaste                name_const_string.SetCString (var_path.c_str());
625254721Semaste            else
626254721Semaste                name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
627254721Semaste
628254721Semaste            var_sp = variable_list->FindVariable(name_const_string);
629254721Semaste
630254721Semaste            bool synthetically_added_instance_object = false;
631254721Semaste
632254721Semaste            if (var_sp)
633254721Semaste            {
634254721Semaste                var_path.erase (0, name_const_string.GetLength ());
635254721Semaste            }
636254721Semaste            else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
637254721Semaste            {
638254721Semaste                // Check for direct ivars access which helps us with implicit
639254721Semaste                // access to ivars with the "this->" or "self->"
640254721Semaste                GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
641254721Semaste                lldb::LanguageType method_language = eLanguageTypeUnknown;
642254721Semaste                bool is_instance_method = false;
643254721Semaste                ConstString method_object_name;
644254721Semaste                if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
645254721Semaste                {
646254721Semaste                    if (is_instance_method && method_object_name)
647254721Semaste                    {
648254721Semaste                        var_sp = variable_list->FindVariable(method_object_name);
649254721Semaste                        if (var_sp)
650254721Semaste                        {
651254721Semaste                            separator_idx = 0;
652254721Semaste                            var_path.insert(0, "->");
653254721Semaste                            synthetically_added_instance_object = true;
654254721Semaste                        }
655254721Semaste                    }
656254721Semaste                }
657254721Semaste            }
658254721Semaste
659254721Semaste            if (var_sp)
660254721Semaste            {
661254721Semaste                valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
662254721Semaste                if (!valobj_sp)
663254721Semaste                    return valobj_sp;
664254721Semaste
665254721Semaste                // We are dumping at least one child
666254721Semaste                while (separator_idx != std::string::npos)
667254721Semaste                {
668254721Semaste                    // Calculate the next separator index ahead of time
669254721Semaste                    ValueObjectSP child_valobj_sp;
670254721Semaste                    const char separator_type = var_path[0];
671254721Semaste                    switch (separator_type)
672254721Semaste                    {
673254721Semaste
674254721Semaste                    case '-':
675254721Semaste                        if (var_path.size() >= 2 && var_path[1] != '>')
676254721Semaste                            return ValueObjectSP();
677254721Semaste
678254721Semaste                        if (no_fragile_ivar)
679254721Semaste                        {
680254721Semaste                            // Make sure we aren't trying to deref an objective
681254721Semaste                            // C ivar if this is not allowed
682254721Semaste                            const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL);
683254721Semaste                            if ((pointer_type_flags & ClangASTType::eTypeIsObjC) &&
684254721Semaste                                (pointer_type_flags & ClangASTType::eTypeIsPointer))
685254721Semaste                            {
686254721Semaste                                // This was an objective C object pointer and
687254721Semaste                                // it was requested we skip any fragile ivars
688254721Semaste                                // so return nothing here
689254721Semaste                                return ValueObjectSP();
690254721Semaste                            }
691254721Semaste                        }
692254721Semaste                        var_path.erase (0, 1); // Remove the '-'
693254721Semaste                        // Fall through
694254721Semaste                    case '.':
695254721Semaste                        {
696254721Semaste                            const bool expr_is_ptr = var_path[0] == '>';
697254721Semaste
698254721Semaste                            var_path.erase (0, 1); // Remove the '.' or '>'
699254721Semaste                            separator_idx = var_path.find_first_of(".-[");
700254721Semaste                            ConstString child_name;
701254721Semaste                            if (separator_idx == std::string::npos)
702254721Semaste                                child_name.SetCString (var_path.c_str());
703254721Semaste                            else
704254721Semaste                                child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
705254721Semaste
706254721Semaste                            if (check_ptr_vs_member)
707254721Semaste                            {
708254721Semaste                                // We either have a pointer type and need to verify
709254721Semaste                                // valobj_sp is a pointer, or we have a member of a
710254721Semaste                                // class/union/struct being accessed with the . syntax
711254721Semaste                                // and need to verify we don't have a pointer.
712254721Semaste                                const bool actual_is_ptr = valobj_sp->IsPointerType ();
713254721Semaste
714254721Semaste                                if (actual_is_ptr != expr_is_ptr)
715254721Semaste                                {
716254721Semaste                                    // Incorrect use of "." with a pointer, or "->" with
717254721Semaste                                    // a class/union/struct instance or reference.
718254721Semaste                                    valobj_sp->GetExpressionPath (var_expr_path_strm, false);
719254721Semaste                                    if (actual_is_ptr)
720254721Semaste                                        error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
721254721Semaste                                                                        var_expr_path_strm.GetString().c_str(),
722254721Semaste                                                                        child_name.GetCString(),
723254721Semaste                                                                        var_expr_path_strm.GetString().c_str(),
724254721Semaste                                                                        var_path.c_str());
725254721Semaste                                    else
726254721Semaste                                        error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
727254721Semaste                                                                        var_expr_path_strm.GetString().c_str(),
728254721Semaste                                                                        child_name.GetCString(),
729254721Semaste                                                                        var_expr_path_strm.GetString().c_str(),
730254721Semaste                                                                        var_path.c_str());
731254721Semaste                                    return ValueObjectSP();
732254721Semaste                                }
733254721Semaste                            }
734254721Semaste                            child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
735254721Semaste                            if (!child_valobj_sp)
736254721Semaste                            {
737254721Semaste                                if (no_synth_child == false)
738254721Semaste                                {
739254721Semaste                                    child_valobj_sp = valobj_sp->GetSyntheticValue();
740254721Semaste                                    if (child_valobj_sp)
741254721Semaste                                        child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
742254721Semaste                                }
743254721Semaste
744254721Semaste                                if (no_synth_child || !child_valobj_sp)
745254721Semaste                                {
746254721Semaste                                    // No child member with name "child_name"
747254721Semaste                                    if (synthetically_added_instance_object)
748254721Semaste                                    {
749254721Semaste                                        // We added a "this->" or "self->" to the beginning of the expression
750254721Semaste                                        // and this is the first pointer ivar access, so just return the normal
751254721Semaste                                        // error
752254721Semaste                                        error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
753254721Semaste                                                                       name_const_string.GetCString());
754254721Semaste                                    }
755254721Semaste                                    else
756254721Semaste                                    {
757254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
758254721Semaste                                        if (child_name)
759254721Semaste                                        {
760254721Semaste                                            error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
761254721Semaste                                                                            child_name.GetCString(),
762254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
763254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
764254721Semaste                                        }
765254721Semaste                                        else
766254721Semaste                                        {
767254721Semaste                                            error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
768254721Semaste                                                                            var_expr_path_strm.GetString().c_str(),
769254721Semaste                                                                            var_expr_cstr);
770254721Semaste                                        }
771254721Semaste                                    }
772254721Semaste                                    return ValueObjectSP();
773254721Semaste                                }
774254721Semaste                            }
775254721Semaste                            synthetically_added_instance_object = false;
776254721Semaste                            // Remove the child name from the path
777254721Semaste                            var_path.erase(0, child_name.GetLength());
778254721Semaste                            if (use_dynamic != eNoDynamicValues)
779254721Semaste                            {
780254721Semaste                                ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
781254721Semaste                                if (dynamic_value_sp)
782254721Semaste                                    child_valobj_sp = dynamic_value_sp;
783254721Semaste                            }
784254721Semaste                        }
785254721Semaste                        break;
786254721Semaste
787254721Semaste                    case '[':
788254721Semaste                        // Array member access, or treating pointer as an array
789254721Semaste                        if (var_path.size() > 2) // Need at least two brackets and a number
790254721Semaste                        {
791254721Semaste                            char *end = NULL;
792254721Semaste                            long child_index = ::strtol (&var_path[1], &end, 0);
793254721Semaste                            if (end && *end == ']'
794254721Semaste                                && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
795254721Semaste                            {
796254721Semaste                                if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
797254721Semaste                                {
798254721Semaste                                    // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
799254721Semaste                                    // and extract bit low out of it. reading array item low
800254721Semaste                                    // would be done by saying ptr[low], without a deref * sign
801254721Semaste                                    Error error;
802254721Semaste                                    ValueObjectSP temp(valobj_sp->Dereference(error));
803254721Semaste                                    if (error.Fail())
804254721Semaste                                    {
805254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
806254721Semaste                                        error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
807254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
808254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
809254721Semaste                                        return ValueObjectSP();
810254721Semaste                                    }
811254721Semaste                                    valobj_sp = temp;
812254721Semaste                                    deref = false;
813254721Semaste                                }
814254721Semaste                                else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
815254721Semaste                                {
816254721Semaste                                    // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
817254721Semaste                                    // (an operation that is equivalent to deref-ing arr)
818254721Semaste                                    // and extract bit low out of it. reading array item low
819254721Semaste                                    // would be done by saying arr[low], without a deref * sign
820254721Semaste                                    Error error;
821254721Semaste                                    ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
822254721Semaste                                    if (error.Fail())
823254721Semaste                                    {
824254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
825254721Semaste                                        error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
826254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
827254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
828254721Semaste                                        return ValueObjectSP();
829254721Semaste                                    }
830254721Semaste                                    valobj_sp = temp;
831254721Semaste                                    deref = false;
832254721Semaste                                }
833254721Semaste
834254721Semaste                                bool is_incomplete_array = false;
835254721Semaste                                if (valobj_sp->IsPointerType ())
836254721Semaste                                {
837254721Semaste                                    bool is_objc_pointer = true;
838254721Semaste
839254721Semaste                                    if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC)
840254721Semaste                                        is_objc_pointer = false;
841254721Semaste                                    else if (!valobj_sp->GetClangType().IsPointerType())
842254721Semaste                                        is_objc_pointer = false;
843254721Semaste
844254721Semaste                                    if (no_synth_child && is_objc_pointer)
845254721Semaste                                    {
846254721Semaste                                        error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
847254721Semaste                                                                       valobj_sp->GetTypeName().AsCString("<invalid type>"),
848254721Semaste                                                                       var_expr_path_strm.GetString().c_str());
849254721Semaste
850254721Semaste                                        return ValueObjectSP();
851254721Semaste                                    }
852254721Semaste                                    else if (is_objc_pointer)
853254721Semaste                                    {
854254721Semaste                                        // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
855254721Semaste                                        ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
856254721Semaste                                        if (synthetic.get() == NULL /* no synthetic */
857254721Semaste                                            || synthetic == valobj_sp) /* synthetic is the same as the original object */
858254721Semaste                                        {
859254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
860254721Semaste                                            error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
861254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
862254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
863254721Semaste                                        }
864254721Semaste                                        else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
865254721Semaste                                        {
866254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
867254721Semaste                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
868254721Semaste                                                                            child_index,
869254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
870254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
871254721Semaste                                        }
872254721Semaste                                        else
873254721Semaste                                        {
874254721Semaste                                            child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
875254721Semaste                                            if (!child_valobj_sp)
876254721Semaste                                            {
877254721Semaste                                                valobj_sp->GetExpressionPath (var_expr_path_strm, false);
878254721Semaste                                                error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
879254721Semaste                                                                                child_index,
880254721Semaste                                                                                valobj_sp->GetTypeName().AsCString("<invalid type>"),
881254721Semaste                                                                                var_expr_path_strm.GetString().c_str());
882254721Semaste                                            }
883254721Semaste                                        }
884254721Semaste                                    }
885254721Semaste                                    else
886254721Semaste                                    {
887254721Semaste                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
888254721Semaste                                        if (!child_valobj_sp)
889254721Semaste                                        {
890254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
891254721Semaste                                            error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
892254721Semaste                                                                            child_index,
893254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
894254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
895254721Semaste                                        }
896254721Semaste                                    }
897254721Semaste                                }
898254721Semaste                                else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array))
899254721Semaste                                {
900254721Semaste                                    // Pass false to dynamic_value here so we can tell the difference between
901254721Semaste                                    // no dynamic value and no member of this type...
902254721Semaste                                    child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
903254721Semaste                                    if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
904254721Semaste                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
905254721Semaste
906254721Semaste                                    if (!child_valobj_sp)
907254721Semaste                                    {
908254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
909254721Semaste                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
910254721Semaste                                                                        child_index,
911254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
912254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
913254721Semaste                                    }
914254721Semaste                                }
915254721Semaste                                else if (valobj_sp->GetClangType().IsScalarType())
916254721Semaste                                {
917254721Semaste                                    // this is a bitfield asking to display just one bit
918254721Semaste                                    child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
919254721Semaste                                    if (!child_valobj_sp)
920254721Semaste                                    {
921254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
922254721Semaste                                        error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
923254721Semaste                                                                        child_index, child_index,
924254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
925254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
926254721Semaste                                    }
927254721Semaste                                }
928254721Semaste                                else
929254721Semaste                                {
930254721Semaste                                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
931254721Semaste                                    if (no_synth_child /* synthetic is forbidden */ ||
932254721Semaste                                        synthetic.get() == NULL /* no synthetic */
933254721Semaste                                        || synthetic == valobj_sp) /* synthetic is the same as the original object */
934254721Semaste                                    {
935254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
936254721Semaste                                        error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
937254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
938254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
939254721Semaste                                    }
940254721Semaste                                    else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
941254721Semaste                                    {
942254721Semaste                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
943254721Semaste                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
944254721Semaste                                                                        child_index,
945254721Semaste                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
946254721Semaste                                                                        var_expr_path_strm.GetString().c_str());
947254721Semaste                                    }
948254721Semaste                                    else
949254721Semaste                                    {
950254721Semaste                                        child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
951254721Semaste                                        if (!child_valobj_sp)
952254721Semaste                                        {
953254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
954254721Semaste                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
955254721Semaste                                                                            child_index,
956254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
957254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
958254721Semaste                                        }
959254721Semaste                                    }
960254721Semaste                                }
961254721Semaste
962254721Semaste                                if (!child_valobj_sp)
963254721Semaste                                {
964254721Semaste                                    // Invalid array index...
965254721Semaste                                    return ValueObjectSP();
966254721Semaste                                }
967254721Semaste
968254721Semaste                                // Erase the array member specification '[%i]' where
969254721Semaste                                // %i is the array index
970254721Semaste                                var_path.erase(0, (end - var_path.c_str()) + 1);
971254721Semaste                                separator_idx = var_path.find_first_of(".-[");
972254721Semaste                                if (use_dynamic != eNoDynamicValues)
973254721Semaste                                {
974254721Semaste                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
975254721Semaste                                    if (dynamic_value_sp)
976254721Semaste                                        child_valobj_sp = dynamic_value_sp;
977254721Semaste                                }
978254721Semaste                                // Break out early from the switch since we were
979254721Semaste                                // able to find the child member
980254721Semaste                                break;
981254721Semaste                            }
982254721Semaste                            else if (end && *end == '-')
983254721Semaste                            {
984254721Semaste                                // this is most probably a BitField, let's take a look
985254721Semaste                                char *real_end = NULL;
986254721Semaste                                long final_index = ::strtol (end+1, &real_end, 0);
987254721Semaste                                bool expand_bitfield = true;
988254721Semaste                                if (real_end && *real_end == ']')
989254721Semaste                                {
990254721Semaste                                    // if the format given is [high-low], swap range
991254721Semaste                                    if (child_index > final_index)
992254721Semaste                                    {
993254721Semaste                                        long temp = child_index;
994254721Semaste                                        child_index = final_index;
995254721Semaste                                        final_index = temp;
996254721Semaste                                    }
997254721Semaste
998254721Semaste                                    if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
999254721Semaste                                    {
1000254721Semaste                                        // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
1001254721Semaste                                        // and extract bits low thru high out of it. reading array items low thru high
1002254721Semaste                                        // would be done by saying ptr[low-high], without a deref * sign
1003254721Semaste                                        Error error;
1004254721Semaste                                        ValueObjectSP temp(valobj_sp->Dereference(error));
1005254721Semaste                                        if (error.Fail())
1006254721Semaste                                        {
1007254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1008254721Semaste                                            error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
1009254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1010254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
1011254721Semaste                                            return ValueObjectSP();
1012254721Semaste                                        }
1013254721Semaste                                        valobj_sp = temp;
1014254721Semaste                                        deref = false;
1015254721Semaste                                    }
1016254721Semaste                                    else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
1017254721Semaste                                    {
1018254721Semaste                                        // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
1019254721Semaste                                        // (an operation that is equivalent to deref-ing arr)
1020254721Semaste                                        // and extract bits low thru high out of it. reading array items low thru high
1021254721Semaste                                        // would be done by saying arr[low-high], without a deref * sign
1022254721Semaste                                        Error error;
1023254721Semaste                                        ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
1024254721Semaste                                        if (error.Fail())
1025254721Semaste                                        {
1026254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1027254721Semaste                                            error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
1028254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1029254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
1030254721Semaste                                            return ValueObjectSP();
1031254721Semaste                                        }
1032254721Semaste                                        valobj_sp = temp;
1033254721Semaste                                        deref = false;
1034254721Semaste                                    }
1035254721Semaste                                    /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
1036254721Semaste                                    {
1037254721Semaste                                        child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
1038254721Semaste                                        expand_bitfield = false;
1039254721Semaste                                        if (!child_valobj_sp)
1040254721Semaste                                        {
1041254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1042254721Semaste                                            error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
1043254721Semaste                                                                            child_index, final_index,
1044254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1045254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
1046254721Semaste                                        }
1047254721Semaste                                    }*/
1048254721Semaste
1049254721Semaste                                    if (expand_bitfield)
1050254721Semaste                                    {
1051254721Semaste                                        child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1052254721Semaste                                        if (!child_valobj_sp)
1053254721Semaste                                        {
1054254721Semaste                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1055254721Semaste                                            error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
1056254721Semaste                                                                            child_index, final_index,
1057254721Semaste                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1058254721Semaste                                                                            var_expr_path_strm.GetString().c_str());
1059254721Semaste                                        }
1060254721Semaste                                    }
1061254721Semaste                                }
1062254721Semaste
1063254721Semaste                                if (!child_valobj_sp)
1064254721Semaste                                {
1065254721Semaste                                    // Invalid bitfield range...
1066254721Semaste                                    return ValueObjectSP();
1067254721Semaste                                }
1068254721Semaste
1069254721Semaste                                // Erase the bitfield member specification '[%i-%i]' where
1070254721Semaste                                // %i is the index
1071254721Semaste                                var_path.erase(0, (real_end - var_path.c_str()) + 1);
1072254721Semaste                                separator_idx = var_path.find_first_of(".-[");
1073254721Semaste                                if (use_dynamic != eNoDynamicValues)
1074254721Semaste                                {
1075254721Semaste                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
1076254721Semaste                                    if (dynamic_value_sp)
1077254721Semaste                                        child_valobj_sp = dynamic_value_sp;
1078254721Semaste                                }
1079254721Semaste                                // Break out early from the switch since we were
1080254721Semaste                                // able to find the child member
1081254721Semaste                                break;
1082254721Semaste
1083254721Semaste                            }
1084254721Semaste                        }
1085254721Semaste                        else
1086254721Semaste                        {
1087254721Semaste                            error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
1088254721Semaste                                                           var_expr_path_strm.GetString().c_str(),
1089254721Semaste                                                           var_path.c_str());
1090254721Semaste                        }
1091254721Semaste                        return ValueObjectSP();
1092254721Semaste
1093254721Semaste                    default:
1094254721Semaste                        // Failure...
1095254721Semaste                        {
1096254721Semaste                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1097254721Semaste                            error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
1098254721Semaste                                                            separator_type,
1099254721Semaste                                                            var_expr_path_strm.GetString().c_str(),
1100254721Semaste                                                            var_path.c_str());
1101254721Semaste
1102254721Semaste                            return ValueObjectSP();
1103254721Semaste                        }
1104254721Semaste                    }
1105254721Semaste
1106254721Semaste                    if (child_valobj_sp)
1107254721Semaste                        valobj_sp = child_valobj_sp;
1108254721Semaste
1109254721Semaste                    if (var_path.empty())
1110254721Semaste                        break;
1111254721Semaste
1112254721Semaste                }
1113254721Semaste                if (valobj_sp)
1114254721Semaste                {
1115254721Semaste                    if (deref)
1116254721Semaste                    {
1117254721Semaste                        ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
1118254721Semaste                        valobj_sp = deref_valobj_sp;
1119254721Semaste                    }
1120254721Semaste                    else if (address_of)
1121254721Semaste                    {
1122254721Semaste                        ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
1123254721Semaste                        valobj_sp = address_of_valobj_sp;
1124254721Semaste                    }
1125254721Semaste                }
1126254721Semaste                return valobj_sp;
1127254721Semaste            }
1128254721Semaste            else
1129254721Semaste            {
1130254721Semaste                error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
1131254721Semaste                                               name_const_string.GetCString());
1132254721Semaste            }
1133254721Semaste        }
1134254721Semaste    }
1135254721Semaste    else
1136254721Semaste    {
1137254721Semaste        error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
1138254721Semaste    }
1139254721Semaste    return ValueObjectSP();
1140254721Semaste}
1141254721Semaste
1142254721Semastebool
1143254721SemasteStackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
1144254721Semaste{
1145263363Semaste    if (m_cfa_is_valid == false)
1146263363Semaste    {
1147263363Semaste        m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
1148263363Semaste        return false;
1149263363Semaste    }
1150263363Semaste
1151254721Semaste    if (m_flags.IsClear(GOT_FRAME_BASE))
1152254721Semaste    {
1153254721Semaste        if (m_sc.function)
1154254721Semaste        {
1155254721Semaste            m_frame_base.Clear();
1156254721Semaste            m_frame_base_error.Clear();
1157254721Semaste
1158254721Semaste            m_flags.Set(GOT_FRAME_BASE);
1159254721Semaste            ExecutionContext exe_ctx (shared_from_this());
1160254721Semaste            Value expr_value;
1161254721Semaste            addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1162254721Semaste            if (m_sc.function->GetFrameBaseExpression().IsLocationList())
1163254721Semaste                loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
1164254721Semaste
1165254721Semaste            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
1166254721Semaste            {
1167254721Semaste                // We should really have an error if evaluate returns, but in case
1168254721Semaste                // we don't, lets set the error to something at least.
1169254721Semaste                if (m_frame_base_error.Success())
1170254721Semaste                    m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
1171254721Semaste            }
1172254721Semaste            else
1173254721Semaste            {
1174254721Semaste                m_frame_base = expr_value.ResolveValue(&exe_ctx);
1175254721Semaste            }
1176254721Semaste        }
1177254721Semaste        else
1178254721Semaste        {
1179254721Semaste            m_frame_base_error.SetErrorString ("No function in symbol context.");
1180254721Semaste        }
1181254721Semaste    }
1182254721Semaste
1183254721Semaste    if (m_frame_base_error.Success())
1184254721Semaste        frame_base = m_frame_base;
1185254721Semaste
1186254721Semaste    if (error_ptr)
1187254721Semaste        *error_ptr = m_frame_base_error;
1188254721Semaste    return m_frame_base_error.Success();
1189254721Semaste}
1190254721Semaste
1191254721SemasteRegisterContextSP
1192254721SemasteStackFrame::GetRegisterContext ()
1193254721Semaste{
1194254721Semaste    if (!m_reg_context_sp)
1195254721Semaste    {
1196254721Semaste        ThreadSP thread_sp (GetThread());
1197254721Semaste        if (thread_sp)
1198254721Semaste            m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
1199254721Semaste    }
1200254721Semaste    return m_reg_context_sp;
1201254721Semaste}
1202254721Semaste
1203254721Semastebool
1204254721SemasteStackFrame::HasDebugInformation ()
1205254721Semaste{
1206254721Semaste    GetSymbolContext (eSymbolContextLineEntry);
1207254721Semaste    return m_sc.line_entry.IsValid();
1208254721Semaste}
1209254721Semaste
1210254721Semaste
1211254721SemasteValueObjectSP
1212254721SemasteStackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1213254721Semaste{
1214254721Semaste    ValueObjectSP valobj_sp;
1215263363Semaste    if (m_is_history_frame)
1216263363Semaste    {
1217263363Semaste        return valobj_sp;
1218263363Semaste    }
1219254721Semaste    VariableList *var_list = GetVariableList (true);
1220254721Semaste    if (var_list)
1221254721Semaste    {
1222254721Semaste        // Make sure the variable is a frame variable
1223254721Semaste        const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
1224254721Semaste        const uint32_t num_variables = var_list->GetSize();
1225254721Semaste        if (var_idx < num_variables)
1226254721Semaste        {
1227254721Semaste            valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
1228254721Semaste            if (valobj_sp.get() == NULL)
1229254721Semaste            {
1230254721Semaste                if (m_variable_list_value_objects.GetSize() < num_variables)
1231254721Semaste                    m_variable_list_value_objects.Resize(num_variables);
1232254721Semaste                valobj_sp = ValueObjectVariable::Create (this, variable_sp);
1233254721Semaste                m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
1234254721Semaste            }
1235254721Semaste        }
1236254721Semaste    }
1237254721Semaste    if (use_dynamic != eNoDynamicValues && valobj_sp)
1238254721Semaste    {
1239254721Semaste        ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
1240254721Semaste        if (dynamic_sp)
1241254721Semaste            return dynamic_sp;
1242254721Semaste    }
1243254721Semaste    return valobj_sp;
1244254721Semaste}
1245254721Semaste
1246254721SemasteValueObjectSP
1247254721SemasteStackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1248254721Semaste{
1249263363Semaste    if (m_is_history_frame)
1250263363Semaste        return ValueObjectSP();
1251263363Semaste
1252254721Semaste    // Check to make sure we aren't already tracking this variable?
1253254721Semaste    ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
1254254721Semaste    if (!valobj_sp)
1255254721Semaste    {
1256254721Semaste        // We aren't already tracking this global
1257254721Semaste        VariableList *var_list = GetVariableList (true);
1258254721Semaste        // If this frame has no variables, create a new list
1259254721Semaste        if (var_list == NULL)
1260254721Semaste            m_variable_list_sp.reset (new VariableList());
1261254721Semaste
1262254721Semaste        // Add the global/static variable to this frame
1263254721Semaste        m_variable_list_sp->AddVariable (variable_sp);
1264254721Semaste
1265254721Semaste        // Now make a value object for it so we can track its changes
1266254721Semaste        valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
1267254721Semaste    }
1268254721Semaste    return valobj_sp;
1269254721Semaste}
1270254721Semaste
1271254721Semastebool
1272254721SemasteStackFrame::IsInlined ()
1273254721Semaste{
1274254721Semaste    if (m_sc.block == NULL)
1275254721Semaste        GetSymbolContext (eSymbolContextBlock);
1276254721Semaste    if (m_sc.block)
1277254721Semaste        return m_sc.block->GetContainingInlinedBlock() != NULL;
1278254721Semaste    return false;
1279254721Semaste}
1280254721Semaste
1281254721SemasteTargetSP
1282254721SemasteStackFrame::CalculateTarget ()
1283254721Semaste{
1284254721Semaste    TargetSP target_sp;
1285254721Semaste    ThreadSP thread_sp(GetThread());
1286254721Semaste    if (thread_sp)
1287254721Semaste    {
1288254721Semaste        ProcessSP process_sp (thread_sp->CalculateProcess());
1289254721Semaste        if (process_sp)
1290254721Semaste            target_sp = process_sp->CalculateTarget();
1291254721Semaste    }
1292254721Semaste    return target_sp;
1293254721Semaste}
1294254721Semaste
1295254721SemasteProcessSP
1296254721SemasteStackFrame::CalculateProcess ()
1297254721Semaste{
1298254721Semaste    ProcessSP process_sp;
1299254721Semaste    ThreadSP thread_sp(GetThread());
1300254721Semaste    if (thread_sp)
1301254721Semaste        process_sp = thread_sp->CalculateProcess();
1302254721Semaste    return process_sp;
1303254721Semaste}
1304254721Semaste
1305254721SemasteThreadSP
1306254721SemasteStackFrame::CalculateThread ()
1307254721Semaste{
1308254721Semaste    return GetThread();
1309254721Semaste}
1310254721Semaste
1311254721SemasteStackFrameSP
1312254721SemasteStackFrame::CalculateStackFrame ()
1313254721Semaste{
1314254721Semaste    return shared_from_this();
1315254721Semaste}
1316254721Semaste
1317254721Semaste
1318254721Semastevoid
1319254721SemasteStackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
1320254721Semaste{
1321254721Semaste    exe_ctx.SetContext (shared_from_this());
1322254721Semaste}
1323254721Semaste
1324254721Semastevoid
1325263363SemasteStackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
1326254721Semaste{
1327254721Semaste    if (strm == NULL)
1328254721Semaste        return;
1329254721Semaste
1330254721Semaste    GetSymbolContext(eSymbolContextEverything);
1331254721Semaste    ExecutionContext exe_ctx (shared_from_this());
1332254721Semaste    StreamString s;
1333263363Semaste
1334263363Semaste    if (frame_marker)
1335263363Semaste        s.PutCString(frame_marker);
1336263363Semaste
1337254721Semaste    const char *frame_format = NULL;
1338254721Semaste    Target *target = exe_ctx.GetTargetPtr();
1339254721Semaste    if (target)
1340254721Semaste        frame_format = target->GetDebugger().GetFrameFormat();
1341254721Semaste    if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
1342254721Semaste    {
1343254721Semaste        strm->Write(s.GetData(), s.GetSize());
1344254721Semaste    }
1345254721Semaste    else
1346254721Semaste    {
1347254721Semaste        Dump (strm, true, false);
1348254721Semaste        strm->EOL();
1349254721Semaste    }
1350254721Semaste}
1351254721Semaste
1352254721Semastevoid
1353254721SemasteStackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
1354254721Semaste{
1355254721Semaste    if (strm == NULL)
1356254721Semaste        return;
1357254721Semaste
1358254721Semaste    if (show_frame_index)
1359254721Semaste        strm->Printf("frame #%u: ", m_frame_index);
1360254721Semaste    ExecutionContext exe_ctx (shared_from_this());
1361254721Semaste    Target *target = exe_ctx.GetTargetPtr();
1362254721Semaste    strm->Printf("0x%0*" PRIx64 " ",
1363254721Semaste                 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
1364254721Semaste                 GetFrameCodeAddress().GetLoadAddress(target));
1365254721Semaste    GetSymbolContext(eSymbolContextEverything);
1366254721Semaste    const bool show_module = true;
1367254721Semaste    const bool show_inline = true;
1368254721Semaste    m_sc.DumpStopContext (strm,
1369254721Semaste                          exe_ctx.GetBestExecutionContextScope(),
1370254721Semaste                          GetFrameCodeAddress(),
1371254721Semaste                          show_fullpaths,
1372254721Semaste                          show_module,
1373254721Semaste                          show_inline);
1374254721Semaste}
1375254721Semaste
1376254721Semastevoid
1377254721SemasteStackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
1378254721Semaste{
1379254721Semaste    assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
1380254721Semaste    m_variable_list_sp = prev_frame.m_variable_list_sp;
1381254721Semaste    m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
1382254721Semaste    if (!m_disassembly.GetString().empty())
1383254721Semaste        m_disassembly.GetString().swap (m_disassembly.GetString());
1384254721Semaste}
1385254721Semaste
1386254721Semaste
1387254721Semastevoid
1388254721SemasteStackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
1389254721Semaste{
1390254721Semaste    assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
1391254721Semaste    m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
1392254721Semaste    assert (GetThread() == curr_frame.GetThread());
1393254721Semaste    m_frame_index = curr_frame.m_frame_index;
1394254721Semaste    m_concrete_frame_index = curr_frame.m_concrete_frame_index;
1395254721Semaste    m_reg_context_sp = curr_frame.m_reg_context_sp;
1396254721Semaste    m_frame_code_addr = curr_frame.m_frame_code_addr;
1397254721Semaste    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());
1398254721Semaste    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());
1399254721Semaste    assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1400254721Semaste    assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
1401254721Semaste    m_sc = curr_frame.m_sc;
1402254721Semaste    m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1403254721Semaste    m_flags.Set (m_sc.GetResolvedMask());
1404254721Semaste    m_frame_base.Clear();
1405254721Semaste    m_frame_base_error.Clear();
1406254721Semaste}
1407254721Semaste
1408254721Semaste
1409254721Semastebool
1410254721SemasteStackFrame::HasCachedData () const
1411254721Semaste{
1412254721Semaste    if (m_variable_list_sp.get())
1413254721Semaste        return true;
1414254721Semaste    if (m_variable_list_value_objects.GetSize() > 0)
1415254721Semaste        return true;
1416254721Semaste    if (!m_disassembly.GetString().empty())
1417254721Semaste        return true;
1418254721Semaste    return false;
1419254721Semaste}
1420254721Semaste
1421254721Semastebool
1422254721SemasteStackFrame::GetStatus (Stream& strm,
1423254721Semaste                       bool show_frame_info,
1424263363Semaste                       bool show_source,
1425263363Semaste                       const char *frame_marker)
1426254721Semaste{
1427254721Semaste
1428254721Semaste    if (show_frame_info)
1429254721Semaste    {
1430254721Semaste        strm.Indent();
1431263363Semaste        DumpUsingSettingsFormat (&strm, frame_marker);
1432254721Semaste    }
1433254721Semaste
1434254721Semaste    if (show_source)
1435254721Semaste    {
1436254721Semaste        ExecutionContext exe_ctx (shared_from_this());
1437254721Semaste        bool have_source = false;
1438254721Semaste        Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
1439254721Semaste        Target *target = exe_ctx.GetTargetPtr();
1440254721Semaste        if (target)
1441254721Semaste        {
1442254721Semaste            Debugger &debugger = target->GetDebugger();
1443254721Semaste            const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
1444254721Semaste            const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
1445254721Semaste            disasm_display = debugger.GetStopDisassemblyDisplay ();
1446254721Semaste
1447254721Semaste            if (source_lines_before > 0 || source_lines_after > 0)
1448254721Semaste            {
1449254721Semaste                GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1450254721Semaste
1451254721Semaste                if (m_sc.comp_unit && m_sc.line_entry.IsValid())
1452254721Semaste                {
1453254721Semaste                    have_source = true;
1454254721Semaste                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
1455254721Semaste                                                                                      m_sc.line_entry.line,
1456254721Semaste                                                                                      source_lines_before,
1457254721Semaste                                                                                      source_lines_after,
1458254721Semaste                                                                                      "->",
1459254721Semaste                                                                                      &strm);
1460254721Semaste                }
1461254721Semaste            }
1462254721Semaste            switch (disasm_display)
1463254721Semaste            {
1464254721Semaste            case Debugger::eStopDisassemblyTypeNever:
1465254721Semaste                break;
1466254721Semaste
1467254721Semaste            case Debugger::eStopDisassemblyTypeNoSource:
1468254721Semaste                if (have_source)
1469254721Semaste                    break;
1470254721Semaste                // Fall through to next case
1471254721Semaste            case Debugger::eStopDisassemblyTypeAlways:
1472254721Semaste                if (target)
1473254721Semaste                {
1474254721Semaste                    const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
1475254721Semaste                    if (disasm_lines > 0)
1476254721Semaste                    {
1477254721Semaste                        const ArchSpec &target_arch = target->GetArchitecture();
1478254721Semaste                        AddressRange pc_range;
1479254721Semaste                        pc_range.GetBaseAddress() = GetFrameCodeAddress();
1480254721Semaste                        pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
1481254721Semaste                        const char *plugin_name = NULL;
1482254721Semaste                        const char *flavor = NULL;
1483254721Semaste                        Disassembler::Disassemble (target->GetDebugger(),
1484254721Semaste                                                   target_arch,
1485254721Semaste                                                   plugin_name,
1486254721Semaste                                                   flavor,
1487254721Semaste                                                   exe_ctx,
1488254721Semaste                                                   pc_range,
1489254721Semaste                                                   disasm_lines,
1490254721Semaste                                                   0,
1491254721Semaste                                                   Disassembler::eOptionMarkPCAddress,
1492254721Semaste                                                   strm);
1493254721Semaste                    }
1494254721Semaste                }
1495254721Semaste                break;
1496254721Semaste            }
1497254721Semaste        }
1498254721Semaste    }
1499254721Semaste    return true;
1500254721Semaste}
1501254721Semaste
1502