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