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