1//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12#include "lldb/Target/StackFrame.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Core/Module.h"
19#include "lldb/Core/Debugger.h"
20#include "lldb/Core/Disassembler.h"
21#include "lldb/Core/Value.h"
22#include "lldb/Core/ValueObjectVariable.h"
23#include "lldb/Core/ValueObjectConstResult.h"
24#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Function.h"
26#include "lldb/Symbol/Symbol.h"
27#include "lldb/Symbol/SymbolContextScope.h"
28#include "lldb/Symbol/VariableList.h"
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/Process.h"
31#include "lldb/Target/RegisterContext.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38// The first bits in the flags are reserved for the SymbolContext::Scope bits
39// so we know if we have tried to look up information in our internal symbol
40// context (m_sc) already.
41#define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
42#define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
43#define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
44#define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
45#define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
46
47StackFrame::StackFrame (const ThreadSP &thread_sp,
48                        user_id_t frame_idx,
49                        user_id_t unwind_frame_index,
50                        addr_t cfa,
51                        bool cfa_is_valid,
52                        addr_t pc,
53                        uint32_t stop_id,
54                        bool stop_id_is_valid,
55                        bool is_history_frame,
56                        const SymbolContext *sc_ptr) :
57    m_thread_wp (thread_sp),
58    m_frame_index (frame_idx),
59    m_concrete_frame_index (unwind_frame_index),
60    m_reg_context_sp (),
61    m_id (pc, cfa, NULL),
62    m_frame_code_addr (pc),
63    m_sc (),
64    m_flags (),
65    m_frame_base (),
66    m_frame_base_error (),
67    m_cfa_is_valid (cfa_is_valid),
68    m_stop_id  (stop_id),
69    m_stop_id_is_valid (stop_id_is_valid),
70    m_is_history_frame (is_history_frame),
71    m_variable_list_sp (),
72    m_variable_list_value_objects (),
73    m_disassembly ()
74{
75    // If we don't have a CFA value, use the frame index for our StackID so that recursive
76    // functions properly aren't confused with one another on a history stack.
77    if (m_is_history_frame && m_cfa_is_valid == false)
78    {
79        m_id.SetCFA (m_frame_index);
80    }
81
82    if (sc_ptr != NULL)
83    {
84        m_sc = *sc_ptr;
85        m_flags.Set(m_sc.GetResolvedMask ());
86    }
87}
88
89StackFrame::StackFrame (const ThreadSP &thread_sp,
90                        user_id_t frame_idx,
91                        user_id_t unwind_frame_index,
92                        const RegisterContextSP &reg_context_sp,
93                        addr_t cfa,
94                        addr_t pc,
95                        const SymbolContext *sc_ptr) :
96    m_thread_wp (thread_sp),
97    m_frame_index (frame_idx),
98    m_concrete_frame_index (unwind_frame_index),
99    m_reg_context_sp (reg_context_sp),
100    m_id (pc, cfa, NULL),
101    m_frame_code_addr (pc),
102    m_sc (),
103    m_flags (),
104    m_frame_base (),
105    m_frame_base_error (),
106    m_cfa_is_valid (true),
107    m_stop_id  (0),
108    m_stop_id_is_valid (false),
109    m_is_history_frame (false),
110    m_variable_list_sp (),
111    m_variable_list_value_objects (),
112    m_disassembly ()
113{
114    if (sc_ptr != NULL)
115    {
116        m_sc = *sc_ptr;
117        m_flags.Set(m_sc.GetResolvedMask ());
118    }
119
120    if (reg_context_sp && !m_sc.target_sp)
121    {
122        m_sc.target_sp = reg_context_sp->CalculateTarget();
123        if (m_sc.target_sp)
124            m_flags.Set (eSymbolContextTarget);
125    }
126}
127
128StackFrame::StackFrame (const ThreadSP &thread_sp,
129                        user_id_t frame_idx,
130                        user_id_t unwind_frame_index,
131                        const RegisterContextSP &reg_context_sp,
132                        addr_t cfa,
133                        const Address& pc_addr,
134                        const SymbolContext *sc_ptr) :
135    m_thread_wp (thread_sp),
136    m_frame_index (frame_idx),
137    m_concrete_frame_index (unwind_frame_index),
138    m_reg_context_sp (reg_context_sp),
139    m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
140    m_frame_code_addr (pc_addr),
141    m_sc (),
142    m_flags (),
143    m_frame_base (),
144    m_frame_base_error (),
145    m_cfa_is_valid (true),
146    m_stop_id  (0),
147    m_stop_id_is_valid (false),
148    m_is_history_frame (false),
149    m_variable_list_sp (),
150    m_variable_list_value_objects (),
151    m_disassembly ()
152{
153    if (sc_ptr != NULL)
154    {
155        m_sc = *sc_ptr;
156        m_flags.Set(m_sc.GetResolvedMask ());
157    }
158
159    if (m_sc.target_sp.get() == NULL && reg_context_sp)
160    {
161        m_sc.target_sp = reg_context_sp->CalculateTarget();
162        if (m_sc.target_sp)
163            m_flags.Set (eSymbolContextTarget);
164    }
165
166    ModuleSP pc_module_sp (pc_addr.GetModule());
167    if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
168    {
169        if (pc_module_sp)
170        {
171            m_sc.module_sp = pc_module_sp;
172            m_flags.Set (eSymbolContextModule);
173        }
174        else
175        {
176            m_sc.module_sp.reset();
177        }
178    }
179}
180
181
182//----------------------------------------------------------------------
183// Destructor
184//----------------------------------------------------------------------
185StackFrame::~StackFrame()
186{
187}
188
189StackID&
190StackFrame::GetStackID()
191{
192    // Make sure we have resolved the StackID object's symbol context scope if
193    // we already haven't looked it up.
194
195    if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
196    {
197        if (m_id.GetSymbolContextScope ())
198        {
199            // We already have a symbol context scope, we just don't have our
200            // flag bit set.
201            m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
202        }
203        else
204        {
205            // Calculate the frame block and use this for the stack ID symbol
206            // context scope if we have one.
207            SymbolContextScope *scope = GetFrameBlock ();
208            if (scope == NULL)
209            {
210                // We don't have a block, so use the symbol
211                if (m_flags.IsClear (eSymbolContextSymbol))
212                    GetSymbolContext (eSymbolContextSymbol);
213
214                // It is ok if m_sc.symbol is NULL here
215                scope = m_sc.symbol;
216            }
217            // Set the symbol context scope (the accessor will set the
218            // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
219            SetSymbolContextScope (scope);
220        }
221    }
222    return m_id;
223}
224
225uint32_t
226StackFrame::GetFrameIndex () const
227{
228    ThreadSP thread_sp = GetThread();
229    if (thread_sp)
230        return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
231    else
232        return m_frame_index;
233}
234
235void
236StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
237{
238    m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
239    m_id.SetSymbolContextScope (symbol_scope);
240}
241
242const Address&
243StackFrame::GetFrameCodeAddress()
244{
245    if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
246    {
247        m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
248
249        // Resolve the PC into a temporary address because if ResolveLoadAddress
250        // fails to resolve the address, it will clear the address object...
251        ThreadSP thread_sp (GetThread());
252        if (thread_sp)
253        {
254            TargetSP target_sp (thread_sp->CalculateTarget());
255            if (target_sp)
256            {
257                if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get()))
258                {
259                    ModuleSP module_sp (m_frame_code_addr.GetModule());
260                    if (module_sp)
261                    {
262                        m_sc.module_sp = module_sp;
263                        m_flags.Set(eSymbolContextModule);
264                    }
265                }
266            }
267        }
268    }
269    return m_frame_code_addr;
270}
271
272bool
273StackFrame::ChangePC (addr_t pc)
274{
275    // We can't change the pc value of a history stack frame - it is immutable.
276    if (m_is_history_frame)
277        return false;
278    m_frame_code_addr.SetRawAddress(pc);
279    m_sc.Clear(false);
280    m_flags.Reset(0);
281    ThreadSP thread_sp (GetThread());
282    if (thread_sp)
283        thread_sp->ClearStackFrames ();
284    return true;
285}
286
287const char *
288StackFrame::Disassemble ()
289{
290    if (m_disassembly.GetSize() == 0)
291    {
292        ExecutionContext exe_ctx (shared_from_this());
293        Target *target = exe_ctx.GetTargetPtr();
294        if (target)
295        {
296            const char *plugin_name = NULL;
297            const char *flavor = NULL;
298            Disassembler::Disassemble (target->GetDebugger(),
299                                       target->GetArchitecture(),
300                                       plugin_name,
301                                       flavor,
302                                       exe_ctx,
303                                       0,
304                                       0,
305                                       0,
306                                       m_disassembly);
307        }
308        if (m_disassembly.GetSize() == 0)
309            return NULL;
310    }
311    return m_disassembly.GetData();
312}
313
314Block *
315StackFrame::GetFrameBlock ()
316{
317    if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
318        GetSymbolContext (eSymbolContextBlock);
319
320    if (m_sc.block)
321    {
322        Block *inline_block = m_sc.block->GetContainingInlinedBlock();
323        if (inline_block)
324        {
325            // Use the block with the inlined function info
326            // as the frame block we want this frame to have only the variables
327            // for the inlined function and its non-inlined block child blocks.
328            return inline_block;
329        }
330        else
331        {
332            // This block is not contained withing any inlined function blocks
333            // with so we want to use the top most function block.
334            return &m_sc.function->GetBlock (false);
335        }
336    }
337    return NULL;
338}
339
340//----------------------------------------------------------------------
341// Get the symbol context if we already haven't done so by resolving the
342// PC address as much as possible. This way when we pass around a
343// StackFrame object, everyone will have as much information as
344// possible and no one will ever have to look things up manually.
345//----------------------------------------------------------------------
346const SymbolContext&
347StackFrame::GetSymbolContext (uint32_t resolve_scope)
348{
349    // Copy our internal symbol context into "sc".
350    if ((m_flags.Get() & resolve_scope) != resolve_scope)
351    {
352        uint32_t resolved = 0;
353
354        // If the target was requested add that:
355        if (!m_sc.target_sp)
356        {
357            m_sc.target_sp = CalculateTarget();
358            if (m_sc.target_sp)
359                resolved |= eSymbolContextTarget;
360        }
361
362
363        // Resolve our PC to section offset if we haven't alreday done so
364        // and if we don't have a module. The resolved address section will
365        // contain the module to which it belongs
366        if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
367            GetFrameCodeAddress();
368
369        // If this is not frame zero, then we need to subtract 1 from the PC
370        // value when doing address lookups since the PC will be on the
371        // instruction following the function call instruction...
372
373        Address lookup_addr(GetFrameCodeAddress());
374        if (m_frame_index > 0 && lookup_addr.IsValid())
375        {
376            addr_t offset = lookup_addr.GetOffset();
377            if (offset > 0)
378                lookup_addr.SetOffset(offset - 1);
379        }
380
381
382        if (m_sc.module_sp)
383        {
384            // We have something in our stack frame symbol context, lets check
385            // if we haven't already tried to lookup one of those things. If we
386            // haven't then we will do the query.
387
388            uint32_t actual_resolve_scope = 0;
389
390            if (resolve_scope & eSymbolContextCompUnit)
391            {
392                if (m_flags.IsClear (eSymbolContextCompUnit))
393                {
394                    if (m_sc.comp_unit)
395                        resolved |= eSymbolContextCompUnit;
396                    else
397                        actual_resolve_scope |= eSymbolContextCompUnit;
398                }
399            }
400
401            if (resolve_scope & eSymbolContextFunction)
402            {
403                if (m_flags.IsClear (eSymbolContextFunction))
404                {
405                    if (m_sc.function)
406                        resolved |= eSymbolContextFunction;
407                    else
408                        actual_resolve_scope |= eSymbolContextFunction;
409                }
410            }
411
412            if (resolve_scope & eSymbolContextBlock)
413            {
414                if (m_flags.IsClear (eSymbolContextBlock))
415                {
416                    if (m_sc.block)
417                        resolved |= eSymbolContextBlock;
418                    else
419                        actual_resolve_scope |= eSymbolContextBlock;
420                }
421            }
422
423            if (resolve_scope & eSymbolContextSymbol)
424            {
425                if (m_flags.IsClear (eSymbolContextSymbol))
426                {
427                    if (m_sc.symbol)
428                        resolved |= eSymbolContextSymbol;
429                    else
430                        actual_resolve_scope |= eSymbolContextSymbol;
431                }
432            }
433
434            if (resolve_scope & eSymbolContextLineEntry)
435            {
436                if (m_flags.IsClear (eSymbolContextLineEntry))
437                {
438                    if (m_sc.line_entry.IsValid())
439                        resolved |= eSymbolContextLineEntry;
440                    else
441                        actual_resolve_scope |= eSymbolContextLineEntry;
442                }
443            }
444
445            if (actual_resolve_scope)
446            {
447                // We might be resolving less information than what is already
448                // in our current symbol context so resolve into a temporary
449                // symbol context "sc" so we don't clear out data we have
450                // already found in "m_sc"
451                SymbolContext sc;
452                // Set flags that indicate what we have tried to resolve
453                resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
454                // Only replace what we didn't already have as we may have
455                // information for an inlined function scope that won't match
456                // what a standard lookup by address would match
457                if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
458                    m_sc.comp_unit = sc.comp_unit;
459                if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
460                    m_sc.function = sc.function;
461                if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
462                    m_sc.block = sc.block;
463                if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
464                    m_sc.symbol = sc.symbol;
465                if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
466                {
467                    m_sc.line_entry = sc.line_entry;
468                    if (m_sc.target_sp)
469                    {
470                        // Be sure to apply and file remappings to our file and line
471                        // entries when handing out a line entry
472                        FileSpec new_file_spec;
473                        if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
474                            m_sc.line_entry.file = new_file_spec;
475                    }
476                }
477            }
478        }
479        else
480        {
481            // If we don't have a module, then we can't have the compile unit,
482            // function, block, line entry or symbol, so we can safely call
483            // ResolveSymbolContextForAddress with our symbol context member m_sc.
484            if (m_sc.target_sp)
485            {
486                resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
487            }
488        }
489
490        // Update our internal flags so we remember what we have tried to locate so
491        // we don't have to keep trying when more calls to this function are made.
492        // We might have dug up more information that was requested (for example
493        // if we were asked to only get the block, we will have gotten the
494        // compile unit, and function) so set any additional bits that we resolved
495        m_flags.Set (resolve_scope | resolved);
496    }
497
498    // Return the symbol context with everything that was possible to resolve
499    // resolved.
500    return m_sc;
501}
502
503
504VariableList *
505StackFrame::GetVariableList (bool get_file_globals)
506{
507    if (m_flags.IsClear(RESOLVED_VARIABLES))
508    {
509        m_flags.Set(RESOLVED_VARIABLES);
510
511        Block *frame_block = GetFrameBlock();
512
513        if (frame_block)
514        {
515            const bool get_child_variables = true;
516            const bool can_create = true;
517            const bool stop_if_child_block_is_inlined_function = true;
518            m_variable_list_sp.reset(new VariableList());
519            frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
520        }
521    }
522
523    if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
524        get_file_globals)
525    {
526        m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
527
528        if (m_flags.IsClear (eSymbolContextCompUnit))
529            GetSymbolContext (eSymbolContextCompUnit);
530
531        if (m_sc.comp_unit)
532        {
533            VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
534            if (m_variable_list_sp)
535                m_variable_list_sp->AddVariables (global_variable_list_sp.get());
536            else
537                m_variable_list_sp = global_variable_list_sp;
538        }
539    }
540
541    return m_variable_list_sp.get();
542}
543
544VariableListSP
545StackFrame::GetInScopeVariableList (bool get_file_globals)
546{
547    // We can't fetch variable information for a history stack frame.
548    if (m_is_history_frame)
549        return VariableListSP();
550
551    VariableListSP var_list_sp(new VariableList);
552    GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
553
554    if (m_sc.block)
555    {
556        const bool can_create = true;
557        const bool get_parent_variables = true;
558        const bool stop_if_block_is_inlined_function = true;
559        m_sc.block->AppendVariables (can_create,
560                                     get_parent_variables,
561                                     stop_if_block_is_inlined_function,
562                                     var_list_sp.get());
563    }
564
565    if (m_sc.comp_unit)
566    {
567        VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
568        if (global_variable_list_sp)
569            var_list_sp->AddVariables (global_variable_list_sp.get());
570    }
571
572    return var_list_sp;
573}
574
575
576ValueObjectSP
577StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
578                                               DynamicValueType use_dynamic,
579                                               uint32_t options,
580                                               VariableSP &var_sp,
581                                               Error &error)
582{
583    // We can't fetch variable information for a history stack frame.
584    if (m_is_history_frame)
585        return ValueObjectSP();
586
587    if (var_expr_cstr && var_expr_cstr[0])
588    {
589        const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
590        const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
591        const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
592        //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
593        error.Clear();
594        bool deref = false;
595        bool address_of = false;
596        ValueObjectSP valobj_sp;
597        const bool get_file_globals = true;
598        // When looking up a variable for an expression, we need only consider the
599        // variables that are in scope.
600        VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
601        VariableList *variable_list = var_list_sp.get();
602
603        if (variable_list)
604        {
605            // If first character is a '*', then show pointer contents
606            const char *var_expr = var_expr_cstr;
607            if (var_expr[0] == '*')
608            {
609                deref = true;
610                var_expr++; // Skip the '*'
611            }
612            else if (var_expr[0] == '&')
613            {
614                address_of = true;
615                var_expr++; // Skip the '&'
616            }
617
618            std::string var_path (var_expr);
619            size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
620            StreamString var_expr_path_strm;
621
622            ConstString name_const_string;
623            if (separator_idx == std::string::npos)
624                name_const_string.SetCString (var_path.c_str());
625            else
626                name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
627
628            var_sp = variable_list->FindVariable(name_const_string);
629
630            bool synthetically_added_instance_object = false;
631
632            if (var_sp)
633            {
634                var_path.erase (0, name_const_string.GetLength ());
635            }
636            else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
637            {
638                // Check for direct ivars access which helps us with implicit
639                // access to ivars with the "this->" or "self->"
640                GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
641                lldb::LanguageType method_language = eLanguageTypeUnknown;
642                bool is_instance_method = false;
643                ConstString method_object_name;
644                if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
645                {
646                    if (is_instance_method && method_object_name)
647                    {
648                        var_sp = variable_list->FindVariable(method_object_name);
649                        if (var_sp)
650                        {
651                            separator_idx = 0;
652                            var_path.insert(0, "->");
653                            synthetically_added_instance_object = true;
654                        }
655                    }
656                }
657            }
658
659            if (var_sp)
660            {
661                valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
662                if (!valobj_sp)
663                    return valobj_sp;
664
665                // We are dumping at least one child
666                while (separator_idx != std::string::npos)
667                {
668                    // Calculate the next separator index ahead of time
669                    ValueObjectSP child_valobj_sp;
670                    const char separator_type = var_path[0];
671                    switch (separator_type)
672                    {
673
674                    case '-':
675                        if (var_path.size() >= 2 && var_path[1] != '>')
676                            return ValueObjectSP();
677
678                        if (no_fragile_ivar)
679                        {
680                            // Make sure we aren't trying to deref an objective
681                            // C ivar if this is not allowed
682                            const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL);
683                            if ((pointer_type_flags & ClangASTType::eTypeIsObjC) &&
684                                (pointer_type_flags & ClangASTType::eTypeIsPointer))
685                            {
686                                // This was an objective C object pointer and
687                                // it was requested we skip any fragile ivars
688                                // so return nothing here
689                                return ValueObjectSP();
690                            }
691                        }
692                        var_path.erase (0, 1); // Remove the '-'
693                        // Fall through
694                    case '.':
695                        {
696                            const bool expr_is_ptr = var_path[0] == '>';
697
698                            var_path.erase (0, 1); // Remove the '.' or '>'
699                            separator_idx = var_path.find_first_of(".-[");
700                            ConstString child_name;
701                            if (separator_idx == std::string::npos)
702                                child_name.SetCString (var_path.c_str());
703                            else
704                                child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
705
706                            if (check_ptr_vs_member)
707                            {
708                                // We either have a pointer type and need to verify
709                                // valobj_sp is a pointer, or we have a member of a
710                                // class/union/struct being accessed with the . syntax
711                                // and need to verify we don't have a pointer.
712                                const bool actual_is_ptr = valobj_sp->IsPointerType ();
713
714                                if (actual_is_ptr != expr_is_ptr)
715                                {
716                                    // Incorrect use of "." with a pointer, or "->" with
717                                    // a class/union/struct instance or reference.
718                                    valobj_sp->GetExpressionPath (var_expr_path_strm, false);
719                                    if (actual_is_ptr)
720                                        error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
721                                                                        var_expr_path_strm.GetString().c_str(),
722                                                                        child_name.GetCString(),
723                                                                        var_expr_path_strm.GetString().c_str(),
724                                                                        var_path.c_str());
725                                    else
726                                        error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
727                                                                        var_expr_path_strm.GetString().c_str(),
728                                                                        child_name.GetCString(),
729                                                                        var_expr_path_strm.GetString().c_str(),
730                                                                        var_path.c_str());
731                                    return ValueObjectSP();
732                                }
733                            }
734                            child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
735                            if (!child_valobj_sp)
736                            {
737                                if (no_synth_child == false)
738                                {
739                                    child_valobj_sp = valobj_sp->GetSyntheticValue();
740                                    if (child_valobj_sp)
741                                        child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
742                                }
743
744                                if (no_synth_child || !child_valobj_sp)
745                                {
746                                    // No child member with name "child_name"
747                                    if (synthetically_added_instance_object)
748                                    {
749                                        // We added a "this->" or "self->" to the beginning of the expression
750                                        // and this is the first pointer ivar access, so just return the normal
751                                        // error
752                                        error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
753                                                                       name_const_string.GetCString());
754                                    }
755                                    else
756                                    {
757                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
758                                        if (child_name)
759                                        {
760                                            error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
761                                                                            child_name.GetCString(),
762                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
763                                                                            var_expr_path_strm.GetString().c_str());
764                                        }
765                                        else
766                                        {
767                                            error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
768                                                                            var_expr_path_strm.GetString().c_str(),
769                                                                            var_expr_cstr);
770                                        }
771                                    }
772                                    return ValueObjectSP();
773                                }
774                            }
775                            synthetically_added_instance_object = false;
776                            // Remove the child name from the path
777                            var_path.erase(0, child_name.GetLength());
778                            if (use_dynamic != eNoDynamicValues)
779                            {
780                                ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
781                                if (dynamic_value_sp)
782                                    child_valobj_sp = dynamic_value_sp;
783                            }
784                        }
785                        break;
786
787                    case '[':
788                        // Array member access, or treating pointer as an array
789                        if (var_path.size() > 2) // Need at least two brackets and a number
790                        {
791                            char *end = NULL;
792                            long child_index = ::strtol (&var_path[1], &end, 0);
793                            if (end && *end == ']'
794                                && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
795                            {
796                                if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
797                                {
798                                    // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
799                                    // and extract bit low out of it. reading array item low
800                                    // would be done by saying ptr[low], without a deref * sign
801                                    Error error;
802                                    ValueObjectSP temp(valobj_sp->Dereference(error));
803                                    if (error.Fail())
804                                    {
805                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
806                                        error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
807                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
808                                                                        var_expr_path_strm.GetString().c_str());
809                                        return ValueObjectSP();
810                                    }
811                                    valobj_sp = temp;
812                                    deref = false;
813                                }
814                                else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
815                                {
816                                    // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
817                                    // (an operation that is equivalent to deref-ing arr)
818                                    // and extract bit low out of it. reading array item low
819                                    // would be done by saying arr[low], without a deref * sign
820                                    Error error;
821                                    ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
822                                    if (error.Fail())
823                                    {
824                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
825                                        error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
826                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
827                                                                        var_expr_path_strm.GetString().c_str());
828                                        return ValueObjectSP();
829                                    }
830                                    valobj_sp = temp;
831                                    deref = false;
832                                }
833
834                                bool is_incomplete_array = false;
835                                if (valobj_sp->IsPointerType ())
836                                {
837                                    bool is_objc_pointer = true;
838
839                                    if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC)
840                                        is_objc_pointer = false;
841                                    else if (!valobj_sp->GetClangType().IsPointerType())
842                                        is_objc_pointer = false;
843
844                                    if (no_synth_child && is_objc_pointer)
845                                    {
846                                        error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
847                                                                       valobj_sp->GetTypeName().AsCString("<invalid type>"),
848                                                                       var_expr_path_strm.GetString().c_str());
849
850                                        return ValueObjectSP();
851                                    }
852                                    else if (is_objc_pointer)
853                                    {
854                                        // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
855                                        ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
856                                        if (synthetic.get() == NULL /* no synthetic */
857                                            || synthetic == valobj_sp) /* synthetic is the same as the original object */
858                                        {
859                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
860                                            error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
861                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
862                                                                            var_expr_path_strm.GetString().c_str());
863                                        }
864                                        else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
865                                        {
866                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
867                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
868                                                                            child_index,
869                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
870                                                                            var_expr_path_strm.GetString().c_str());
871                                        }
872                                        else
873                                        {
874                                            child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
875                                            if (!child_valobj_sp)
876                                            {
877                                                valobj_sp->GetExpressionPath (var_expr_path_strm, false);
878                                                error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
879                                                                                child_index,
880                                                                                valobj_sp->GetTypeName().AsCString("<invalid type>"),
881                                                                                var_expr_path_strm.GetString().c_str());
882                                            }
883                                        }
884                                    }
885                                    else
886                                    {
887                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
888                                        if (!child_valobj_sp)
889                                        {
890                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
891                                            error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
892                                                                            child_index,
893                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
894                                                                            var_expr_path_strm.GetString().c_str());
895                                        }
896                                    }
897                                }
898                                else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array))
899                                {
900                                    // Pass false to dynamic_value here so we can tell the difference between
901                                    // no dynamic value and no member of this type...
902                                    child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
903                                    if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
904                                        child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
905
906                                    if (!child_valobj_sp)
907                                    {
908                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
909                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
910                                                                        child_index,
911                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
912                                                                        var_expr_path_strm.GetString().c_str());
913                                    }
914                                }
915                                else if (valobj_sp->GetClangType().IsScalarType())
916                                {
917                                    // this is a bitfield asking to display just one bit
918                                    child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
919                                    if (!child_valobj_sp)
920                                    {
921                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
922                                        error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
923                                                                        child_index, child_index,
924                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
925                                                                        var_expr_path_strm.GetString().c_str());
926                                    }
927                                }
928                                else
929                                {
930                                    ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
931                                    if (no_synth_child /* synthetic is forbidden */ ||
932                                        synthetic.get() == NULL /* no synthetic */
933                                        || synthetic == valobj_sp) /* synthetic is the same as the original object */
934                                    {
935                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
936                                        error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
937                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
938                                                                        var_expr_path_strm.GetString().c_str());
939                                    }
940                                    else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
941                                    {
942                                        valobj_sp->GetExpressionPath (var_expr_path_strm, false);
943                                        error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
944                                                                        child_index,
945                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
946                                                                        var_expr_path_strm.GetString().c_str());
947                                    }
948                                    else
949                                    {
950                                        child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
951                                        if (!child_valobj_sp)
952                                        {
953                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
954                                            error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
955                                                                            child_index,
956                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
957                                                                            var_expr_path_strm.GetString().c_str());
958                                        }
959                                    }
960                                }
961
962                                if (!child_valobj_sp)
963                                {
964                                    // Invalid array index...
965                                    return ValueObjectSP();
966                                }
967
968                                // Erase the array member specification '[%i]' where
969                                // %i is the array index
970                                var_path.erase(0, (end - var_path.c_str()) + 1);
971                                separator_idx = var_path.find_first_of(".-[");
972                                if (use_dynamic != eNoDynamicValues)
973                                {
974                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
975                                    if (dynamic_value_sp)
976                                        child_valobj_sp = dynamic_value_sp;
977                                }
978                                // Break out early from the switch since we were
979                                // able to find the child member
980                                break;
981                            }
982                            else if (end && *end == '-')
983                            {
984                                // this is most probably a BitField, let's take a look
985                                char *real_end = NULL;
986                                long final_index = ::strtol (end+1, &real_end, 0);
987                                bool expand_bitfield = true;
988                                if (real_end && *real_end == ']')
989                                {
990                                    // if the format given is [high-low], swap range
991                                    if (child_index > final_index)
992                                    {
993                                        long temp = child_index;
994                                        child_index = final_index;
995                                        final_index = temp;
996                                    }
997
998                                    if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
999                                    {
1000                                        // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
1001                                        // and extract bits low thru high out of it. reading array items low thru high
1002                                        // would be done by saying ptr[low-high], without a deref * sign
1003                                        Error error;
1004                                        ValueObjectSP temp(valobj_sp->Dereference(error));
1005                                        if (error.Fail())
1006                                        {
1007                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1008                                            error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
1009                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1010                                                                            var_expr_path_strm.GetString().c_str());
1011                                            return ValueObjectSP();
1012                                        }
1013                                        valobj_sp = temp;
1014                                        deref = false;
1015                                    }
1016                                    else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
1017                                    {
1018                                        // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
1019                                        // (an operation that is equivalent to deref-ing arr)
1020                                        // and extract bits low thru high out of it. reading array items low thru high
1021                                        // would be done by saying arr[low-high], without a deref * sign
1022                                        Error error;
1023                                        ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
1024                                        if (error.Fail())
1025                                        {
1026                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1027                                            error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
1028                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1029                                                                            var_expr_path_strm.GetString().c_str());
1030                                            return ValueObjectSP();
1031                                        }
1032                                        valobj_sp = temp;
1033                                        deref = false;
1034                                    }
1035                                    /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
1036                                    {
1037                                        child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
1038                                        expand_bitfield = false;
1039                                        if (!child_valobj_sp)
1040                                        {
1041                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1042                                            error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
1043                                                                            child_index, final_index,
1044                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1045                                                                            var_expr_path_strm.GetString().c_str());
1046                                        }
1047                                    }*/
1048
1049                                    if (expand_bitfield)
1050                                    {
1051                                        child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1052                                        if (!child_valobj_sp)
1053                                        {
1054                                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1055                                            error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
1056                                                                            child_index, final_index,
1057                                                                            valobj_sp->GetTypeName().AsCString("<invalid type>"),
1058                                                                            var_expr_path_strm.GetString().c_str());
1059                                        }
1060                                    }
1061                                }
1062
1063                                if (!child_valobj_sp)
1064                                {
1065                                    // Invalid bitfield range...
1066                                    return ValueObjectSP();
1067                                }
1068
1069                                // Erase the bitfield member specification '[%i-%i]' where
1070                                // %i is the index
1071                                var_path.erase(0, (real_end - var_path.c_str()) + 1);
1072                                separator_idx = var_path.find_first_of(".-[");
1073                                if (use_dynamic != eNoDynamicValues)
1074                                {
1075                                    ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
1076                                    if (dynamic_value_sp)
1077                                        child_valobj_sp = dynamic_value_sp;
1078                                }
1079                                // Break out early from the switch since we were
1080                                // able to find the child member
1081                                break;
1082
1083                            }
1084                        }
1085                        else
1086                        {
1087                            error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
1088                                                           var_expr_path_strm.GetString().c_str(),
1089                                                           var_path.c_str());
1090                        }
1091                        return ValueObjectSP();
1092
1093                    default:
1094                        // Failure...
1095                        {
1096                            valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1097                            error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
1098                                                            separator_type,
1099                                                            var_expr_path_strm.GetString().c_str(),
1100                                                            var_path.c_str());
1101
1102                            return ValueObjectSP();
1103                        }
1104                    }
1105
1106                    if (child_valobj_sp)
1107                        valobj_sp = child_valobj_sp;
1108
1109                    if (var_path.empty())
1110                        break;
1111
1112                }
1113                if (valobj_sp)
1114                {
1115                    if (deref)
1116                    {
1117                        ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
1118                        valobj_sp = deref_valobj_sp;
1119                    }
1120                    else if (address_of)
1121                    {
1122                        ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
1123                        valobj_sp = address_of_valobj_sp;
1124                    }
1125                }
1126                return valobj_sp;
1127            }
1128            else
1129            {
1130                error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
1131                                               name_const_string.GetCString());
1132            }
1133        }
1134    }
1135    else
1136    {
1137        error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
1138    }
1139    return ValueObjectSP();
1140}
1141
1142bool
1143StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
1144{
1145    if (m_cfa_is_valid == false)
1146    {
1147        m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
1148        return false;
1149    }
1150
1151    if (m_flags.IsClear(GOT_FRAME_BASE))
1152    {
1153        if (m_sc.function)
1154        {
1155            m_frame_base.Clear();
1156            m_frame_base_error.Clear();
1157
1158            m_flags.Set(GOT_FRAME_BASE);
1159            ExecutionContext exe_ctx (shared_from_this());
1160            Value expr_value;
1161            addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1162            if (m_sc.function->GetFrameBaseExpression().IsLocationList())
1163                loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
1164
1165            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
1166            {
1167                // We should really have an error if evaluate returns, but in case
1168                // we don't, lets set the error to something at least.
1169                if (m_frame_base_error.Success())
1170                    m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
1171            }
1172            else
1173            {
1174                m_frame_base = expr_value.ResolveValue(&exe_ctx);
1175            }
1176        }
1177        else
1178        {
1179            m_frame_base_error.SetErrorString ("No function in symbol context.");
1180        }
1181    }
1182
1183    if (m_frame_base_error.Success())
1184        frame_base = m_frame_base;
1185
1186    if (error_ptr)
1187        *error_ptr = m_frame_base_error;
1188    return m_frame_base_error.Success();
1189}
1190
1191RegisterContextSP
1192StackFrame::GetRegisterContext ()
1193{
1194    if (!m_reg_context_sp)
1195    {
1196        ThreadSP thread_sp (GetThread());
1197        if (thread_sp)
1198            m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
1199    }
1200    return m_reg_context_sp;
1201}
1202
1203bool
1204StackFrame::HasDebugInformation ()
1205{
1206    GetSymbolContext (eSymbolContextLineEntry);
1207    return m_sc.line_entry.IsValid();
1208}
1209
1210
1211ValueObjectSP
1212StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1213{
1214    ValueObjectSP valobj_sp;
1215    if (m_is_history_frame)
1216    {
1217        return valobj_sp;
1218    }
1219    VariableList *var_list = GetVariableList (true);
1220    if (var_list)
1221    {
1222        // Make sure the variable is a frame variable
1223        const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
1224        const uint32_t num_variables = var_list->GetSize();
1225        if (var_idx < num_variables)
1226        {
1227            valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
1228            if (valobj_sp.get() == NULL)
1229            {
1230                if (m_variable_list_value_objects.GetSize() < num_variables)
1231                    m_variable_list_value_objects.Resize(num_variables);
1232                valobj_sp = ValueObjectVariable::Create (this, variable_sp);
1233                m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
1234            }
1235        }
1236    }
1237    if (use_dynamic != eNoDynamicValues && valobj_sp)
1238    {
1239        ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
1240        if (dynamic_sp)
1241            return dynamic_sp;
1242    }
1243    return valobj_sp;
1244}
1245
1246ValueObjectSP
1247StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1248{
1249    if (m_is_history_frame)
1250        return ValueObjectSP();
1251
1252    // Check to make sure we aren't already tracking this variable?
1253    ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
1254    if (!valobj_sp)
1255    {
1256        // We aren't already tracking this global
1257        VariableList *var_list = GetVariableList (true);
1258        // If this frame has no variables, create a new list
1259        if (var_list == NULL)
1260            m_variable_list_sp.reset (new VariableList());
1261
1262        // Add the global/static variable to this frame
1263        m_variable_list_sp->AddVariable (variable_sp);
1264
1265        // Now make a value object for it so we can track its changes
1266        valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
1267    }
1268    return valobj_sp;
1269}
1270
1271bool
1272StackFrame::IsInlined ()
1273{
1274    if (m_sc.block == NULL)
1275        GetSymbolContext (eSymbolContextBlock);
1276    if (m_sc.block)
1277        return m_sc.block->GetContainingInlinedBlock() != NULL;
1278    return false;
1279}
1280
1281TargetSP
1282StackFrame::CalculateTarget ()
1283{
1284    TargetSP target_sp;
1285    ThreadSP thread_sp(GetThread());
1286    if (thread_sp)
1287    {
1288        ProcessSP process_sp (thread_sp->CalculateProcess());
1289        if (process_sp)
1290            target_sp = process_sp->CalculateTarget();
1291    }
1292    return target_sp;
1293}
1294
1295ProcessSP
1296StackFrame::CalculateProcess ()
1297{
1298    ProcessSP process_sp;
1299    ThreadSP thread_sp(GetThread());
1300    if (thread_sp)
1301        process_sp = thread_sp->CalculateProcess();
1302    return process_sp;
1303}
1304
1305ThreadSP
1306StackFrame::CalculateThread ()
1307{
1308    return GetThread();
1309}
1310
1311StackFrameSP
1312StackFrame::CalculateStackFrame ()
1313{
1314    return shared_from_this();
1315}
1316
1317
1318void
1319StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
1320{
1321    exe_ctx.SetContext (shared_from_this());
1322}
1323
1324void
1325StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
1326{
1327    if (strm == NULL)
1328        return;
1329
1330    GetSymbolContext(eSymbolContextEverything);
1331    ExecutionContext exe_ctx (shared_from_this());
1332    StreamString s;
1333
1334    if (frame_marker)
1335        s.PutCString(frame_marker);
1336
1337    const char *frame_format = NULL;
1338    Target *target = exe_ctx.GetTargetPtr();
1339    if (target)
1340        frame_format = target->GetDebugger().GetFrameFormat();
1341    if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
1342    {
1343        strm->Write(s.GetData(), s.GetSize());
1344    }
1345    else
1346    {
1347        Dump (strm, true, false);
1348        strm->EOL();
1349    }
1350}
1351
1352void
1353StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
1354{
1355    if (strm == NULL)
1356        return;
1357
1358    if (show_frame_index)
1359        strm->Printf("frame #%u: ", m_frame_index);
1360    ExecutionContext exe_ctx (shared_from_this());
1361    Target *target = exe_ctx.GetTargetPtr();
1362    strm->Printf("0x%0*" PRIx64 " ",
1363                 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
1364                 GetFrameCodeAddress().GetLoadAddress(target));
1365    GetSymbolContext(eSymbolContextEverything);
1366    const bool show_module = true;
1367    const bool show_inline = true;
1368    m_sc.DumpStopContext (strm,
1369                          exe_ctx.GetBestExecutionContextScope(),
1370                          GetFrameCodeAddress(),
1371                          show_fullpaths,
1372                          show_module,
1373                          show_inline);
1374}
1375
1376void
1377StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
1378{
1379    assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
1380    m_variable_list_sp = prev_frame.m_variable_list_sp;
1381    m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
1382    if (!m_disassembly.GetString().empty())
1383        m_disassembly.GetString().swap (m_disassembly.GetString());
1384}
1385
1386
1387void
1388StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
1389{
1390    assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
1391    m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
1392    assert (GetThread() == curr_frame.GetThread());
1393    m_frame_index = curr_frame.m_frame_index;
1394    m_concrete_frame_index = curr_frame.m_concrete_frame_index;
1395    m_reg_context_sp = curr_frame.m_reg_context_sp;
1396    m_frame_code_addr = curr_frame.m_frame_code_addr;
1397    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());
1398    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());
1399    assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1400    assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
1401    m_sc = curr_frame.m_sc;
1402    m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1403    m_flags.Set (m_sc.GetResolvedMask());
1404    m_frame_base.Clear();
1405    m_frame_base_error.Clear();
1406}
1407
1408
1409bool
1410StackFrame::HasCachedData () const
1411{
1412    if (m_variable_list_sp.get())
1413        return true;
1414    if (m_variable_list_value_objects.GetSize() > 0)
1415        return true;
1416    if (!m_disassembly.GetString().empty())
1417        return true;
1418    return false;
1419}
1420
1421bool
1422StackFrame::GetStatus (Stream& strm,
1423                       bool show_frame_info,
1424                       bool show_source,
1425                       const char *frame_marker)
1426{
1427
1428    if (show_frame_info)
1429    {
1430        strm.Indent();
1431        DumpUsingSettingsFormat (&strm, frame_marker);
1432    }
1433
1434    if (show_source)
1435    {
1436        ExecutionContext exe_ctx (shared_from_this());
1437        bool have_source = false;
1438        Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
1439        Target *target = exe_ctx.GetTargetPtr();
1440        if (target)
1441        {
1442            Debugger &debugger = target->GetDebugger();
1443            const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
1444            const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
1445            disasm_display = debugger.GetStopDisassemblyDisplay ();
1446
1447            if (source_lines_before > 0 || source_lines_after > 0)
1448            {
1449                GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1450
1451                if (m_sc.comp_unit && m_sc.line_entry.IsValid())
1452                {
1453                    have_source = true;
1454                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
1455                                                                                      m_sc.line_entry.line,
1456                                                                                      source_lines_before,
1457                                                                                      source_lines_after,
1458                                                                                      "->",
1459                                                                                      &strm);
1460                }
1461            }
1462            switch (disasm_display)
1463            {
1464            case Debugger::eStopDisassemblyTypeNever:
1465                break;
1466
1467            case Debugger::eStopDisassemblyTypeNoSource:
1468                if (have_source)
1469                    break;
1470                // Fall through to next case
1471            case Debugger::eStopDisassemblyTypeAlways:
1472                if (target)
1473                {
1474                    const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
1475                    if (disasm_lines > 0)
1476                    {
1477                        const ArchSpec &target_arch = target->GetArchitecture();
1478                        AddressRange pc_range;
1479                        pc_range.GetBaseAddress() = GetFrameCodeAddress();
1480                        pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
1481                        const char *plugin_name = NULL;
1482                        const char *flavor = NULL;
1483                        Disassembler::Disassemble (target->GetDebugger(),
1484                                                   target_arch,
1485                                                   plugin_name,
1486                                                   flavor,
1487                                                   exe_ctx,
1488                                                   pc_range,
1489                                                   disasm_lines,
1490                                                   0,
1491                                                   Disassembler::eOptionMarkPCAddress,
1492                                                   strm);
1493                    }
1494                }
1495                break;
1496            }
1497        }
1498    }
1499    return true;
1500}
1501
1502