blob: 0d258790f3cf6ba900e9b7fcdebcaac8444e2930 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Target/StackFrame.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Module.h"
Greg Claytona830adb2010-10-04 01:05:56 +000017#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/Disassembler.h"
19#include "lldb/Core/Value.h"
Greg Clayton17dae082010-09-02 02:59:18 +000020#include "lldb/Core/ValueObjectVariable.h"
Greg Claytonc3b61d22010-12-15 05:08:08 +000021#include "lldb/Core/ValueObjectConstResult.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Symbol/Function.h"
Greg Clayton17dae082010-09-02 02:59:18 +000023#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/ExecutionContext.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Target/RegisterContext.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33// The first bits in the flags are reserved for the SymbolContext::Scope bits
34// so we know if we have tried to look up information in our internal symbol
35// context (m_sc) already.
Greg Clayton4fb08152010-08-30 18:11:35 +000036#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
Greg Clayton72b71582010-09-02 21:44:10 +000037#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
Greg Clayton4fb08152010-08-30 18:11:35 +000038#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
39#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
Sean Callanan89363592010-11-01 04:38:59 +000040#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
Chris Lattner24943d22010-06-08 16:52:24 +000041
Greg Clayton23b8abb2011-09-26 07:11:27 +000042StackFrame::StackFrame (user_id_t frame_idx,
43 user_id_t unwind_frame_index,
44 Thread &thread,
45 addr_t cfa,
46 addr_t pc,
47 const SymbolContext *sc_ptr) :
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000048 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000049 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +000050 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +000051 m_reg_context_sp (),
Greg Clayton72b71582010-09-02 21:44:10 +000052 m_id (pc, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000053 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000054 m_sc (),
55 m_flags (),
56 m_frame_base (),
57 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000059 m_variable_list_value_objects (),
60 m_disassembly ()
Chris Lattner24943d22010-06-08 16:52:24 +000061{
62 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000063 {
Chris Lattner24943d22010-06-08 16:52:24 +000064 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000065 m_flags.Set(m_sc.GetResolvedMask ());
66 }
Chris Lattner24943d22010-06-08 16:52:24 +000067}
68
Greg Clayton23b8abb2011-09-26 07:11:27 +000069StackFrame::StackFrame (user_id_t frame_idx,
70 user_id_t unwind_frame_index,
71 Thread &thread,
72 const RegisterContextSP &reg_context_sp,
73 addr_t cfa,
74 addr_t pc,
75 const SymbolContext *sc_ptr) :
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000076 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +000077 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +000078 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +000079 m_reg_context_sp (reg_context_sp),
Greg Clayton72b71582010-09-02 21:44:10 +000080 m_id (pc, cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +000081 m_frame_code_addr (NULL, pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000082 m_sc (),
83 m_flags (),
84 m_frame_base (),
85 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000086 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000087 m_variable_list_value_objects (),
88 m_disassembly ()
Chris Lattner24943d22010-06-08 16:52:24 +000089{
90 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000091 {
Chris Lattner24943d22010-06-08 16:52:24 +000092 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000093 m_flags.Set(m_sc.GetResolvedMask ());
94 }
95
96 if (reg_context_sp && !m_sc.target_sp)
97 {
98 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
99 m_flags.Set (eSymbolContextTarget);
100 }
101}
102
Greg Clayton23b8abb2011-09-26 07:11:27 +0000103StackFrame::StackFrame (user_id_t frame_idx,
104 user_id_t unwind_frame_index,
105 Thread &thread,
106 const RegisterContextSP &reg_context_sp,
107 addr_t cfa,
108 const Address& pc_addr,
109 const SymbolContext *sc_ptr) :
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000110 m_thread (thread),
Greg Clayton33ed1702010-08-24 00:45:41 +0000111 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000112 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +0000113 m_reg_context_sp (reg_context_sp),
Greg Claytoneea26402010-09-14 23:36:40 +0000114 m_id (pc_addr.GetLoadAddress (&thread.GetProcess().GetTarget()), cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +0000115 m_frame_code_addr (pc_addr),
Greg Clayton33ed1702010-08-24 00:45:41 +0000116 m_sc (),
117 m_flags (),
118 m_frame_base (),
119 m_frame_base_error (),
120 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000121 m_variable_list_value_objects (),
122 m_disassembly ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000123{
124 if (sc_ptr != NULL)
125 {
126 m_sc = *sc_ptr;
127 m_flags.Set(m_sc.GetResolvedMask ());
128 }
129
130 if (m_sc.target_sp.get() == NULL && reg_context_sp)
131 {
132 m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
133 m_flags.Set (eSymbolContextTarget);
134 }
135
Greg Claytone2c5e452010-09-13 04:34:30 +0000136 Module *pc_module = pc_addr.GetModule();
137 if (m_sc.module_sp.get() == NULL || m_sc.module_sp.get() != pc_module)
Greg Clayton33ed1702010-08-24 00:45:41 +0000138 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000139 if (pc_module)
140 {
Greg Clayton02e210c2011-09-17 07:23:18 +0000141 m_sc.module_sp = pc_module;
Greg Clayton33ed1702010-08-24 00:45:41 +0000142 m_flags.Set (eSymbolContextModule);
143 }
Greg Claytone2c5e452010-09-13 04:34:30 +0000144 else
145 {
146 m_sc.module_sp.reset();
147 }
148
Greg Clayton33ed1702010-08-24 00:45:41 +0000149 }
Chris Lattner24943d22010-06-08 16:52:24 +0000150}
151
152
153//----------------------------------------------------------------------
154// Destructor
155//----------------------------------------------------------------------
156StackFrame::~StackFrame()
157{
158}
159
160StackID&
161StackFrame::GetStackID()
162{
Greg Clayton72b71582010-09-02 21:44:10 +0000163 // Make sure we have resolved the StackID object's symbol context scope if
164 // we already haven't looked it up.
Chris Lattner24943d22010-06-08 16:52:24 +0000165
Greg Clayton4fb08152010-08-30 18:11:35 +0000166 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
167 {
Greg Clayton5205f0b2010-09-03 17:10:42 +0000168 if (m_id.GetSymbolContextScope ())
Greg Clayton4fb08152010-08-30 18:11:35 +0000169 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000170 // We already have a symbol context scope, we just don't have our
171 // flag bit set.
Greg Clayton4fb08152010-08-30 18:11:35 +0000172 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
173 }
174 else
175 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000176 // Calculate the frame block and use this for the stack ID symbol
177 // context scope if we have one.
178 SymbolContextScope *scope = GetFrameBlock ();
179 if (scope == NULL)
Greg Clayton4fb08152010-08-30 18:11:35 +0000180 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000181 // We don't have a block, so use the symbol
182 if (m_flags.IsClear (eSymbolContextSymbol))
183 GetSymbolContext (eSymbolContextSymbol);
184
185 // It is ok if m_sc.symbol is NULL here
186 scope = m_sc.symbol;
Greg Clayton4fb08152010-08-30 18:11:35 +0000187 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000188 // Set the symbol context scope (the accessor will set the
189 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
190 SetSymbolContextScope (scope);
Greg Clayton4fb08152010-08-30 18:11:35 +0000191 }
Chris Lattner24943d22010-06-08 16:52:24 +0000192 }
193 return m_id;
194}
195
Greg Clayton4fb08152010-08-30 18:11:35 +0000196void
197StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
198{
199 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
200 m_id.SetSymbolContextScope (symbol_scope);
201}
202
Greg Clayton107e53d2011-07-06 04:07:21 +0000203const Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000204StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000205{
Greg Clayton4fb08152010-08-30 18:11:35 +0000206 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000207 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000208 m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000209
210 // Resolve the PC into a temporary address because if ResolveLoadAddress
211 // fails to resolve the address, it will clear the address object...
Greg Clayton107e53d2011-07-06 04:07:21 +0000212
213 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), &m_thread.GetProcess().GetTarget()))
Chris Lattner24943d22010-06-08 16:52:24 +0000214 {
Greg Clayton65124ea2010-08-26 22:05:43 +0000215 const Section *section = m_frame_code_addr.GetSection();
Chris Lattner24943d22010-06-08 16:52:24 +0000216 if (section)
217 {
218 Module *module = section->GetModule();
219 if (module)
220 {
Greg Clayton02e210c2011-09-17 07:23:18 +0000221 m_sc.module_sp = module;
Chris Lattner24943d22010-06-08 16:52:24 +0000222 if (m_sc.module_sp)
223 m_flags.Set(eSymbolContextModule);
224 }
225 }
226 }
227 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000228 return m_frame_code_addr;
Chris Lattner24943d22010-06-08 16:52:24 +0000229}
230
231void
232StackFrame::ChangePC (addr_t pc)
233{
Greg Clayton65124ea2010-08-26 22:05:43 +0000234 m_frame_code_addr.SetOffset(pc);
235 m_frame_code_addr.SetSection(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000236 m_sc.Clear();
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000237 m_flags.Reset(0);
Chris Lattner24943d22010-06-08 16:52:24 +0000238 m_thread.ClearStackFrames ();
239}
240
241const char *
242StackFrame::Disassemble ()
243{
244 if (m_disassembly.GetSize() == 0)
245 {
246 ExecutionContext exe_ctx;
Greg Claytona830adb2010-10-04 01:05:56 +0000247 CalculateExecutionContext(exe_ctx);
Greg Clayton63094e02010-06-23 01:19:29 +0000248 Target &target = m_thread.GetProcess().GetTarget();
249 Disassembler::Disassemble (target.GetDebugger(),
250 target.GetArchitecture(),
Greg Clayton149731c2011-03-25 18:03:16 +0000251 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000252 exe_ctx,
253 0,
Jim Inghamaa3e3e12011-03-22 01:48:42 +0000254 0,
Greg Clayton4bb0f192011-06-22 01:39:49 +0000255 0,
Chris Lattner24943d22010-06-08 16:52:24 +0000256 m_disassembly);
257 if (m_disassembly.GetSize() == 0)
258 return NULL;
259 }
260 return m_disassembly.GetData();
261}
262
Greg Clayton69aa5d92010-09-07 04:20:48 +0000263Block *
264StackFrame::GetFrameBlock ()
265{
266 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
267 GetSymbolContext (eSymbolContextBlock);
268
269 if (m_sc.block)
270 {
271 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
272 if (inline_block)
273 {
274 // Use the block with the inlined function info
275 // as the frame block we want this frame to have only the variables
276 // for the inlined function and its non-inlined block child blocks.
277 return inline_block;
278 }
279 else
280 {
281 // This block is not contained withing any inlined function blocks
282 // with so we want to use the top most function block.
283 return &m_sc.function->GetBlock (false);
284 }
285 }
286 return NULL;
287}
288
Chris Lattner24943d22010-06-08 16:52:24 +0000289//----------------------------------------------------------------------
290// Get the symbol context if we already haven't done so by resolving the
291// PC address as much as possible. This way when we pass around a
292// StackFrame object, everyone will have as much information as
293// possible and no one will ever have to look things up manually.
294//----------------------------------------------------------------------
295const SymbolContext&
296StackFrame::GetSymbolContext (uint32_t resolve_scope)
297{
298 // Copy our internal symbol context into "sc".
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000299 if ((m_flags.Get() & resolve_scope) != resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000300 {
301 // Resolve our PC to section offset if we haven't alreday done so
302 // and if we don't have a module. The resolved address section will
303 // contain the module to which it belongs
Greg Clayton4fb08152010-08-30 18:11:35 +0000304 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
Greg Claytonb04e7a82010-08-24 21:05:24 +0000305 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000306
307 // If this is not frame zero, then we need to subtract 1 from the PC
308 // value when doing address lookups since the PC will be on the
309 // instruction following the function call instruction...
310
Greg Claytonb04e7a82010-08-24 21:05:24 +0000311 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000312 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
314 addr_t offset = lookup_addr.GetOffset();
315 if (offset > 0)
316 lookup_addr.SetOffset(offset - 1);
317 }
318
Greg Claytonb04e7a82010-08-24 21:05:24 +0000319
320 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000321 if (m_sc.module_sp)
322 {
323 // We have something in our stack frame symbol context, lets check
324 // if we haven't already tried to lookup one of those things. If we
325 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000326
327 uint32_t actual_resolve_scope = 0;
328
329 if (resolve_scope & eSymbolContextCompUnit)
330 {
331 if (m_flags.IsClear (eSymbolContextCompUnit))
332 {
333 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000334 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000335 else
336 actual_resolve_scope |= eSymbolContextCompUnit;
337 }
338 }
339
340 if (resolve_scope & eSymbolContextFunction)
341 {
342 if (m_flags.IsClear (eSymbolContextFunction))
343 {
344 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000345 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000346 else
347 actual_resolve_scope |= eSymbolContextFunction;
348 }
349 }
350
351 if (resolve_scope & eSymbolContextBlock)
352 {
353 if (m_flags.IsClear (eSymbolContextBlock))
354 {
355 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000356 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000357 else
358 actual_resolve_scope |= eSymbolContextBlock;
359 }
360 }
361
362 if (resolve_scope & eSymbolContextSymbol)
363 {
364 if (m_flags.IsClear (eSymbolContextSymbol))
365 {
366 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000367 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000368 else
369 actual_resolve_scope |= eSymbolContextSymbol;
370 }
371 }
372
373 if (resolve_scope & eSymbolContextLineEntry)
374 {
375 if (m_flags.IsClear (eSymbolContextLineEntry))
376 {
377 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000378 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000379 else
380 actual_resolve_scope |= eSymbolContextLineEntry;
381 }
382 }
383
384 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000385 {
386 // We might be resolving less information than what is already
387 // in our current symbol context so resolve into a temporary
388 // symbol context "sc" so we don't clear out data we have
389 // already found in "m_sc"
390 SymbolContext sc;
391 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000392 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000393 // Only replace what we didn't already have as we may have
394 // information for an inlined function scope that won't match
395 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000396 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
397 m_sc.comp_unit = sc.comp_unit;
398 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
399 m_sc.function = sc.function;
400 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
401 m_sc.block = sc.block;
402 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
403 m_sc.symbol = sc.symbol;
404 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
405 m_sc.line_entry = sc.line_entry;
406
Chris Lattner24943d22010-06-08 16:52:24 +0000407 }
408 }
409 else
410 {
411 // If we don't have a module, then we can't have the compile unit,
412 // function, block, line entry or symbol, so we can safely call
413 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000414 resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000415 }
416
417 // If the target was requested add that:
418 if (m_sc.target_sp.get() == NULL)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000419 {
Chris Lattner24943d22010-06-08 16:52:24 +0000420 m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000421 if (m_sc.target_sp)
422 resolved |= eSymbolContextTarget;
423 }
Chris Lattner24943d22010-06-08 16:52:24 +0000424
425 // Update our internal flags so we remember what we have tried to locate so
426 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000427 // We might have dug up more information that was requested (for example
428 // if we were asked to only get the block, we will have gotten the
429 // compile unit, and function) so set any additional bits that we resolved
430 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000431 }
432
433 // Return the symbol context with everything that was possible to resolve
434 // resolved.
435 return m_sc;
436}
437
438
439VariableList *
Greg Clayton17dae082010-09-02 02:59:18 +0000440StackFrame::GetVariableList (bool get_file_globals)
Chris Lattner24943d22010-06-08 16:52:24 +0000441{
442 if (m_flags.IsClear(RESOLVED_VARIABLES))
443 {
444 m_flags.Set(RESOLVED_VARIABLES);
445
Greg Clayton69aa5d92010-09-07 04:20:48 +0000446 Block *frame_block = GetFrameBlock();
447
448 if (frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000449 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000450 const bool get_child_variables = true;
451 const bool can_create = true;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000452 const bool stop_if_child_block_is_inlined_function = true;
453 m_variable_list_sp.reset(new VariableList());
454 frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000455 }
Sean Callanan89363592010-11-01 04:38:59 +0000456 }
457
458 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
459 get_file_globals)
460 {
461 m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
Greg Clayton17dae082010-09-02 02:59:18 +0000462
Sean Callanan89363592010-11-01 04:38:59 +0000463 if (m_flags.IsClear (eSymbolContextCompUnit))
464 GetSymbolContext (eSymbolContextCompUnit);
465
466 if (m_sc.comp_unit)
Greg Clayton17dae082010-09-02 02:59:18 +0000467 {
Sean Callanan89363592010-11-01 04:38:59 +0000468 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
469 if (m_variable_list_sp)
470 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
471 else
472 m_variable_list_sp = global_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +0000473 }
Chris Lattner24943d22010-06-08 16:52:24 +0000474 }
Sean Callanan89363592010-11-01 04:38:59 +0000475
Chris Lattner24943d22010-06-08 16:52:24 +0000476 return m_variable_list_sp.get();
477}
478
Greg Clayton6e2d2822011-08-02 23:35:43 +0000479VariableListSP
480StackFrame::GetInScopeVariableList (bool get_file_globals)
481{
482 VariableListSP var_list_sp(new VariableList);
483 GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
484
485 if (m_sc.block)
486 {
487 const bool can_create = true;
488 const bool get_parent_variables = true;
489 const bool stop_if_block_is_inlined_function = true;
490 m_sc.block->AppendVariables (can_create,
491 get_parent_variables,
492 stop_if_block_is_inlined_function,
493 var_list_sp.get());
494 }
495
496 if (m_sc.comp_unit)
497 {
498 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
499 if (global_variable_list_sp)
500 var_list_sp->AddVariables (global_variable_list_sp.get());
501 }
502
503 return var_list_sp;
504}
505
506
Greg Clayton427f2902010-12-14 02:59:59 +0000507ValueObjectSP
Jim Ingham10de7d12011-05-04 03:43:18 +0000508StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
Greg Clayton987c7eb2011-09-17 08:33:22 +0000509 DynamicValueType use_dynamic,
Jim Ingham10de7d12011-05-04 03:43:18 +0000510 uint32_t options,
Greg Clayton987c7eb2011-09-17 08:33:22 +0000511 VariableSP &var_sp,
Jim Ingham10de7d12011-05-04 03:43:18 +0000512 Error &error)
Greg Clayton427f2902010-12-14 02:59:59 +0000513{
Greg Claytonc3b61d22010-12-15 05:08:08 +0000514
515 if (var_expr_cstr && var_expr_cstr[0])
Greg Clayton427f2902010-12-14 02:59:59 +0000516 {
Greg Claytonc67efa42011-01-20 19:27:18 +0000517 const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
518 const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
Enrico Granataf6698502011-08-09 01:04:56 +0000519 const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
Enrico Granata13a54a12011-08-19 21:56:10 +0000520 //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
Greg Claytonc3b61d22010-12-15 05:08:08 +0000521 error.Clear();
522 bool deref = false;
523 bool address_of = false;
524 ValueObjectSP valobj_sp;
525 const bool get_file_globals = true;
Greg Clayton6e2d2822011-08-02 23:35:43 +0000526 // When looking up a variable for an expression, we need only consider the
527 // variables that are in scope.
528 VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
529 VariableList *variable_list = var_list_sp.get();
Greg Claytonc3b61d22010-12-15 05:08:08 +0000530
531 if (variable_list)
Greg Clayton427f2902010-12-14 02:59:59 +0000532 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000533 // If first character is a '*', then show pointer contents
534 const char *var_expr = var_expr_cstr;
535 if (var_expr[0] == '*')
Greg Clayton427f2902010-12-14 02:59:59 +0000536 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000537 deref = true;
538 var_expr++; // Skip the '*'
539 }
540 else if (var_expr[0] == '&')
541 {
542 address_of = true;
543 var_expr++; // Skip the '&'
544 }
545
546 std::string var_path (var_expr);
547 size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
548 StreamString var_expr_path_strm;
549
550 ConstString name_const_string;
551 if (separator_idx == std::string::npos)
552 name_const_string.SetCString (var_path.c_str());
553 else
554 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
555
Jim Ingham10de7d12011-05-04 03:43:18 +0000556 var_sp = variable_list->FindVariable(name_const_string);
Greg Claytonc3b61d22010-12-15 05:08:08 +0000557 if (var_sp)
558 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000559 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
Jim Inghame41494a2011-04-16 00:01:13 +0000560 if (!valobj_sp)
561 return valobj_sp;
562
Greg Claytonc3b61d22010-12-15 05:08:08 +0000563 var_path.erase (0, name_const_string.GetLength ());
564 // We are dumping at least one child
565 while (separator_idx != std::string::npos)
Greg Clayton427f2902010-12-14 02:59:59 +0000566 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000567 // Calculate the next separator index ahead of time
568 ValueObjectSP child_valobj_sp;
569 const char separator_type = var_path[0];
570 switch (separator_type)
Greg Clayton427f2902010-12-14 02:59:59 +0000571 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000572
573 case '-':
574 if (var_path.size() >= 2 && var_path[1] != '>')
Greg Clayton427f2902010-12-14 02:59:59 +0000575 return ValueObjectSP();
Greg Clayton427f2902010-12-14 02:59:59 +0000576
Greg Claytonc67efa42011-01-20 19:27:18 +0000577 if (no_fragile_ivar)
578 {
579 // Make sure we aren't trying to deref an objective
580 // C ivar if this is not allowed
581 const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (valobj_sp->GetClangType(), NULL, NULL);
582 if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) &&
583 (pointer_type_flags & ClangASTContext::eTypeIsPointer))
584 {
585 // This was an objective C object pointer and
586 // it was requested we skip any fragile ivars
587 // so return nothing here
588 return ValueObjectSP();
589 }
590 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000591 var_path.erase (0, 1); // Remove the '-'
592 // Fall through
593 case '.':
Greg Clayton427f2902010-12-14 02:59:59 +0000594 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000595 const bool expr_is_ptr = var_path[0] == '>';
Greg Clayton427f2902010-12-14 02:59:59 +0000596
Greg Claytonc3b61d22010-12-15 05:08:08 +0000597 var_path.erase (0, 1); // Remove the '.' or '>'
598 separator_idx = var_path.find_first_of(".-[");
599 ConstString child_name;
600 if (separator_idx == std::string::npos)
601 child_name.SetCString (var_path.c_str());
Greg Clayton427f2902010-12-14 02:59:59 +0000602 else
Greg Claytonc3b61d22010-12-15 05:08:08 +0000603 child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
604
605 if (check_ptr_vs_member)
Greg Clayton427f2902010-12-14 02:59:59 +0000606 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000607 // We either have a pointer type and need to verify
608 // valobj_sp is a pointer, or we have a member of a
609 // class/union/struct being accessed with the . syntax
610 // and need to verify we don't have a pointer.
611 const bool actual_is_ptr = valobj_sp->IsPointerType ();
612
613 if (actual_is_ptr != expr_is_ptr)
614 {
615 // Incorrect use of "." with a pointer, or "->" with
616 // a class/union/struct instance or reference.
Greg Claytonb01000f2011-01-17 03:46:26 +0000617 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Greg Claytonc3b61d22010-12-15 05:08:08 +0000618 if (actual_is_ptr)
619 error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
620 var_expr_path_strm.GetString().c_str(),
621 child_name.GetCString(),
622 var_expr_path_strm.GetString().c_str(),
623 var_path.c_str());
624 else
625 error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
626 var_expr_path_strm.GetString().c_str(),
627 child_name.GetCString(),
628 var_expr_path_strm.GetString().c_str(),
629 var_path.c_str());
630 return ValueObjectSP();
631 }
Greg Clayton427f2902010-12-14 02:59:59 +0000632 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000633 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
Greg Clayton427f2902010-12-14 02:59:59 +0000634 if (!child_valobj_sp)
635 {
Enrico Granata9c57fc02011-08-11 17:08:01 +0000636 if (no_synth_child == false)
Greg Clayton987c7eb2011-09-17 08:33:22 +0000637 child_valobj_sp = valobj_sp->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName (child_name, true);
Enrico Granata9c57fc02011-08-11 17:08:01 +0000638
639 if (no_synth_child || !child_valobj_sp)
Greg Claytonc3b61d22010-12-15 05:08:08 +0000640 {
Enrico Granata9c57fc02011-08-11 17:08:01 +0000641 // No child member with name "child_name"
642 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
643 if (child_name)
644 {
645 error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
646 child_name.GetCString(),
647 valobj_sp->GetTypeName().AsCString("<invalid type>"),
648 var_expr_path_strm.GetString().c_str());
649 }
650 else
651 {
652 error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
653 var_expr_path_strm.GetString().c_str(),
654 var_expr_cstr);
655 }
656 return ValueObjectSP();
Greg Claytonc3b61d22010-12-15 05:08:08 +0000657 }
Greg Clayton427f2902010-12-14 02:59:59 +0000658 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000659 // Remove the child name from the path
660 var_path.erase(0, child_name.GetLength());
Greg Clayton987c7eb2011-09-17 08:33:22 +0000661 if (use_dynamic != eNoDynamicValues)
Jim Inghame41494a2011-04-16 00:01:13 +0000662 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000663 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
Jim Inghame41494a2011-04-16 00:01:13 +0000664 if (dynamic_value_sp)
665 child_valobj_sp = dynamic_value_sp;
666 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000667 }
668 break;
Greg Clayton427f2902010-12-14 02:59:59 +0000669
Greg Claytonc3b61d22010-12-15 05:08:08 +0000670 case '[':
671 // Array member access, or treating pointer as an array
672 if (var_path.size() > 2) // Need at least two brackets and a number
673 {
674 char *end = NULL;
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000675 long child_index = ::strtol (&var_path[1], &end, 0);
Enrico Granata9762e102011-07-06 02:13:41 +0000676 if (end && *end == ']'
677 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
Greg Claytonc3b61d22010-12-15 05:08:08 +0000678 {
Enrico Granata9762e102011-07-06 02:13:41 +0000679 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
680 {
681 // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
682 // and extract bit low out of it. reading array item low
683 // would be done by saying ptr[low], without a deref * sign
684 Error error;
685 ValueObjectSP temp(valobj_sp->Dereference(error));
686 if (error.Fail())
687 {
688 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
689 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
690 valobj_sp->GetTypeName().AsCString("<invalid type>"),
691 var_expr_path_strm.GetString().c_str());
692 return ValueObjectSP();
693 }
694 valobj_sp = temp;
695 deref = false;
696 }
697 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
698 {
699 // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
700 // (an operation that is equivalent to deref-ing arr)
701 // and extract bit low out of it. reading array item low
702 // would be done by saying arr[low], without a deref * sign
703 Error error;
704 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
705 if (error.Fail())
706 {
707 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
708 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
709 valobj_sp->GetTypeName().AsCString("<invalid type>"),
710 var_expr_path_strm.GetString().c_str());
711 return ValueObjectSP();
712 }
713 valobj_sp = temp;
714 deref = false;
715 }
716
Greg Claytonc3b61d22010-12-15 05:08:08 +0000717 if (valobj_sp->IsPointerType ())
718 {
Enrico Granataf6698502011-08-09 01:04:56 +0000719 if (no_synth_child == false
720 &&
721 ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(),
Greg Clayton987c7eb2011-09-17 08:33:22 +0000722 valobj_sp->GetClangType()) == eLanguageTypeObjC /* is ObjC pointer */
Enrico Granataf6698502011-08-09 01:04:56 +0000723 &&
724 ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(valobj_sp->GetClangType())) == false /* is not double-ptr */)
Greg Claytonc3b61d22010-12-15 05:08:08 +0000725 {
Enrico Granataf6698502011-08-09 01:04:56 +0000726 // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
Greg Clayton987c7eb2011-09-17 08:33:22 +0000727 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(eUseSyntheticFilter);
Enrico Granataf6698502011-08-09 01:04:56 +0000728 if (synthetic.get() == NULL /* no synthetic */
729 || synthetic == valobj_sp) /* synthetic is the same as the original object */
730 {
731 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
732 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
733 valobj_sp->GetTypeName().AsCString("<invalid type>"),
734 var_expr_path_strm.GetString().c_str());
735 }
736 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
737 {
738 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000739 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000740 child_index,
741 valobj_sp->GetTypeName().AsCString("<invalid type>"),
742 var_expr_path_strm.GetString().c_str());
743 }
744 else
745 {
746 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
747 if (!child_valobj_sp)
748 {
749 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000750 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000751 child_index,
752 valobj_sp->GetTypeName().AsCString("<invalid type>"),
753 var_expr_path_strm.GetString().c_str());
754 }
755 }
756 }
757 else
758 {
759 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
760 if (!child_valobj_sp)
761 {
762 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000763 error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000764 child_index,
765 valobj_sp->GetTypeName().AsCString("<invalid type>"),
766 var_expr_path_strm.GetString().c_str());
767 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000768 }
769 }
770 else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL))
771 {
Jim Inghame41494a2011-04-16 00:01:13 +0000772 // Pass false to dynamic_value here so we can tell the difference between
773 // no dynamic value and no member of this type...
Greg Claytonc3b61d22010-12-15 05:08:08 +0000774 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
775 if (!child_valobj_sp)
776 {
Greg Claytonb01000f2011-01-17 03:46:26 +0000777 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000778 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Greg Claytonc3b61d22010-12-15 05:08:08 +0000779 child_index,
780 valobj_sp->GetTypeName().AsCString("<invalid type>"),
781 var_expr_path_strm.GetString().c_str());
782 }
783 }
Enrico Granata9762e102011-07-06 02:13:41 +0000784 else if (ClangASTContext::IsScalarType(valobj_sp->GetClangType()))
785 {
786 // this is a bitfield asking to display just one bit
787 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
788 if (!child_valobj_sp)
789 {
790 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000791 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
Enrico Granata9762e102011-07-06 02:13:41 +0000792 child_index, child_index,
793 valobj_sp->GetTypeName().AsCString("<invalid type>"),
794 var_expr_path_strm.GetString().c_str());
795 }
796 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000797 else
798 {
Greg Clayton987c7eb2011-09-17 08:33:22 +0000799 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(eUseSyntheticFilter);
Enrico Granataf6698502011-08-09 01:04:56 +0000800 if (no_synth_child /* synthetic is forbidden */ ||
801 synthetic.get() == NULL /* no synthetic */
802 || synthetic == valobj_sp) /* synthetic is the same as the original object */
803 {
804 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
805 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
806 valobj_sp->GetTypeName().AsCString("<invalid type>"),
807 var_expr_path_strm.GetString().c_str());
808 }
809 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
810 {
811 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000812 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000813 child_index,
814 valobj_sp->GetTypeName().AsCString("<invalid type>"),
815 var_expr_path_strm.GetString().c_str());
816 }
817 else
818 {
819 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
820 if (!child_valobj_sp)
821 {
822 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000823 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000824 child_index,
825 valobj_sp->GetTypeName().AsCString("<invalid type>"),
826 var_expr_path_strm.GetString().c_str());
827 }
828 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000829 }
830
831 if (!child_valobj_sp)
832 {
833 // Invalid array index...
834 return ValueObjectSP();
835 }
836
837 // Erase the array member specification '[%i]' where
838 // %i is the array index
839 var_path.erase(0, (end - var_path.c_str()) + 1);
840 separator_idx = var_path.find_first_of(".-[");
Greg Clayton987c7eb2011-09-17 08:33:22 +0000841 if (use_dynamic != eNoDynamicValues)
Jim Inghame41494a2011-04-16 00:01:13 +0000842 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000843 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
Jim Inghame41494a2011-04-16 00:01:13 +0000844 if (dynamic_value_sp)
845 child_valobj_sp = dynamic_value_sp;
846 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000847 // Break out early from the switch since we were
848 // able to find the child member
849 break;
850 }
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000851 else if (end && *end == '-')
Enrico Granata9762e102011-07-06 02:13:41 +0000852 {
853 // this is most probably a BitField, let's take a look
854 char *real_end = NULL;
855 long final_index = ::strtol (end+1, &real_end, 0);
Enrico Granata6f302872011-08-19 21:13:46 +0000856 bool expand_bitfield = true;
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000857 if (real_end && *real_end == ']')
Enrico Granata9762e102011-07-06 02:13:41 +0000858 {
859 // if the format given is [high-low], swap range
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000860 if (child_index > final_index)
Enrico Granata9762e102011-07-06 02:13:41 +0000861 {
862 long temp = child_index;
863 child_index = final_index;
864 final_index = temp;
865 }
866
867 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
868 {
869 // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
870 // and extract bits low thru high out of it. reading array items low thru high
871 // would be done by saying ptr[low-high], without a deref * sign
872 Error error;
873 ValueObjectSP temp(valobj_sp->Dereference(error));
874 if (error.Fail())
875 {
876 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
877 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
878 valobj_sp->GetTypeName().AsCString("<invalid type>"),
879 var_expr_path_strm.GetString().c_str());
880 return ValueObjectSP();
881 }
882 valobj_sp = temp;
883 deref = false;
884 }
885 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
886 {
887 // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
888 // (an operation that is equivalent to deref-ing arr)
889 // and extract bits low thru high out of it. reading array items low thru high
890 // would be done by saying arr[low-high], without a deref * sign
891 Error error;
892 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
893 if (error.Fail())
894 {
895 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
896 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
897 valobj_sp->GetTypeName().AsCString("<invalid type>"),
898 var_expr_path_strm.GetString().c_str());
899 return ValueObjectSP();
900 }
901 valobj_sp = temp;
902 deref = false;
903 }
Enrico Granata6f302872011-08-19 21:13:46 +0000904 /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
Enrico Granata9762e102011-07-06 02:13:41 +0000905 {
Enrico Granata6f302872011-08-19 21:13:46 +0000906 child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
907 expand_bitfield = false;
908 if (!child_valobj_sp)
909 {
910 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
911 error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
912 child_index, final_index,
913 valobj_sp->GetTypeName().AsCString("<invalid type>"),
914 var_expr_path_strm.GetString().c_str());
915 }
916 }*/
917
918 if (expand_bitfield)
919 {
920 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
921 if (!child_valobj_sp)
922 {
923 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000924 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
Enrico Granata6f302872011-08-19 21:13:46 +0000925 child_index, final_index,
926 valobj_sp->GetTypeName().AsCString("<invalid type>"),
927 var_expr_path_strm.GetString().c_str());
928 }
Enrico Granata9762e102011-07-06 02:13:41 +0000929 }
930 }
931
932 if (!child_valobj_sp)
933 {
934 // Invalid bitfield range...
935 return ValueObjectSP();
936 }
937
938 // Erase the bitfield member specification '[%i-%i]' where
939 // %i is the index
940 var_path.erase(0, (real_end - var_path.c_str()) + 1);
941 separator_idx = var_path.find_first_of(".-[");
Greg Clayton987c7eb2011-09-17 08:33:22 +0000942 if (use_dynamic != eNoDynamicValues)
Enrico Granata9762e102011-07-06 02:13:41 +0000943 {
944 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
945 if (dynamic_value_sp)
946 child_valobj_sp = dynamic_value_sp;
947 }
948 // Break out early from the switch since we were
949 // able to find the child member
950 break;
951
952 }
953 }
954 else
955 {
956 error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
957 var_expr_path_strm.GetString().c_str(),
958 var_path.c_str());
Greg Claytonc3b61d22010-12-15 05:08:08 +0000959 }
960 return ValueObjectSP();
961
962 default:
963 // Failure...
964 {
Greg Claytonb01000f2011-01-17 03:46:26 +0000965 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Greg Claytonc3b61d22010-12-15 05:08:08 +0000966 error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
967 separator_type,
968 var_expr_path_strm.GetString().c_str(),
969 var_path.c_str());
970
971 return ValueObjectSP();
Greg Clayton427f2902010-12-14 02:59:59 +0000972 }
973 }
Greg Clayton427f2902010-12-14 02:59:59 +0000974
Greg Claytonc3b61d22010-12-15 05:08:08 +0000975 if (child_valobj_sp)
976 valobj_sp = child_valobj_sp;
977
978 if (var_path.empty())
979 break;
980
Greg Clayton427f2902010-12-14 02:59:59 +0000981 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000982 if (valobj_sp)
983 {
984 if (deref)
985 {
Greg Claytonbdcda462010-12-20 20:49:23 +0000986 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
Greg Claytonc3b61d22010-12-15 05:08:08 +0000987 valobj_sp = deref_valobj_sp;
988 }
989 else if (address_of)
990 {
991 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
992 valobj_sp = address_of_valobj_sp;
993 }
994 }
995 return valobj_sp;
Greg Clayton427f2902010-12-14 02:59:59 +0000996 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000997 else
Greg Clayton427f2902010-12-14 02:59:59 +0000998 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000999 error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
1000 name_const_string.GetCString());
Greg Clayton427f2902010-12-14 02:59:59 +00001001 }
Greg Clayton427f2902010-12-14 02:59:59 +00001002 }
1003 }
Greg Claytonc3b61d22010-12-15 05:08:08 +00001004 else
1005 {
1006 error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
1007 }
Greg Clayton427f2902010-12-14 02:59:59 +00001008 return ValueObjectSP();
1009}
Chris Lattner24943d22010-06-08 16:52:24 +00001010
1011bool
1012StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
1013{
1014 if (m_flags.IsClear(GOT_FRAME_BASE))
1015 {
1016 if (m_sc.function)
1017 {
1018 m_frame_base.Clear();
1019 m_frame_base_error.Clear();
1020
1021 m_flags.Set(GOT_FRAME_BASE);
1022 ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
1023 Value expr_value;
Greg Clayton178710c2010-09-14 02:20:48 +00001024 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1025 if (m_sc.function->GetFrameBaseExpression().IsLocationList())
Greg Claytoneea26402010-09-14 23:36:40 +00001026 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget());
Greg Clayton178710c2010-09-14 02:20:48 +00001027
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001028 if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
Chris Lattner24943d22010-06-08 16:52:24 +00001029 {
1030 // We should really have an error if evaluate returns, but in case
1031 // we don't, lets set the error to something at least.
1032 if (m_frame_base_error.Success())
1033 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
1034 }
1035 else
1036 {
1037 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
1038 }
1039 }
1040 else
1041 {
1042 m_frame_base_error.SetErrorString ("No function in symbol context.");
1043 }
1044 }
1045
1046 if (m_frame_base_error.Success())
1047 frame_base = m_frame_base;
1048
1049 if (error_ptr)
1050 *error_ptr = m_frame_base_error;
1051 return m_frame_base_error.Success();
1052}
1053
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001054RegisterContextSP
Chris Lattner24943d22010-06-08 16:52:24 +00001055StackFrame::GetRegisterContext ()
1056{
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001057 if (!m_reg_context_sp)
1058 m_reg_context_sp = m_thread.CreateRegisterContextForFrame (this);
1059 return m_reg_context_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001060}
1061
1062bool
1063StackFrame::HasDebugInformation ()
1064{
Greg Claytonb04e7a82010-08-24 21:05:24 +00001065 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +00001066 return m_sc.line_entry.IsValid();
1067}
1068
Greg Clayton17dae082010-09-02 02:59:18 +00001069
1070ValueObjectSP
Greg Clayton987c7eb2011-09-17 08:33:22 +00001071StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
Chris Lattner24943d22010-06-08 16:52:24 +00001072{
Greg Clayton17dae082010-09-02 02:59:18 +00001073 ValueObjectSP valobj_sp;
1074 VariableList *var_list = GetVariableList (true);
1075 if (var_list)
1076 {
1077 // Make sure the variable is a frame variable
1078 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
1079 const uint32_t num_variables = var_list->GetSize();
1080 if (var_idx < num_variables)
1081 {
1082 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
1083 if (valobj_sp.get() == NULL)
1084 {
1085 if (m_variable_list_value_objects.GetSize() < num_variables)
1086 m_variable_list_value_objects.Resize(num_variables);
Jim Ingham47da8102011-04-22 23:53:53 +00001087 valobj_sp = ValueObjectVariable::Create (this, variable_sp);
Greg Clayton17dae082010-09-02 02:59:18 +00001088 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
1089 }
1090 }
1091 }
Greg Clayton987c7eb2011-09-17 08:33:22 +00001092 if (use_dynamic != eNoDynamicValues && valobj_sp)
Jim Inghame41494a2011-04-16 00:01:13 +00001093 {
Jim Ingham10de7d12011-05-04 03:43:18 +00001094 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
Jim Inghame41494a2011-04-16 00:01:13 +00001095 if (dynamic_sp)
1096 return dynamic_sp;
1097 }
Greg Clayton17dae082010-09-02 02:59:18 +00001098 return valobj_sp;
1099}
1100
1101ValueObjectSP
Greg Clayton987c7eb2011-09-17 08:33:22 +00001102StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
Greg Clayton17dae082010-09-02 02:59:18 +00001103{
1104 // Check to make sure we aren't already tracking this variable?
Jim Inghame41494a2011-04-16 00:01:13 +00001105 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
Greg Clayton17dae082010-09-02 02:59:18 +00001106 if (!valobj_sp)
1107 {
1108 // We aren't already tracking this global
1109 VariableList *var_list = GetVariableList (true);
1110 // If this frame has no variables, create a new list
1111 if (var_list == NULL)
1112 m_variable_list_sp.reset (new VariableList());
1113
1114 // Add the global/static variable to this frame
1115 m_variable_list_sp->AddVariable (variable_sp);
1116
1117 // Now make a value object for it so we can track its changes
Jim Inghame41494a2011-04-16 00:01:13 +00001118 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
Greg Clayton17dae082010-09-02 02:59:18 +00001119 }
1120 return valobj_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001121}
1122
Jim Ingham2154da42010-08-26 20:44:45 +00001123bool
1124StackFrame::IsInlined ()
1125{
Greg Clayton4fb08152010-08-30 18:11:35 +00001126 if (m_sc.block == NULL)
1127 GetSymbolContext (eSymbolContextBlock);
1128 if (m_sc.block)
1129 return m_sc.block->GetContainingInlinedBlock() != NULL;
1130 return false;
Jim Ingham2154da42010-08-26 20:44:45 +00001131}
1132
Chris Lattner24943d22010-06-08 16:52:24 +00001133Target *
1134StackFrame::CalculateTarget ()
1135{
1136 return m_thread.CalculateTarget();
1137}
1138
1139Process *
1140StackFrame::CalculateProcess ()
1141{
1142 return m_thread.CalculateProcess();
1143}
1144
1145Thread *
1146StackFrame::CalculateThread ()
1147{
1148 return &m_thread;
1149}
1150
1151StackFrame *
1152StackFrame::CalculateStackFrame ()
1153{
1154 return this;
1155}
1156
1157
1158void
Greg Claytona830adb2010-10-04 01:05:56 +00001159StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00001160{
Greg Claytona830adb2010-10-04 01:05:56 +00001161 m_thread.CalculateExecutionContext (exe_ctx);
Greg Clayton567e7f32011-09-22 04:58:26 +00001162 exe_ctx.SetFramePtr(this);
Chris Lattner24943d22010-06-08 16:52:24 +00001163}
1164
1165void
Greg Claytona830adb2010-10-04 01:05:56 +00001166StackFrame::DumpUsingSettingsFormat (Stream *strm)
1167{
1168 if (strm == NULL)
1169 return;
1170
1171 GetSymbolContext(eSymbolContextEverything);
1172 ExecutionContext exe_ctx;
1173 CalculateExecutionContext(exe_ctx);
1174 const char *end = NULL;
1175 StreamString s;
1176 const char *frame_format = m_thread.GetProcess().GetTarget().GetDebugger().GetFrameFormat();
1177 if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end))
1178 {
1179 strm->Write(s.GetData(), s.GetSize());
1180 }
1181 else
1182 {
1183 Dump (strm, true, false);
1184 strm->EOL();
1185 }
1186}
1187
1188void
Greg Clayton72b71582010-09-02 21:44:10 +00001189StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
Chris Lattner24943d22010-06-08 16:52:24 +00001190{
1191 if (strm == NULL)
1192 return;
1193
1194 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +00001195 strm->Printf("frame #%u: ", m_frame_index);
Greg Clayton395fc332011-02-15 21:59:32 +00001196 strm->Printf("0x%0*llx ", m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget()));
Greg Claytonb04e7a82010-08-24 21:05:24 +00001197 GetSymbolContext(eSymbolContextEverything);
Greg Clayton33ed1702010-08-24 00:45:41 +00001198 const bool show_module = true;
1199 const bool show_inline = true;
Greg Clayton72b71582010-09-02 21:44:10 +00001200 m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +00001201}
1202
Greg Clayton1d66ef52010-08-27 18:24:16 +00001203void
Greg Clayton4fb08152010-08-30 18:11:35 +00001204StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
Greg Clayton1d66ef52010-08-27 18:24:16 +00001205{
Greg Clayton4fb08152010-08-30 18:11:35 +00001206 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
1207 m_variable_list_sp = prev_frame.m_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +00001208 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
Greg Clayton870a1cd2010-08-27 21:47:54 +00001209 if (!m_disassembly.GetString().empty())
1210 m_disassembly.GetString().swap (m_disassembly.GetString());
Greg Clayton1d66ef52010-08-27 18:24:16 +00001211}
Greg Clayton870a1cd2010-08-27 21:47:54 +00001212
1213
Greg Clayton4fb08152010-08-30 18:11:35 +00001214void
1215StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
1216{
Greg Clayton5205f0b2010-09-03 17:10:42 +00001217 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing
1218 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value
Greg Clayton4fb08152010-08-30 18:11:35 +00001219 assert (&m_thread == &curr_frame.m_thread);
1220 m_frame_index = curr_frame.m_frame_index;
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001221 m_concrete_frame_index = curr_frame.m_concrete_frame_index;
Greg Clayton4fb08152010-08-30 18:11:35 +00001222 m_reg_context_sp = curr_frame.m_reg_context_sp;
1223 m_frame_code_addr = curr_frame.m_frame_code_addr;
1224 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());
1225 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());
1226 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1227 assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
Greg Clayton4fb08152010-08-30 18:11:35 +00001228 m_sc = curr_frame.m_sc;
1229 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1230 m_flags.Set (m_sc.GetResolvedMask());
1231 m_frame_base.Clear();
1232 m_frame_base_error.Clear();
1233}
1234
1235
Greg Clayton5205f0b2010-09-03 17:10:42 +00001236bool
1237StackFrame::HasCachedData () const
1238{
1239 if (m_variable_list_sp.get())
1240 return true;
1241 if (m_variable_list_value_objects.GetSize() > 0)
1242 return true;
1243 if (!m_disassembly.GetString().empty())
1244 return true;
1245 return false;
Jim Inghamccd584d2010-09-23 17:40:12 +00001246}
1247
Greg Clayton987c7eb2011-09-17 08:33:22 +00001248StackFrameSP
Jim Inghamccd584d2010-09-23 17:40:12 +00001249StackFrame::GetSP ()
1250{
Greg Clayton987c7eb2011-09-17 08:33:22 +00001251 // This object contains an instrusive ref count base class so we can
1252 // easily make a shared pointer to this object
1253 return StackFrameSP (this);
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001254}
Greg Claytonabe0fed2011-04-18 08:33:37 +00001255
1256
1257
1258bool
1259StackFrame::GetStatus (Stream& strm,
1260 bool show_frame_info,
1261 bool show_source,
1262 uint32_t source_lines_before,
1263 uint32_t source_lines_after)
1264{
1265 if (show_frame_info)
1266 {
1267 strm.Indent();
1268 DumpUsingSettingsFormat (&strm);
1269 }
1270
1271 if (show_source)
1272 {
1273 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1274
1275 if (m_sc.comp_unit && m_sc.line_entry.IsValid())
1276 {
Greg Claytonff44ab42011-04-23 02:04:55 +00001277 Target &target = GetThread().GetProcess().GetTarget();
Jim Inghamfdf24ef2011-09-08 22:13:49 +00001278 target.GetSourceManager().DisplaySourceLinesWithLineNumbers (
Greg Claytonabe0fed2011-04-18 08:33:37 +00001279 m_sc.line_entry.file,
1280 m_sc.line_entry.line,
1281 3,
1282 3,
1283 "->",
1284 &strm);
1285
1286 }
1287 }
1288 return true;
1289}
1290