1 //===-- SBFrame.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/API/SBFrame.h"
11 
12 #include <string>
13 #include <algorithm>
14 
15 #include "lldb/lldb-types.h"
16 
17 #include "lldb/Core/Address.h"
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/StreamFile.h"
22 #include "lldb/Core/ValueObjectRegister.h"
23 #include "lldb/Core/ValueObjectVariable.h"
24 #include "lldb/Expression/ClangUserExpression.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Symbol/Block.h"
27 #include "lldb/Symbol/SymbolContext.h"
28 #include "lldb/Symbol/VariableList.h"
29 #include "lldb/Symbol/Variable.h"
30 #include "lldb/Target/ExecutionContext.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/StackFrame.h"
35 #include "lldb/Target/Thread.h"
36 
37 #include "lldb/API/SBDebugger.h"
38 #include "lldb/API/SBValue.h"
39 #include "lldb/API/SBAddress.h"
40 #include "lldb/API/SBStream.h"
41 #include "lldb/API/SBSymbolContext.h"
42 #include "lldb/API/SBThread.h"
43 
44 using namespace lldb;
45 using namespace lldb_private;
46 
47 SBFrame::SBFrame () :
48     m_opaque_sp ()
49 {
50 }
51 
52 SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) :
53     m_opaque_sp (lldb_object_sp)
54 {
55     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
56 
57     if (log)
58     {
59         SBStream sstr;
60         GetDescription (sstr);
61         log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s",
62                      lldb_object_sp.get(), m_opaque_sp.get(), sstr.GetData());
63 
64     }
65 }
66 
67 SBFrame::SBFrame(const SBFrame &rhs) :
68     m_opaque_sp (rhs.m_opaque_sp)
69 {
70 }
71 
72 const SBFrame &
73 SBFrame::operator = (const SBFrame &rhs)
74 {
75     if (this != &rhs)
76         m_opaque_sp = rhs.m_opaque_sp;
77     return *this;
78 }
79 
80 SBFrame::~SBFrame()
81 {
82 }
83 
84 
85 void
86 SBFrame::SetFrame (const StackFrameSP &lldb_object_sp)
87 {
88     void *old_ptr = m_opaque_sp.get();
89     m_opaque_sp = lldb_object_sp;
90     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
91 
92     if (log)
93     {
94         log->Printf ("SBFrame(%p)::SetFrame(sp=%p) := SBFrame(%p)",
95                      old_ptr, lldb_object_sp.get(), m_opaque_sp.get());
96     }
97 
98 }
99 
100 
101 bool
102 SBFrame::IsValid() const
103 {
104     return (m_opaque_sp.get() != NULL);
105 }
106 
107 SBSymbolContext
108 SBFrame::GetSymbolContext (uint32_t resolve_scope) const
109 {
110 
111     SBSymbolContext sb_sym_ctx;
112     if (m_opaque_sp)
113     {
114         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
115         sb_sym_ctx.SetSymbolContext(&m_opaque_sp->GetSymbolContext (resolve_scope));
116     }
117 
118     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
119     if (log)
120         log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)",
121                      m_opaque_sp.get(), resolve_scope, sb_sym_ctx.get());
122 
123     return sb_sym_ctx;
124 }
125 
126 SBModule
127 SBFrame::GetModule () const
128 {
129     SBModule sb_module;
130     if (m_opaque_sp)
131     {
132         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
133         *sb_module = m_opaque_sp->GetSymbolContext (eSymbolContextModule).module_sp;
134     }
135 
136     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
137     if (log)
138         log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)",
139                      m_opaque_sp.get(), sb_module.get());
140 
141     return sb_module;
142 }
143 
144 SBCompileUnit
145 SBFrame::GetCompileUnit () const
146 {
147     SBCompileUnit sb_comp_unit;
148     if (m_opaque_sp)
149     {
150         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
151         sb_comp_unit.reset (m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
152     }
153     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
154     if (log)
155         log->Printf ("SBFrame(%p)::GetModule () => SBCompileUnit(%p)",
156                      m_opaque_sp.get(), sb_comp_unit.get());
157 
158     return sb_comp_unit;
159 }
160 
161 SBFunction
162 SBFrame::GetFunction () const
163 {
164     SBFunction sb_function;
165     if (m_opaque_sp)
166     {
167         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
168         sb_function.reset(m_opaque_sp->GetSymbolContext (eSymbolContextFunction).function);
169     }
170     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
171     if (log)
172         log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)",
173                      m_opaque_sp.get(), sb_function.get());
174 
175     return sb_function;
176 }
177 
178 SBSymbol
179 SBFrame::GetSymbol () const
180 {
181     SBSymbol sb_symbol;
182     if (m_opaque_sp)
183     {
184         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
185         sb_symbol.reset(m_opaque_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
186     }
187     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
188     if (log)
189         log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)",
190                      m_opaque_sp.get(), sb_symbol.get());
191     return sb_symbol;
192 }
193 
194 SBBlock
195 SBFrame::GetBlock () const
196 {
197     SBBlock sb_block;
198     if (m_opaque_sp)
199     {
200         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
201         sb_block.reset (m_opaque_sp->GetSymbolContext (eSymbolContextBlock).block);
202     }
203     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
204     if (log)
205         log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)",
206                      m_opaque_sp.get(), sb_block.get());
207     return sb_block;
208 }
209 
210 SBBlock
211 SBFrame::GetFrameBlock () const
212 {
213     SBBlock sb_block;
214     if (m_opaque_sp)
215     {
216         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
217         sb_block.reset(m_opaque_sp->GetFrameBlock ());
218     }
219     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
220     if (log)
221         log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)",
222                      m_opaque_sp.get(), sb_block.get());
223     return sb_block;
224 }
225 
226 SBLineEntry
227 SBFrame::GetLineEntry () const
228 {
229     SBLineEntry sb_line_entry;
230     if (m_opaque_sp)
231     {
232         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
233         sb_line_entry.SetLineEntry (m_opaque_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry);
234     }
235     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
236     if (log)
237         log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)",
238                      m_opaque_sp.get(), sb_line_entry.get());
239     return sb_line_entry;
240 }
241 
242 uint32_t
243 SBFrame::GetFrameID () const
244 {
245     uint32_t frame_idx = m_opaque_sp ? m_opaque_sp->GetFrameIndex () : UINT32_MAX;
246 
247     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
248     if (log)
249         log->Printf ("SBFrame(%p)::GetFrameID () => %u",
250                      m_opaque_sp.get(), frame_idx);
251     return frame_idx;
252 }
253 
254 addr_t
255 SBFrame::GetPC () const
256 {
257     addr_t addr = LLDB_INVALID_ADDRESS;
258     if (m_opaque_sp)
259     {
260         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
261         addr = m_opaque_sp->GetFrameCodeAddress().GetOpcodeLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget());
262     }
263 
264     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
265     if (log)
266         log->Printf ("SBFrame(%p)::GetPC () => 0x%llx", m_opaque_sp.get(), addr);
267 
268     return addr;
269 }
270 
271 bool
272 SBFrame::SetPC (addr_t new_pc)
273 {
274     bool ret_val = false;
275     if (m_opaque_sp)
276     {
277         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
278         ret_val = m_opaque_sp->GetRegisterContext()->SetPC (new_pc);
279     }
280 
281     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
282     if (log)
283         log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%llx) => %i",
284                      m_opaque_sp.get(), new_pc, ret_val);
285 
286     return ret_val;
287 }
288 
289 addr_t
290 SBFrame::GetSP () const
291 {
292     addr_t addr = LLDB_INVALID_ADDRESS;
293     if (m_opaque_sp)
294     {
295         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
296         addr = m_opaque_sp->GetRegisterContext()->GetSP();
297     }
298     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
299     if (log)
300         log->Printf ("SBFrame(%p)::GetSP () => 0x%llx", m_opaque_sp.get(), addr);
301 
302     return addr;
303 }
304 
305 
306 addr_t
307 SBFrame::GetFP () const
308 {
309     addr_t addr = LLDB_INVALID_ADDRESS;
310     if (m_opaque_sp)
311     {
312         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
313         addr = m_opaque_sp->GetRegisterContext()->GetFP();
314     }
315 
316     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
317     if (log)
318         log->Printf ("SBFrame(%p)::GetFP () => 0x%llx", m_opaque_sp.get(), addr);
319     return addr;
320 }
321 
322 
323 SBAddress
324 SBFrame::GetPCAddress () const
325 {
326     SBAddress sb_addr;
327     if (m_opaque_sp)
328     {
329         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
330         sb_addr.SetAddress (&m_opaque_sp->GetFrameCodeAddress());
331     }
332     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
333     if (log)
334         log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", m_opaque_sp.get(), sb_addr.get());
335     return sb_addr;
336 }
337 
338 void
339 SBFrame::Clear()
340 {
341     m_opaque_sp.reset();
342 }
343 
344 SBValue
345 SBFrame::FindVariable (const char *name)
346 {
347     SBValue value;
348     if (m_opaque_sp)
349     {
350         lldb::DynamicValueType  use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue();
351         value = FindVariable (name, use_dynamic);
352     }
353     return value;
354 }
355 
356 SBValue
357 SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
358 {
359     VariableSP var_sp;
360     SBValue sb_value;
361 
362     if (m_opaque_sp && name && name[0])
363     {
364         VariableList variable_list;
365         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
366         SymbolContext sc (m_opaque_sp->GetSymbolContext (eSymbolContextBlock));
367 
368         if (sc.block)
369         {
370             const bool can_create = true;
371             const bool get_parent_variables = true;
372             const bool stop_if_block_is_inlined_function = true;
373 
374             if (sc.block->AppendVariables (can_create,
375                                            get_parent_variables,
376                                            stop_if_block_is_inlined_function,
377                                            &variable_list))
378             {
379                 var_sp = variable_list.FindVariable (ConstString(name));
380             }
381         }
382 
383         if (var_sp)
384             *sb_value = ValueObjectSP (m_opaque_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic));
385 
386     }
387 
388     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
389     if (log)
390         log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)",
391                      m_opaque_sp.get(), name, sb_value.get());
392 
393     return sb_value;
394 }
395 
396 SBValue
397 SBFrame::FindValue (const char *name, ValueType value_type)
398 {
399     SBValue value;
400     if (m_opaque_sp)
401     {
402         lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue();
403         value = FindValue (name, value_type, use_dynamic);
404     }
405     return value;
406 }
407 
408 SBValue
409 SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic)
410 {
411     SBValue sb_value;
412     if (m_opaque_sp && name && name[0])
413     {
414         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
415 
416         switch (value_type)
417         {
418         case eValueTypeVariableGlobal:      // global variable
419         case eValueTypeVariableStatic:      // static variable
420         case eValueTypeVariableArgument:    // function argument variables
421         case eValueTypeVariableLocal:       // function local variables
422             {
423                 VariableList *variable_list = m_opaque_sp->GetVariableList(true);
424 
425                 SymbolContext sc (m_opaque_sp->GetSymbolContext (eSymbolContextBlock));
426 
427                 const bool can_create = true;
428                 const bool get_parent_variables = true;
429                 const bool stop_if_block_is_inlined_function = true;
430 
431                 if (sc.block && sc.block->AppendVariables (can_create,
432                                                            get_parent_variables,
433                                                            stop_if_block_is_inlined_function,
434                                                            variable_list))
435                 {
436                     ConstString const_name(name);
437                     const uint32_t num_variables = variable_list->GetSize();
438                     for (uint32_t i = 0; i < num_variables; ++i)
439                     {
440                         VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
441                         if (variable_sp &&
442                             variable_sp->GetScope() == value_type &&
443                             variable_sp->GetName() == const_name)
444                         {
445                             *sb_value = ValueObjectSP (m_opaque_sp->GetValueObjectForFrameVariable(variable_sp,
446                                                                                                    use_dynamic));
447                             break;
448                         }
449                     }
450                 }
451             }
452             break;
453 
454         case eValueTypeRegister:            // stack frame register value
455             {
456                 RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext());
457                 if (reg_ctx)
458                 {
459                     const uint32_t num_regs = reg_ctx->GetRegisterCount();
460                     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
461                     {
462                         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
463                         if (reg_info &&
464                             ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
465                              (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
466                         {
467                             *sb_value = ValueObjectRegister::Create (m_opaque_sp.get(), reg_ctx, reg_idx);
468                         }
469                     }
470                 }
471             }
472             break;
473 
474         case eValueTypeRegisterSet:         // A collection of stack frame register values
475             {
476                 RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext());
477                 if (reg_ctx)
478                 {
479                     const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
480                     for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
481                     {
482                         const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
483                         if (reg_set &&
484                             ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
485                              (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
486                         {
487                             *sb_value = ValueObjectRegisterSet::Create (m_opaque_sp.get(), reg_ctx, set_idx);
488                         }
489                     }
490                 }
491             }
492             break;
493 
494         case eValueTypeConstResult:         // constant result variables
495             {
496                 ConstString const_name(name);
497                 ClangExpressionVariableSP expr_var_sp (m_opaque_sp->GetThread().GetProcess().GetTarget().GetPersistentVariables().GetVariable (const_name));
498                 if (expr_var_sp)
499                     *sb_value = expr_var_sp->GetValueObject();
500             }
501             break;
502 
503         default:
504             break;
505         }
506     }
507 
508     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
509     if (log)
510         log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)",
511                      m_opaque_sp.get(), name, value_type, sb_value.get());
512 
513 
514     return sb_value;
515 }
516 
517 bool
518 SBFrame::operator == (const SBFrame &rhs) const
519 {
520     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
521 }
522 
523 bool
524 SBFrame::operator != (const SBFrame &rhs) const
525 {
526     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
527 }
528 
529 lldb_private::StackFrame *
530 SBFrame::operator->() const
531 {
532     return m_opaque_sp.get();
533 }
534 
535 lldb_private::StackFrame *
536 SBFrame::get() const
537 {
538     return m_opaque_sp.get();
539 }
540 
541 lldb::StackFrameSP &
542 SBFrame::get_sp()
543 {
544     return m_opaque_sp;
545 }
546 
547 SBThread
548 SBFrame::GetThread () const
549 {
550     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
551 
552     SBThread sb_thread;
553     if (m_opaque_sp)
554     {
555         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
556         sb_thread.SetThread (m_opaque_sp->GetThread().GetSP());
557     }
558 
559     if (log)
560     {
561         SBStream sstr;
562         sb_thread.GetDescription (sstr);
563         log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", m_opaque_sp.get(),
564                      sb_thread.get(), sstr.GetData());
565     }
566 
567     return sb_thread;
568 }
569 
570 const char *
571 SBFrame::Disassemble () const
572 {
573     const char *disassembly = NULL;
574     if (m_opaque_sp)
575     {
576         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
577         disassembly = m_opaque_sp->Disassemble();
578     }
579     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
580 
581     if (log)
582         log->Printf ("SBFrame(%p)::Disassemble () => %s", m_opaque_sp.get(), disassembly);
583 
584     return disassembly;
585 }
586 
587 
588 SBValueList
589 SBFrame::GetVariables (bool arguments,
590                        bool locals,
591                        bool statics,
592                        bool in_scope_only)
593 {
594     SBValueList value_list;
595     if (m_opaque_sp)
596     {
597         lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue();
598         value_list = GetVariables (arguments, locals, statics, in_scope_only, use_dynamic);
599     }
600     return value_list;
601 }
602 
603 SBValueList
604 SBFrame::GetVariables (bool arguments,
605                        bool locals,
606                        bool statics,
607                        bool in_scope_only,
608                        lldb::DynamicValueType  use_dynamic)
609 {
610     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
611 
612     if (log)
613         log->Printf ("SBFrame(%p)::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)",
614                      m_opaque_sp.get(),
615                      arguments,
616                      locals,
617                      statics,
618                      in_scope_only);
619 
620     SBValueList value_list;
621     if (m_opaque_sp)
622     {
623 
624         size_t i;
625         VariableList *variable_list = NULL;
626         // Scope for locker
627         {
628             Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
629             variable_list = m_opaque_sp->GetVariableList(true);
630         }
631         if (variable_list)
632         {
633             const size_t num_variables = variable_list->GetSize();
634             if (num_variables)
635             {
636                 for (i = 0; i < num_variables; ++i)
637                 {
638                     VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
639                     if (variable_sp)
640                     {
641                         bool add_variable = false;
642                         switch (variable_sp->GetScope())
643                         {
644                         case eValueTypeVariableGlobal:
645                         case eValueTypeVariableStatic:
646                             add_variable = statics;
647                             break;
648 
649                         case eValueTypeVariableArgument:
650                             add_variable = arguments;
651                             break;
652 
653                         case eValueTypeVariableLocal:
654                             add_variable = locals;
655                             break;
656 
657                         default:
658                             break;
659                         }
660                         if (add_variable)
661                         {
662                             if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get()))
663                                 continue;
664 
665                             value_list.Append(m_opaque_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic));
666                         }
667                     }
668                 }
669             }
670         }
671     }
672 
673     if (log)
674     {
675         log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", m_opaque_sp.get(),
676                      value_list.get());
677     }
678 
679     return value_list;
680 }
681 
682 SBValueList
683 SBFrame::GetRegisters ()
684 {
685     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
686 
687     SBValueList value_list;
688     if (m_opaque_sp)
689     {
690         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
691         RegisterContextSP reg_ctx (m_opaque_sp->GetRegisterContext());
692         if (reg_ctx)
693         {
694             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
695             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
696             {
697                 value_list.Append(ValueObjectRegisterSet::Create (m_opaque_sp.get(), reg_ctx, set_idx));
698             }
699         }
700     }
701 
702     if (log)
703         log->Printf ("SBFrame(%p)::Registers () => SBValueList(%p)", m_opaque_sp.get(), value_list.get());
704 
705     return value_list;
706 }
707 
708 bool
709 SBFrame::GetDescription (SBStream &description)
710 {
711     Stream &strm = description.ref();
712 
713     if (m_opaque_sp)
714     {
715         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
716         m_opaque_sp->DumpUsingSettingsFormat (&strm);
717     }
718     else
719         strm.PutCString ("No value");
720 
721     return true;
722 }
723 
724 SBValue
725 SBFrame::EvaluateExpression (const char *expr)
726 {
727     SBValue result;
728     if (m_opaque_sp)
729     {
730         lldb::DynamicValueType use_dynamic = m_opaque_sp->CalculateTarget()->GetPreferDynamicValue();
731         result = EvaluateExpression (expr, use_dynamic);
732     }
733     return result;
734 }
735 
736 SBValue
737 SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value)
738 {
739     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
740 
741     LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
742 
743     ExecutionResults exe_results;
744     SBValue expr_result;
745     if (log)
746         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", m_opaque_sp.get(), expr);
747 
748     if (m_opaque_sp)
749     {
750         Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
751 
752 
753         StreamString frame_description;
754         m_opaque_sp->DumpUsingSettingsFormat (&frame_description);
755 
756         Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
757                                              expr, fetch_dynamic_value, frame_description.GetString().c_str());
758 
759         const bool unwind_on_error = true;
760         const bool keep_in_memory = false;
761 
762         exe_results = m_opaque_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr,
763                                                                                            m_opaque_sp.get(),
764                                                                                            eExecutionPolicyOnlyWhenNeeded,
765                                                                                            unwind_on_error,
766                                                                                            keep_in_memory,
767                                                                                            fetch_dynamic_value,
768                                                                                            *expr_result);
769 
770         Host::SetCrashDescription (NULL);
771     }
772 
773     if (expr_log)
774         expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **",
775                          expr_result.GetValue(),
776                          expr_result.GetSummary());
777 
778     if (log)
779         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", m_opaque_sp.get(),
780                      expr,
781                      expr_result.get(),
782                      exe_results);
783 
784     return expr_result;
785 }
786 
787 bool
788 SBFrame::IsInlined()
789 {
790     if (m_opaque_sp)
791     {
792         Block *block = m_opaque_sp->GetSymbolContext(eSymbolContextBlock).block;
793         if (block)
794             return block->GetContainingInlinedBlock () != NULL;
795     }
796     return false;
797 }
798 
799 const char *
800 SBFrame::GetFunctionName()
801 {
802     const char *name = NULL;
803     if (m_opaque_sp)
804     {
805         SymbolContext sc (m_opaque_sp->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol));
806         if (sc.block)
807         {
808             Block *inlined_block = sc.block->GetContainingInlinedBlock ();
809             if (inlined_block)
810             {
811                 const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo();
812                 name = inlined_info->GetName().AsCString();
813             }
814         }
815 
816         if (name == NULL)
817         {
818             if (sc.function)
819                 name = sc.function->GetName().GetCString();
820         }
821 
822         if (name == NULL)
823         {
824             if (sc.symbol)
825                 name = sc.symbol->GetName().GetCString();
826         }
827     }
828     return name;
829 }
830 
831