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