blob: 5d9bd6e016f9eb227b89b8ec0edbdf8b26cd02e7 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
Eli Friedman7a62c8b2010-06-09 07:44:37 +000010#include "lldb/API/SBFrame.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
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/Stream.h"
20#include "lldb/Core/StreamFile.h"
21#include "lldb/Core/ValueObjectRegister.h"
22#include "lldb/Core/ValueObjectVariable.h"
23#include "lldb/Symbol/Block.h"
24#include "lldb/Symbol/SymbolContext.h"
25#include "lldb/Symbol/VariableList.h"
26#include "lldb/Symbol/Variable.h"
27#include "lldb/Target/ExecutionContext.h"
28#include "lldb/Target/Target.h"
29#include "lldb/Target/Process.h"
30#include "lldb/Target/RegisterContext.h"
31#include "lldb/Target/StackFrame.h"
32#include "lldb/Target/Thread.h"
33
Eli Friedman7a62c8b2010-06-09 07:44:37 +000034#include "lldb/API/SBDebugger.h"
35#include "lldb/API/SBValue.h"
36#include "lldb/API/SBAddress.h"
37#include "lldb/API/SBSymbolContext.h"
38#include "lldb/API/SBThread.h"
Chris Lattner24943d22010-06-08 16:52:24 +000039
40using namespace lldb;
41using namespace lldb_private;
42
43SBFrame::SBFrame () :
Greg Clayton63094e02010-06-23 01:19:29 +000044 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000045{
46}
47
48SBFrame::SBFrame (const lldb::StackFrameSP &lldb_object_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000049 m_opaque_sp (lldb_object_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
51}
52
53SBFrame::~SBFrame()
54{
55}
56
57
58void
59SBFrame::SetFrame (const lldb::StackFrameSP &lldb_object_sp)
60{
Greg Clayton63094e02010-06-23 01:19:29 +000061 m_opaque_sp = lldb_object_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000062}
63
64
65bool
66SBFrame::IsValid() const
67{
Greg Clayton63094e02010-06-23 01:19:29 +000068 return (m_opaque_sp.get() != NULL);
Chris Lattner24943d22010-06-08 16:52:24 +000069}
70
71SBSymbolContext
72SBFrame::GetSymbolContext (uint32_t resolve_scope) const
73{
74 SBSymbolContext sb_sym_ctx;
Greg Clayton63094e02010-06-23 01:19:29 +000075 if (m_opaque_sp)
76 sb_sym_ctx.SetSymbolContext(&m_opaque_sp->GetSymbolContext (resolve_scope));
Chris Lattner24943d22010-06-08 16:52:24 +000077 return sb_sym_ctx;
78}
79
80SBModule
81SBFrame::GetModule () const
82{
Greg Clayton63094e02010-06-23 01:19:29 +000083 SBModule sb_module (m_opaque_sp->GetSymbolContext (eSymbolContextModule).module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +000084 return sb_module;
85}
86
87SBCompileUnit
88SBFrame::GetCompileUnit () const
89{
Greg Clayton63094e02010-06-23 01:19:29 +000090 SBCompileUnit sb_comp_unit(m_opaque_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
Chris Lattner24943d22010-06-08 16:52:24 +000091 return sb_comp_unit;
92}
93
94SBFunction
95SBFrame::GetFunction () const
96{
Greg Clayton63094e02010-06-23 01:19:29 +000097 SBFunction sb_function(m_opaque_sp->GetSymbolContext (eSymbolContextFunction).function);
Chris Lattner24943d22010-06-08 16:52:24 +000098 return sb_function;
99}
100
101SBBlock
102SBFrame::GetBlock () const
103{
Greg Clayton63094e02010-06-23 01:19:29 +0000104 SBBlock sb_block(m_opaque_sp->GetSymbolContext (eSymbolContextBlock).block);
Chris Lattner24943d22010-06-08 16:52:24 +0000105 return sb_block;
106}
107
Greg Clayton69aa5d92010-09-07 04:20:48 +0000108SBBlock
109SBFrame::GetFrameBlock () const
110{
111 SBBlock sb_block(m_opaque_sp->GetFrameBlock ());
112 return sb_block;
113}
114
Chris Lattner24943d22010-06-08 16:52:24 +0000115SBLineEntry
116SBFrame::GetLineEntry () const
117{
Greg Clayton63094e02010-06-23 01:19:29 +0000118 SBLineEntry sb_line_entry(&m_opaque_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry);
Chris Lattner24943d22010-06-08 16:52:24 +0000119 return sb_line_entry;
120}
121
122uint32_t
123SBFrame::GetFrameID () const
124{
Greg Clayton63094e02010-06-23 01:19:29 +0000125 if (m_opaque_sp)
Greg Clayton33ed1702010-08-24 00:45:41 +0000126 return m_opaque_sp->GetFrameIndex ();
Chris Lattner24943d22010-06-08 16:52:24 +0000127 else
128 return UINT32_MAX;
129}
130
Chris Lattner24943d22010-06-08 16:52:24 +0000131lldb::addr_t
132SBFrame::GetPC () const
133{
Greg Clayton63094e02010-06-23 01:19:29 +0000134 if (m_opaque_sp)
Greg Claytoneea26402010-09-14 23:36:40 +0000135 return m_opaque_sp->GetFrameCodeAddress().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget());
Chris Lattner24943d22010-06-08 16:52:24 +0000136 return LLDB_INVALID_ADDRESS;
137}
138
139bool
140SBFrame::SetPC (lldb::addr_t new_pc)
141{
Greg Clayton63094e02010-06-23 01:19:29 +0000142 if (m_opaque_sp)
143 return m_opaque_sp->GetRegisterContext()->SetPC (new_pc);
Chris Lattner24943d22010-06-08 16:52:24 +0000144 return false;
145}
146
147lldb::addr_t
148SBFrame::GetSP () const
149{
Greg Clayton63094e02010-06-23 01:19:29 +0000150 if (m_opaque_sp)
151 return m_opaque_sp->GetRegisterContext()->GetSP();
Chris Lattner24943d22010-06-08 16:52:24 +0000152 return LLDB_INVALID_ADDRESS;
153}
154
155
156lldb::addr_t
157SBFrame::GetFP () const
158{
Greg Clayton63094e02010-06-23 01:19:29 +0000159 if (m_opaque_sp)
160 return m_opaque_sp->GetRegisterContext()->GetFP();
Chris Lattner24943d22010-06-08 16:52:24 +0000161 return LLDB_INVALID_ADDRESS;
162}
163
164
165SBAddress
166SBFrame::GetPCAddress () const
167{
168 SBAddress sb_addr;
Greg Clayton63094e02010-06-23 01:19:29 +0000169 if (m_opaque_sp)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000170 sb_addr.SetAddress (&m_opaque_sp->GetFrameCodeAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000171 return sb_addr;
172}
173
174void
175SBFrame::Clear()
176{
Greg Clayton63094e02010-06-23 01:19:29 +0000177 m_opaque_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000178}
179
180SBValue
181SBFrame::LookupVar (const char *var_name)
182{
183 lldb::VariableSP var_sp;
184 if (IsValid ())
185 {
186 lldb_private::VariableList variable_list;
187 SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything);
188
189 SBBlock block = sc.GetBlock();
190 if (block.IsValid())
191 block.AppendVariables (true, true, &variable_list);
192
193 const uint32_t num_variables = variable_list.GetSize();
194
195 bool found = false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000196 for (uint32_t i = 0; i < num_variables && !found; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000197 {
198 var_sp = variable_list.GetVariableAtIndex(i);
199 if (var_sp
200 && (var_sp.get()->GetName() == lldb_private::ConstString(var_name)))
201 found = true;
202 }
203 if (!found)
204 var_sp.reset();
205 }
206 SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp)));
207 return sb_value;
208}
209
210SBValue
211SBFrame::LookupVarInScope (const char *var_name, const char *scope)
212{
213 lldb::VariableSP var_sp;
214 if (IsValid())
215 {
216 std::string scope_str = scope;
217 lldb::ValueType var_scope = eValueTypeInvalid;
218 // Convert scope_str to be all lowercase;
219 std::transform (scope_str.begin(), scope_str.end(), scope_str.begin(), ::tolower);
220
221 if (scope_str.compare ("global") == 0)
222 var_scope = eValueTypeVariableGlobal;
223 else if (scope_str.compare ("local") == 0)
224 var_scope = eValueTypeVariableLocal;
225 else if (scope_str.compare ("parameter") == 0)
226 var_scope = eValueTypeVariableArgument;
227
228 if (var_scope != eValueTypeInvalid)
229 {
230 lldb_private::VariableList variable_list;
231 SBSymbolContext sc = GetSymbolContext (eSymbolContextEverything);
232
233 SBBlock block = sc.GetBlock();
234 if (block.IsValid())
235 block.AppendVariables (true, true, &variable_list);
236
237 const uint32_t num_variables = variable_list.GetSize();
238
239 bool found = false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000240 for (uint32_t i = 0; i < num_variables && !found; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000241 {
242 var_sp = variable_list.GetVariableAtIndex(i);
243 if (var_sp
244 && (var_sp.get()->GetName() == lldb_private::ConstString(var_name))
245 && var_sp.get()->GetScope() == var_scope)
246 found = true;
247 }
248 if (!found)
249 var_sp.reset();
250 }
251 }
252 SBValue sb_value (ValueObjectSP (new ValueObjectVariable (var_sp)));
253 return sb_value;
254}
255
256bool
257SBFrame::operator == (const SBFrame &rhs) const
258{
Greg Clayton63094e02010-06-23 01:19:29 +0000259 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000260}
261
262bool
263SBFrame::operator != (const SBFrame &rhs) const
264{
Greg Clayton63094e02010-06-23 01:19:29 +0000265 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000266}
267
268lldb_private::StackFrame *
269SBFrame::operator->() const
270{
Greg Clayton63094e02010-06-23 01:19:29 +0000271 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000272}
273
274lldb_private::StackFrame *
275SBFrame::get() const
276{
Greg Clayton63094e02010-06-23 01:19:29 +0000277 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000278}
279
280
281SBThread
282SBFrame::GetThread () const
283{
Greg Clayton63094e02010-06-23 01:19:29 +0000284 SBThread sb_thread (m_opaque_sp->GetThread().GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000285 return sb_thread;
286}
287
288const char *
289SBFrame::Disassemble () const
290{
Greg Clayton63094e02010-06-23 01:19:29 +0000291 if (m_opaque_sp)
292 return m_opaque_sp->Disassemble();
Chris Lattner24943d22010-06-08 16:52:24 +0000293 return NULL;
294}
295
296
297
298lldb_private::StackFrame *
299SBFrame::GetLLDBObjectPtr ()
300{
Greg Clayton63094e02010-06-23 01:19:29 +0000301 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000302}
303
304SBValueList
305SBFrame::GetVariables (bool arguments,
306 bool locals,
307 bool statics,
308 bool in_scope_only)
309{
310 SBValueList value_list;
Greg Clayton63094e02010-06-23 01:19:29 +0000311 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000312 {
313 size_t i;
Greg Clayton17dae082010-09-02 02:59:18 +0000314 VariableList *variable_list = m_opaque_sp->GetVariableList(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000315 if (variable_list)
316 {
317 const size_t num_variables = variable_list->GetSize();
318 if (num_variables)
319 {
320 for (i = 0; i < num_variables; ++i)
321 {
322 VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
323 if (variable_sp)
324 {
325 bool add_variable = false;
326 switch (variable_sp->GetScope())
327 {
328 case eValueTypeVariableGlobal:
329 case eValueTypeVariableStatic:
330 add_variable = statics;
331 break;
332
333 case eValueTypeVariableArgument:
334 add_variable = arguments;
335 break;
336
337 case eValueTypeVariableLocal:
338 add_variable = locals;
339 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000340
341 default:
342 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344 if (add_variable)
345 {
Greg Clayton63094e02010-06-23 01:19:29 +0000346 if (in_scope_only && !variable_sp->IsInScope(m_opaque_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000347 continue;
348
Greg Clayton17dae082010-09-02 02:59:18 +0000349 value_list.Append(m_opaque_sp->GetValueObjectForFrameVariable (variable_sp));
Chris Lattner24943d22010-06-08 16:52:24 +0000350 }
351 }
352 }
353 }
Greg Clayton17dae082010-09-02 02:59:18 +0000354 }
Chris Lattner24943d22010-06-08 16:52:24 +0000355 }
356 return value_list;
357}
358
359lldb::SBValueList
360SBFrame::GetRegisters ()
361{
362 SBValueList value_list;
Greg Clayton63094e02010-06-23 01:19:29 +0000363 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000364 {
Greg Clayton63094e02010-06-23 01:19:29 +0000365 RegisterContext *reg_ctx = m_opaque_sp->GetRegisterContext();
Chris Lattner24943d22010-06-08 16:52:24 +0000366 if (reg_ctx)
367 {
368 const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
369 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
370 {
371 value_list.Append(ValueObjectSP (new ValueObjectRegisterSet (reg_ctx, set_idx)));
372 }
373 }
374 }
375 return value_list;
376}
377