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