blob: 614223d97ff106a80856c7fdafe53b27b5370b97 [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"
Greg Clayton49ce8962012-08-29 21:13:06 +000022#include "lldb/Symbol/CompileUnit.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Symbol/Function.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000024#include "lldb/Symbol/Symbol.h"
25#include "lldb/Symbol/SymbolContextScope.h"
Greg Clayton17dae082010-09-02 02:59:18 +000026#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/ExecutionContext.h"
28#include "lldb/Target/Process.h"
29#include "lldb/Target/RegisterContext.h"
30#include "lldb/Target/Target.h"
31#include "lldb/Target/Thread.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36// The first bits in the flags are reserved for the SymbolContext::Scope bits
37// so we know if we have tried to look up information in our internal symbol
38// context (m_sc) already.
Greg Clayton4fb08152010-08-30 18:11:35 +000039#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
Greg Clayton72b71582010-09-02 21:44:10 +000040#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
Greg Clayton4fb08152010-08-30 18:11:35 +000041#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
42#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
Sean Callanan89363592010-11-01 04:38:59 +000043#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
Chris Lattner24943d22010-06-08 16:52:24 +000044
Greg Clayton289afcb2012-02-18 05:35:26 +000045StackFrame::StackFrame (const ThreadSP &thread_sp,
46 user_id_t frame_idx,
Greg Clayton23b8abb2011-09-26 07:11:27 +000047 user_id_t unwind_frame_index,
Greg Clayton23b8abb2011-09-26 07:11:27 +000048 addr_t cfa,
49 addr_t pc,
50 const SymbolContext *sc_ptr) :
Greg Clayton289afcb2012-02-18 05:35:26 +000051 m_thread_wp (thread_sp),
Greg Clayton33ed1702010-08-24 00:45:41 +000052 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +000053 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +000054 m_reg_context_sp (),
Greg Clayton72b71582010-09-02 21:44:10 +000055 m_id (pc, cfa, NULL),
Greg Clayton3508c382012-02-24 01:59:29 +000056 m_frame_code_addr (pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000057 m_sc (),
58 m_flags (),
59 m_frame_base (),
60 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000061 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000062 m_variable_list_value_objects (),
63 m_disassembly ()
Chris Lattner24943d22010-06-08 16:52:24 +000064{
65 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000066 {
Chris Lattner24943d22010-06-08 16:52:24 +000067 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000068 m_flags.Set(m_sc.GetResolvedMask ());
69 }
Chris Lattner24943d22010-06-08 16:52:24 +000070}
71
Greg Clayton289afcb2012-02-18 05:35:26 +000072StackFrame::StackFrame (const ThreadSP &thread_sp,
73 user_id_t frame_idx,
Greg Clayton23b8abb2011-09-26 07:11:27 +000074 user_id_t unwind_frame_index,
Greg Clayton23b8abb2011-09-26 07:11:27 +000075 const RegisterContextSP &reg_context_sp,
76 addr_t cfa,
77 addr_t pc,
78 const SymbolContext *sc_ptr) :
Greg Clayton289afcb2012-02-18 05:35:26 +000079 m_thread_wp (thread_sp),
Greg Clayton33ed1702010-08-24 00:45:41 +000080 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +000081 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +000082 m_reg_context_sp (reg_context_sp),
Greg Clayton72b71582010-09-02 21:44:10 +000083 m_id (pc, cfa, NULL),
Greg Clayton3508c382012-02-24 01:59:29 +000084 m_frame_code_addr (pc),
Greg Clayton33ed1702010-08-24 00:45:41 +000085 m_sc (),
86 m_flags (),
87 m_frame_base (),
88 m_frame_base_error (),
Chris Lattner24943d22010-06-08 16:52:24 +000089 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +000090 m_variable_list_value_objects (),
91 m_disassembly ()
Chris Lattner24943d22010-06-08 16:52:24 +000092{
93 if (sc_ptr != NULL)
Greg Clayton33ed1702010-08-24 00:45:41 +000094 {
Chris Lattner24943d22010-06-08 16:52:24 +000095 m_sc = *sc_ptr;
Greg Clayton33ed1702010-08-24 00:45:41 +000096 m_flags.Set(m_sc.GetResolvedMask ());
97 }
98
99 if (reg_context_sp && !m_sc.target_sp)
100 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000101 m_sc.target_sp = reg_context_sp->CalculateTarget();
102 if (m_sc.target_sp)
103 m_flags.Set (eSymbolContextTarget);
Greg Clayton33ed1702010-08-24 00:45:41 +0000104 }
105}
106
Greg Clayton289afcb2012-02-18 05:35:26 +0000107StackFrame::StackFrame (const ThreadSP &thread_sp,
108 user_id_t frame_idx,
Greg Clayton23b8abb2011-09-26 07:11:27 +0000109 user_id_t unwind_frame_index,
Greg Clayton23b8abb2011-09-26 07:11:27 +0000110 const RegisterContextSP &reg_context_sp,
111 addr_t cfa,
112 const Address& pc_addr,
113 const SymbolContext *sc_ptr) :
Greg Clayton289afcb2012-02-18 05:35:26 +0000114 m_thread_wp (thread_sp),
Greg Clayton33ed1702010-08-24 00:45:41 +0000115 m_frame_index (frame_idx),
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000116 m_concrete_frame_index (unwind_frame_index),
Greg Clayton33ed1702010-08-24 00:45:41 +0000117 m_reg_context_sp (reg_context_sp),
Greg Claytonf4124de2012-02-21 00:09:25 +0000118 m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
Greg Clayton65124ea2010-08-26 22:05:43 +0000119 m_frame_code_addr (pc_addr),
Greg Clayton33ed1702010-08-24 00:45:41 +0000120 m_sc (),
121 m_flags (),
122 m_frame_base (),
123 m_frame_base_error (),
124 m_variable_list_sp (),
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000125 m_variable_list_value_objects (),
126 m_disassembly ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000127{
128 if (sc_ptr != NULL)
129 {
130 m_sc = *sc_ptr;
131 m_flags.Set(m_sc.GetResolvedMask ());
132 }
133
134 if (m_sc.target_sp.get() == NULL && reg_context_sp)
135 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000136 m_sc.target_sp = reg_context_sp->CalculateTarget();
137 if (m_sc.target_sp)
138 m_flags.Set (eSymbolContextTarget);
Greg Clayton33ed1702010-08-24 00:45:41 +0000139 }
140
Greg Clayton3508c382012-02-24 01:59:29 +0000141 ModuleSP pc_module_sp (pc_addr.GetModule());
142 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
Greg Clayton33ed1702010-08-24 00:45:41 +0000143 {
Greg Clayton3508c382012-02-24 01:59:29 +0000144 if (pc_module_sp)
Greg Clayton33ed1702010-08-24 00:45:41 +0000145 {
Greg Clayton3508c382012-02-24 01:59:29 +0000146 m_sc.module_sp = pc_module_sp;
Greg Clayton33ed1702010-08-24 00:45:41 +0000147 m_flags.Set (eSymbolContextModule);
148 }
Greg Claytone2c5e452010-09-13 04:34:30 +0000149 else
150 {
151 m_sc.module_sp.reset();
152 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000153 }
Chris Lattner24943d22010-06-08 16:52:24 +0000154}
155
156
157//----------------------------------------------------------------------
158// Destructor
159//----------------------------------------------------------------------
160StackFrame::~StackFrame()
161{
162}
163
164StackID&
165StackFrame::GetStackID()
166{
Greg Clayton72b71582010-09-02 21:44:10 +0000167 // Make sure we have resolved the StackID object's symbol context scope if
168 // we already haven't looked it up.
Chris Lattner24943d22010-06-08 16:52:24 +0000169
Greg Clayton4fb08152010-08-30 18:11:35 +0000170 if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
171 {
Greg Clayton5205f0b2010-09-03 17:10:42 +0000172 if (m_id.GetSymbolContextScope ())
Greg Clayton4fb08152010-08-30 18:11:35 +0000173 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000174 // We already have a symbol context scope, we just don't have our
175 // flag bit set.
Greg Clayton4fb08152010-08-30 18:11:35 +0000176 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
177 }
178 else
179 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000180 // Calculate the frame block and use this for the stack ID symbol
181 // context scope if we have one.
182 SymbolContextScope *scope = GetFrameBlock ();
183 if (scope == NULL)
Greg Clayton4fb08152010-08-30 18:11:35 +0000184 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000185 // We don't have a block, so use the symbol
186 if (m_flags.IsClear (eSymbolContextSymbol))
187 GetSymbolContext (eSymbolContextSymbol);
188
189 // It is ok if m_sc.symbol is NULL here
190 scope = m_sc.symbol;
Greg Clayton4fb08152010-08-30 18:11:35 +0000191 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000192 // Set the symbol context scope (the accessor will set the
193 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
194 SetSymbolContextScope (scope);
Greg Clayton4fb08152010-08-30 18:11:35 +0000195 }
Chris Lattner24943d22010-06-08 16:52:24 +0000196 }
197 return m_id;
198}
199
Greg Clayton4fb08152010-08-30 18:11:35 +0000200void
201StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
202{
203 m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
204 m_id.SetSymbolContextScope (symbol_scope);
205}
206
Greg Clayton107e53d2011-07-06 04:07:21 +0000207const Address&
Greg Claytonb04e7a82010-08-24 21:05:24 +0000208StackFrame::GetFrameCodeAddress()
Chris Lattner24943d22010-06-08 16:52:24 +0000209{
Greg Clayton4fb08152010-08-30 18:11:35 +0000210 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
Chris Lattner24943d22010-06-08 16:52:24 +0000211 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000212 m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
Chris Lattner24943d22010-06-08 16:52:24 +0000213
214 // Resolve the PC into a temporary address because if ResolveLoadAddress
215 // fails to resolve the address, it will clear the address object...
Greg Clayton289afcb2012-02-18 05:35:26 +0000216 ThreadSP thread_sp (GetThread());
217 if (thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000218 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000219 TargetSP target_sp (thread_sp->CalculateTarget());
220 if (target_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000221 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000222 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000223 {
Greg Clayton3508c382012-02-24 01:59:29 +0000224 ModuleSP module_sp (m_frame_code_addr.GetModule());
225 if (module_sp)
Greg Clayton289afcb2012-02-18 05:35:26 +0000226 {
Greg Clayton3508c382012-02-24 01:59:29 +0000227 m_sc.module_sp = module_sp;
228 m_flags.Set(eSymbolContextModule);
Greg Clayton289afcb2012-02-18 05:35:26 +0000229 }
Chris Lattner24943d22010-06-08 16:52:24 +0000230 }
231 }
232 }
233 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000234 return m_frame_code_addr;
Chris Lattner24943d22010-06-08 16:52:24 +0000235}
236
237void
238StackFrame::ChangePC (addr_t pc)
239{
Greg Clayton3508c382012-02-24 01:59:29 +0000240 m_frame_code_addr.SetRawAddress(pc);
Chris Lattner24943d22010-06-08 16:52:24 +0000241 m_sc.Clear();
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000242 m_flags.Reset(0);
Greg Clayton289afcb2012-02-18 05:35:26 +0000243 ThreadSP thread_sp (GetThread());
244 if (thread_sp)
245 thread_sp->ClearStackFrames ();
Chris Lattner24943d22010-06-08 16:52:24 +0000246}
247
248const char *
249StackFrame::Disassemble ()
250{
251 if (m_disassembly.GetSize() == 0)
252 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000253 ExecutionContext exe_ctx (shared_from_this());
254 Target *target = exe_ctx.GetTargetPtr();
255 if (target)
256 {
257 Disassembler::Disassemble (target->GetDebugger(),
258 target->GetArchitecture(),
259 NULL,
260 exe_ctx,
261 0,
262 0,
263 0,
264 m_disassembly);
265 }
Chris Lattner24943d22010-06-08 16:52:24 +0000266 if (m_disassembly.GetSize() == 0)
267 return NULL;
268 }
269 return m_disassembly.GetData();
270}
271
Greg Clayton69aa5d92010-09-07 04:20:48 +0000272Block *
273StackFrame::GetFrameBlock ()
274{
275 if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
276 GetSymbolContext (eSymbolContextBlock);
277
278 if (m_sc.block)
279 {
280 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
281 if (inline_block)
282 {
283 // Use the block with the inlined function info
284 // as the frame block we want this frame to have only the variables
285 // for the inlined function and its non-inlined block child blocks.
286 return inline_block;
287 }
288 else
289 {
290 // This block is not contained withing any inlined function blocks
291 // with so we want to use the top most function block.
292 return &m_sc.function->GetBlock (false);
293 }
294 }
295 return NULL;
296}
297
Chris Lattner24943d22010-06-08 16:52:24 +0000298//----------------------------------------------------------------------
299// Get the symbol context if we already haven't done so by resolving the
300// PC address as much as possible. This way when we pass around a
301// StackFrame object, everyone will have as much information as
302// possible and no one will ever have to look things up manually.
303//----------------------------------------------------------------------
304const SymbolContext&
305StackFrame::GetSymbolContext (uint32_t resolve_scope)
306{
307 // Copy our internal symbol context into "sc".
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000308 if ((m_flags.Get() & resolve_scope) != resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000309 {
310 // Resolve our PC to section offset if we haven't alreday done so
311 // and if we don't have a module. The resolved address section will
312 // contain the module to which it belongs
Greg Clayton4fb08152010-08-30 18:11:35 +0000313 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
Greg Claytonb04e7a82010-08-24 21:05:24 +0000314 GetFrameCodeAddress();
Chris Lattner24943d22010-06-08 16:52:24 +0000315
316 // If this is not frame zero, then we need to subtract 1 from the PC
317 // value when doing address lookups since the PC will be on the
318 // instruction following the function call instruction...
319
Greg Claytonb04e7a82010-08-24 21:05:24 +0000320 Address lookup_addr(GetFrameCodeAddress());
Greg Clayton33ed1702010-08-24 00:45:41 +0000321 if (m_frame_index > 0 && lookup_addr.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000322 {
323 addr_t offset = lookup_addr.GetOffset();
324 if (offset > 0)
325 lookup_addr.SetOffset(offset - 1);
326 }
327
Greg Claytonb04e7a82010-08-24 21:05:24 +0000328
329 uint32_t resolved = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000330 if (m_sc.module_sp)
331 {
332 // We have something in our stack frame symbol context, lets check
333 // if we haven't already tried to lookup one of those things. If we
334 // haven't then we will do the query.
Greg Clayton33ed1702010-08-24 00:45:41 +0000335
336 uint32_t actual_resolve_scope = 0;
337
338 if (resolve_scope & eSymbolContextCompUnit)
339 {
340 if (m_flags.IsClear (eSymbolContextCompUnit))
341 {
342 if (m_sc.comp_unit)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000343 resolved |= eSymbolContextCompUnit;
Greg Clayton33ed1702010-08-24 00:45:41 +0000344 else
345 actual_resolve_scope |= eSymbolContextCompUnit;
346 }
347 }
348
349 if (resolve_scope & eSymbolContextFunction)
350 {
351 if (m_flags.IsClear (eSymbolContextFunction))
352 {
353 if (m_sc.function)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000354 resolved |= eSymbolContextFunction;
Greg Clayton33ed1702010-08-24 00:45:41 +0000355 else
356 actual_resolve_scope |= eSymbolContextFunction;
357 }
358 }
359
360 if (resolve_scope & eSymbolContextBlock)
361 {
362 if (m_flags.IsClear (eSymbolContextBlock))
363 {
364 if (m_sc.block)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000365 resolved |= eSymbolContextBlock;
Greg Clayton33ed1702010-08-24 00:45:41 +0000366 else
367 actual_resolve_scope |= eSymbolContextBlock;
368 }
369 }
370
371 if (resolve_scope & eSymbolContextSymbol)
372 {
373 if (m_flags.IsClear (eSymbolContextSymbol))
374 {
375 if (m_sc.symbol)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000376 resolved |= eSymbolContextSymbol;
Greg Clayton33ed1702010-08-24 00:45:41 +0000377 else
378 actual_resolve_scope |= eSymbolContextSymbol;
379 }
380 }
381
382 if (resolve_scope & eSymbolContextLineEntry)
383 {
384 if (m_flags.IsClear (eSymbolContextLineEntry))
385 {
386 if (m_sc.line_entry.IsValid())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000387 resolved |= eSymbolContextLineEntry;
Greg Clayton33ed1702010-08-24 00:45:41 +0000388 else
389 actual_resolve_scope |= eSymbolContextLineEntry;
390 }
391 }
392
393 if (actual_resolve_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000394 {
395 // We might be resolving less information than what is already
396 // in our current symbol context so resolve into a temporary
397 // symbol context "sc" so we don't clear out data we have
398 // already found in "m_sc"
399 SymbolContext sc;
400 // Set flags that indicate what we have tried to resolve
Greg Claytonb04e7a82010-08-24 21:05:24 +0000401 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
Greg Clayton33ed1702010-08-24 00:45:41 +0000402 // Only replace what we didn't already have as we may have
403 // information for an inlined function scope that won't match
404 // what a standard lookup by address would match
Greg Claytonb04e7a82010-08-24 21:05:24 +0000405 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL)
406 m_sc.comp_unit = sc.comp_unit;
407 if ((resolved & eSymbolContextFunction) && m_sc.function == NULL)
408 m_sc.function = sc.function;
409 if ((resolved & eSymbolContextBlock) && m_sc.block == NULL)
410 m_sc.block = sc.block;
411 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
412 m_sc.symbol = sc.symbol;
413 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
414 m_sc.line_entry = sc.line_entry;
415
Chris Lattner24943d22010-06-08 16:52:24 +0000416 }
417 }
418 else
419 {
420 // If we don't have a module, then we can't have the compile unit,
421 // function, block, line entry or symbol, so we can safely call
422 // ResolveSymbolContextForAddress with our symbol context member m_sc.
Greg Clayton289afcb2012-02-18 05:35:26 +0000423 TargetSP target_sp (CalculateTarget());
424 if (target_sp)
425 resolved |= target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000426 }
427
428 // If the target was requested add that:
Greg Clayton289afcb2012-02-18 05:35:26 +0000429 if (!m_sc.target_sp)
Greg Claytonb04e7a82010-08-24 21:05:24 +0000430 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000431 m_sc.target_sp = CalculateTarget();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000432 if (m_sc.target_sp)
433 resolved |= eSymbolContextTarget;
434 }
Chris Lattner24943d22010-06-08 16:52:24 +0000435
436 // Update our internal flags so we remember what we have tried to locate so
437 // we don't have to keep trying when more calls to this function are made.
Greg Claytonb04e7a82010-08-24 21:05:24 +0000438 // We might have dug up more information that was requested (for example
439 // if we were asked to only get the block, we will have gotten the
440 // compile unit, and function) so set any additional bits that we resolved
441 m_flags.Set (resolve_scope | resolved);
Chris Lattner24943d22010-06-08 16:52:24 +0000442 }
443
444 // Return the symbol context with everything that was possible to resolve
445 // resolved.
446 return m_sc;
447}
448
449
450VariableList *
Greg Clayton17dae082010-09-02 02:59:18 +0000451StackFrame::GetVariableList (bool get_file_globals)
Chris Lattner24943d22010-06-08 16:52:24 +0000452{
453 if (m_flags.IsClear(RESOLVED_VARIABLES))
454 {
455 m_flags.Set(RESOLVED_VARIABLES);
456
Greg Clayton69aa5d92010-09-07 04:20:48 +0000457 Block *frame_block = GetFrameBlock();
458
459 if (frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000460 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000461 const bool get_child_variables = true;
462 const bool can_create = true;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000463 const bool stop_if_child_block_is_inlined_function = true;
464 m_variable_list_sp.reset(new VariableList());
465 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 +0000466 }
Sean Callanan89363592010-11-01 04:38:59 +0000467 }
468
469 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
470 get_file_globals)
471 {
472 m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
Greg Clayton17dae082010-09-02 02:59:18 +0000473
Sean Callanan89363592010-11-01 04:38:59 +0000474 if (m_flags.IsClear (eSymbolContextCompUnit))
475 GetSymbolContext (eSymbolContextCompUnit);
476
477 if (m_sc.comp_unit)
Greg Clayton17dae082010-09-02 02:59:18 +0000478 {
Sean Callanan89363592010-11-01 04:38:59 +0000479 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
480 if (m_variable_list_sp)
481 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
482 else
483 m_variable_list_sp = global_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +0000484 }
Chris Lattner24943d22010-06-08 16:52:24 +0000485 }
Sean Callanan89363592010-11-01 04:38:59 +0000486
Chris Lattner24943d22010-06-08 16:52:24 +0000487 return m_variable_list_sp.get();
488}
489
Greg Clayton6e2d2822011-08-02 23:35:43 +0000490VariableListSP
491StackFrame::GetInScopeVariableList (bool get_file_globals)
492{
493 VariableListSP var_list_sp(new VariableList);
494 GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
495
496 if (m_sc.block)
497 {
498 const bool can_create = true;
499 const bool get_parent_variables = true;
500 const bool stop_if_block_is_inlined_function = true;
501 m_sc.block->AppendVariables (can_create,
502 get_parent_variables,
503 stop_if_block_is_inlined_function,
504 var_list_sp.get());
505 }
506
507 if (m_sc.comp_unit)
508 {
509 VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
510 if (global_variable_list_sp)
511 var_list_sp->AddVariables (global_variable_list_sp.get());
512 }
513
514 return var_list_sp;
515}
516
517
Greg Clayton427f2902010-12-14 02:59:59 +0000518ValueObjectSP
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000519StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
Greg Clayton987c7eb2011-09-17 08:33:22 +0000520 DynamicValueType use_dynamic,
Jim Ingham10de7d12011-05-04 03:43:18 +0000521 uint32_t options,
Greg Clayton987c7eb2011-09-17 08:33:22 +0000522 VariableSP &var_sp,
Jim Ingham10de7d12011-05-04 03:43:18 +0000523 Error &error)
Greg Clayton427f2902010-12-14 02:59:59 +0000524{
Greg Claytonc3b61d22010-12-15 05:08:08 +0000525
526 if (var_expr_cstr && var_expr_cstr[0])
Greg Clayton427f2902010-12-14 02:59:59 +0000527 {
Greg Claytonc67efa42011-01-20 19:27:18 +0000528 const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
529 const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
Enrico Granataf6698502011-08-09 01:04:56 +0000530 const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
Enrico Granata13a54a12011-08-19 21:56:10 +0000531 //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
Greg Claytonc3b61d22010-12-15 05:08:08 +0000532 error.Clear();
533 bool deref = false;
534 bool address_of = false;
535 ValueObjectSP valobj_sp;
536 const bool get_file_globals = true;
Greg Clayton6e2d2822011-08-02 23:35:43 +0000537 // When looking up a variable for an expression, we need only consider the
538 // variables that are in scope.
539 VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
540 VariableList *variable_list = var_list_sp.get();
Greg Claytonc3b61d22010-12-15 05:08:08 +0000541
542 if (variable_list)
Greg Clayton427f2902010-12-14 02:59:59 +0000543 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000544 // If first character is a '*', then show pointer contents
545 const char *var_expr = var_expr_cstr;
546 if (var_expr[0] == '*')
Greg Clayton427f2902010-12-14 02:59:59 +0000547 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000548 deref = true;
549 var_expr++; // Skip the '*'
550 }
551 else if (var_expr[0] == '&')
552 {
553 address_of = true;
554 var_expr++; // Skip the '&'
555 }
556
557 std::string var_path (var_expr);
558 size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
559 StreamString var_expr_path_strm;
560
561 ConstString name_const_string;
562 if (separator_idx == std::string::npos)
563 name_const_string.SetCString (var_path.c_str());
564 else
565 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
566
Jim Ingham10de7d12011-05-04 03:43:18 +0000567 var_sp = variable_list->FindVariable(name_const_string);
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000568
569 bool synthetically_added_instance_object = false;
570
571 if (var_sp)
572 {
573 var_path.erase (0, name_const_string.GetLength ());
574 }
575 else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
576 {
577 // Check for direct ivars access which helps us with implicit
578 // access to ivars with the "this->" or "self->"
579 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
580 lldb::LanguageType method_language = eLanguageTypeUnknown;
581 bool is_instance_method = false;
582 ConstString method_object_name;
583 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
584 {
585 if (is_instance_method && method_object_name)
586 {
587 var_sp = variable_list->FindVariable(method_object_name);
588 if (var_sp)
589 {
590 separator_idx = 0;
591 var_path.insert(0, "->");
592 synthetically_added_instance_object = true;
593 }
594 }
595 }
596 }
597
Greg Claytonc3b61d22010-12-15 05:08:08 +0000598 if (var_sp)
599 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000600 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
Jim Inghame41494a2011-04-16 00:01:13 +0000601 if (!valobj_sp)
602 return valobj_sp;
603
Greg Claytonc3b61d22010-12-15 05:08:08 +0000604 // We are dumping at least one child
605 while (separator_idx != std::string::npos)
Greg Clayton427f2902010-12-14 02:59:59 +0000606 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000607 // Calculate the next separator index ahead of time
608 ValueObjectSP child_valobj_sp;
609 const char separator_type = var_path[0];
610 switch (separator_type)
Greg Clayton427f2902010-12-14 02:59:59 +0000611 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000612
613 case '-':
614 if (var_path.size() >= 2 && var_path[1] != '>')
Greg Clayton427f2902010-12-14 02:59:59 +0000615 return ValueObjectSP();
Greg Clayton427f2902010-12-14 02:59:59 +0000616
Greg Claytonc67efa42011-01-20 19:27:18 +0000617 if (no_fragile_ivar)
618 {
619 // Make sure we aren't trying to deref an objective
620 // C ivar if this is not allowed
621 const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (valobj_sp->GetClangType(), NULL, NULL);
622 if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) &&
623 (pointer_type_flags & ClangASTContext::eTypeIsPointer))
624 {
625 // This was an objective C object pointer and
626 // it was requested we skip any fragile ivars
627 // so return nothing here
628 return ValueObjectSP();
629 }
630 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000631 var_path.erase (0, 1); // Remove the '-'
632 // Fall through
633 case '.':
Greg Clayton427f2902010-12-14 02:59:59 +0000634 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000635 const bool expr_is_ptr = var_path[0] == '>';
Greg Clayton427f2902010-12-14 02:59:59 +0000636
Greg Claytonc3b61d22010-12-15 05:08:08 +0000637 var_path.erase (0, 1); // Remove the '.' or '>'
638 separator_idx = var_path.find_first_of(".-[");
639 ConstString child_name;
640 if (separator_idx == std::string::npos)
641 child_name.SetCString (var_path.c_str());
Greg Clayton427f2902010-12-14 02:59:59 +0000642 else
Greg Claytonc3b61d22010-12-15 05:08:08 +0000643 child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
644
645 if (check_ptr_vs_member)
Greg Clayton427f2902010-12-14 02:59:59 +0000646 {
Greg Claytonc3b61d22010-12-15 05:08:08 +0000647 // We either have a pointer type and need to verify
648 // valobj_sp is a pointer, or we have a member of a
649 // class/union/struct being accessed with the . syntax
650 // and need to verify we don't have a pointer.
651 const bool actual_is_ptr = valobj_sp->IsPointerType ();
652
653 if (actual_is_ptr != expr_is_ptr)
654 {
655 // Incorrect use of "." with a pointer, or "->" with
656 // a class/union/struct instance or reference.
Greg Claytonb01000f2011-01-17 03:46:26 +0000657 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Greg Claytonc3b61d22010-12-15 05:08:08 +0000658 if (actual_is_ptr)
659 error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
660 var_expr_path_strm.GetString().c_str(),
661 child_name.GetCString(),
662 var_expr_path_strm.GetString().c_str(),
663 var_path.c_str());
664 else
665 error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
666 var_expr_path_strm.GetString().c_str(),
667 child_name.GetCString(),
668 var_expr_path_strm.GetString().c_str(),
669 var_path.c_str());
670 return ValueObjectSP();
671 }
Greg Clayton427f2902010-12-14 02:59:59 +0000672 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000673 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
Greg Clayton427f2902010-12-14 02:59:59 +0000674 if (!child_valobj_sp)
675 {
Enrico Granata9c57fc02011-08-11 17:08:01 +0000676 if (no_synth_child == false)
Enrico Granatacf09f882012-03-19 22:58:49 +0000677 {
678 child_valobj_sp = valobj_sp->GetSyntheticValue();
679 if (child_valobj_sp)
680 child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
681 }
Enrico Granata9c57fc02011-08-11 17:08:01 +0000682
683 if (no_synth_child || !child_valobj_sp)
Greg Claytonc3b61d22010-12-15 05:08:08 +0000684 {
Enrico Granata9c57fc02011-08-11 17:08:01 +0000685 // No child member with name "child_name"
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000686 if (synthetically_added_instance_object)
Enrico Granata9c57fc02011-08-11 17:08:01 +0000687 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000688 // We added a "this->" or "self->" to the beginning of the expression
689 // and this is the first pointer ivar access, so just return the normal
690 // error
691 error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
692 name_const_string.GetCString());
Enrico Granata9c57fc02011-08-11 17:08:01 +0000693 }
694 else
695 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000696 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
697 if (child_name)
698 {
699 error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
700 child_name.GetCString(),
701 valobj_sp->GetTypeName().AsCString("<invalid type>"),
702 var_expr_path_strm.GetString().c_str());
703 }
704 else
705 {
706 error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
707 var_expr_path_strm.GetString().c_str(),
708 var_expr_cstr);
709 }
Enrico Granata9c57fc02011-08-11 17:08:01 +0000710 }
711 return ValueObjectSP();
Greg Claytonc3b61d22010-12-15 05:08:08 +0000712 }
Greg Clayton427f2902010-12-14 02:59:59 +0000713 }
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000714 synthetically_added_instance_object = false;
Greg Claytonc3b61d22010-12-15 05:08:08 +0000715 // Remove the child name from the path
716 var_path.erase(0, child_name.GetLength());
Greg Clayton987c7eb2011-09-17 08:33:22 +0000717 if (use_dynamic != eNoDynamicValues)
Jim Inghame41494a2011-04-16 00:01:13 +0000718 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000719 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
Jim Inghame41494a2011-04-16 00:01:13 +0000720 if (dynamic_value_sp)
721 child_valobj_sp = dynamic_value_sp;
722 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000723 }
724 break;
Greg Clayton427f2902010-12-14 02:59:59 +0000725
Greg Claytonc3b61d22010-12-15 05:08:08 +0000726 case '[':
727 // Array member access, or treating pointer as an array
728 if (var_path.size() > 2) // Need at least two brackets and a number
729 {
730 char *end = NULL;
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000731 long child_index = ::strtol (&var_path[1], &end, 0);
Enrico Granata9762e102011-07-06 02:13:41 +0000732 if (end && *end == ']'
733 && *(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 +0000734 {
Enrico Granata9762e102011-07-06 02:13:41 +0000735 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
736 {
737 // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
738 // and extract bit low out of it. reading array item low
739 // would be done by saying ptr[low], without a deref * sign
740 Error error;
741 ValueObjectSP temp(valobj_sp->Dereference(error));
742 if (error.Fail())
743 {
744 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
745 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
746 valobj_sp->GetTypeName().AsCString("<invalid type>"),
747 var_expr_path_strm.GetString().c_str());
748 return ValueObjectSP();
749 }
750 valobj_sp = temp;
751 deref = false;
752 }
753 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
754 {
755 // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
756 // (an operation that is equivalent to deref-ing arr)
757 // and extract bit low out of it. reading array item low
758 // would be done by saying arr[low], without a deref * sign
759 Error error;
760 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
761 if (error.Fail())
762 {
763 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
764 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
765 valobj_sp->GetTypeName().AsCString("<invalid type>"),
766 var_expr_path_strm.GetString().c_str());
767 return ValueObjectSP();
768 }
769 valobj_sp = temp;
770 deref = false;
771 }
772
Greg Claytonc3b61d22010-12-15 05:08:08 +0000773 if (valobj_sp->IsPointerType ())
774 {
Sean Callanan6e12c7a2012-03-08 02:39:03 +0000775 bool is_objc_pointer = true;
776
777 if (ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(), valobj_sp->GetClangType()) != eLanguageTypeObjC)
778 is_objc_pointer = false;
779 else if (!ClangASTContext::IsPointerType(valobj_sp->GetClangType()))
780 is_objc_pointer = false;
781
782 if (no_synth_child && is_objc_pointer)
Greg Claytonc3b61d22010-12-15 05:08:08 +0000783 {
Sean Callanan6e12c7a2012-03-08 02:39:03 +0000784 error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
785 valobj_sp->GetTypeName().AsCString("<invalid type>"),
786 var_expr_path_strm.GetString().c_str());
787
788 return ValueObjectSP();
789 }
790 else if (is_objc_pointer)
791 {
Enrico Granataf6698502011-08-09 01:04:56 +0000792 // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
Enrico Granatacf09f882012-03-19 22:58:49 +0000793 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
Enrico Granataf6698502011-08-09 01:04:56 +0000794 if (synthetic.get() == NULL /* no synthetic */
795 || synthetic == valobj_sp) /* synthetic is the same as the original object */
796 {
797 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
798 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
799 valobj_sp->GetTypeName().AsCString("<invalid type>"),
800 var_expr_path_strm.GetString().c_str());
801 }
802 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
803 {
804 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000805 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000806 child_index,
807 valobj_sp->GetTypeName().AsCString("<invalid type>"),
808 var_expr_path_strm.GetString().c_str());
809 }
810 else
811 {
812 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
813 if (!child_valobj_sp)
814 {
815 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000816 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000817 child_index,
818 valobj_sp->GetTypeName().AsCString("<invalid type>"),
819 var_expr_path_strm.GetString().c_str());
820 }
821 }
822 }
823 else
824 {
825 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
826 if (!child_valobj_sp)
827 {
828 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000829 error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000830 child_index,
831 valobj_sp->GetTypeName().AsCString("<invalid type>"),
832 var_expr_path_strm.GetString().c_str());
833 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000834 }
835 }
836 else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL))
837 {
Jim Inghame41494a2011-04-16 00:01:13 +0000838 // Pass false to dynamic_value here so we can tell the difference between
839 // no dynamic value and no member of this type...
Greg Claytonc3b61d22010-12-15 05:08:08 +0000840 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
841 if (!child_valobj_sp)
842 {
Greg Claytonb01000f2011-01-17 03:46:26 +0000843 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000844 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Greg Claytonc3b61d22010-12-15 05:08:08 +0000845 child_index,
846 valobj_sp->GetTypeName().AsCString("<invalid type>"),
847 var_expr_path_strm.GetString().c_str());
848 }
849 }
Enrico Granata9762e102011-07-06 02:13:41 +0000850 else if (ClangASTContext::IsScalarType(valobj_sp->GetClangType()))
851 {
852 // this is a bitfield asking to display just one bit
853 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
854 if (!child_valobj_sp)
855 {
856 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000857 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
Enrico Granata9762e102011-07-06 02:13:41 +0000858 child_index, child_index,
859 valobj_sp->GetTypeName().AsCString("<invalid type>"),
860 var_expr_path_strm.GetString().c_str());
861 }
862 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000863 else
864 {
Enrico Granatacf09f882012-03-19 22:58:49 +0000865 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
Enrico Granataf6698502011-08-09 01:04:56 +0000866 if (no_synth_child /* synthetic is forbidden */ ||
867 synthetic.get() == NULL /* no synthetic */
868 || synthetic == valobj_sp) /* synthetic is the same as the original object */
869 {
870 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
871 error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
872 valobj_sp->GetTypeName().AsCString("<invalid type>"),
873 var_expr_path_strm.GetString().c_str());
874 }
875 else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
876 {
877 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000878 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000879 child_index,
880 valobj_sp->GetTypeName().AsCString("<invalid type>"),
881 var_expr_path_strm.GetString().c_str());
882 }
883 else
884 {
885 child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
886 if (!child_valobj_sp)
887 {
888 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000889 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
Enrico Granataf6698502011-08-09 01:04:56 +0000890 child_index,
891 valobj_sp->GetTypeName().AsCString("<invalid type>"),
892 var_expr_path_strm.GetString().c_str());
893 }
894 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000895 }
896
897 if (!child_valobj_sp)
898 {
899 // Invalid array index...
900 return ValueObjectSP();
901 }
902
903 // Erase the array member specification '[%i]' where
904 // %i is the array index
905 var_path.erase(0, (end - var_path.c_str()) + 1);
906 separator_idx = var_path.find_first_of(".-[");
Greg Clayton987c7eb2011-09-17 08:33:22 +0000907 if (use_dynamic != eNoDynamicValues)
Jim Inghame41494a2011-04-16 00:01:13 +0000908 {
Jim Ingham10de7d12011-05-04 03:43:18 +0000909 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
Jim Inghame41494a2011-04-16 00:01:13 +0000910 if (dynamic_value_sp)
911 child_valobj_sp = dynamic_value_sp;
912 }
Greg Claytonc3b61d22010-12-15 05:08:08 +0000913 // Break out early from the switch since we were
914 // able to find the child member
915 break;
916 }
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000917 else if (end && *end == '-')
Enrico Granata9762e102011-07-06 02:13:41 +0000918 {
919 // this is most probably a BitField, let's take a look
920 char *real_end = NULL;
921 long final_index = ::strtol (end+1, &real_end, 0);
Enrico Granata6f302872011-08-19 21:13:46 +0000922 bool expand_bitfield = true;
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000923 if (real_end && *real_end == ']')
Enrico Granata9762e102011-07-06 02:13:41 +0000924 {
925 // if the format given is [high-low], swap range
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000926 if (child_index > final_index)
Enrico Granata9762e102011-07-06 02:13:41 +0000927 {
928 long temp = child_index;
929 child_index = final_index;
930 final_index = temp;
931 }
932
933 if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
934 {
935 // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
936 // and extract bits low thru high out of it. reading array items low thru high
937 // would be done by saying ptr[low-high], without a deref * sign
938 Error error;
939 ValueObjectSP temp(valobj_sp->Dereference(error));
940 if (error.Fail())
941 {
942 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
943 error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
944 valobj_sp->GetTypeName().AsCString("<invalid type>"),
945 var_expr_path_strm.GetString().c_str());
946 return ValueObjectSP();
947 }
948 valobj_sp = temp;
949 deref = false;
950 }
951 else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
952 {
953 // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
954 // (an operation that is equivalent to deref-ing arr)
955 // and extract bits low thru high out of it. reading array items low thru high
956 // would be done by saying arr[low-high], without a deref * sign
957 Error error;
958 ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
959 if (error.Fail())
960 {
961 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
962 error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
963 valobj_sp->GetTypeName().AsCString("<invalid type>"),
964 var_expr_path_strm.GetString().c_str());
965 return ValueObjectSP();
966 }
967 valobj_sp = temp;
968 deref = false;
969 }
Enrico Granata6f302872011-08-19 21:13:46 +0000970 /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
Enrico Granata9762e102011-07-06 02:13:41 +0000971 {
Enrico Granata6f302872011-08-19 21:13:46 +0000972 child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
973 expand_bitfield = false;
974 if (!child_valobj_sp)
975 {
976 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
977 error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
978 child_index, final_index,
979 valobj_sp->GetTypeName().AsCString("<invalid type>"),
980 var_expr_path_strm.GetString().c_str());
981 }
982 }*/
983
984 if (expand_bitfield)
985 {
986 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
987 if (!child_valobj_sp)
988 {
989 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Jason Molenda95b7b432011-09-20 00:26:08 +0000990 error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
Enrico Granata6f302872011-08-19 21:13:46 +0000991 child_index, final_index,
992 valobj_sp->GetTypeName().AsCString("<invalid type>"),
993 var_expr_path_strm.GetString().c_str());
994 }
Enrico Granata9762e102011-07-06 02:13:41 +0000995 }
996 }
997
998 if (!child_valobj_sp)
999 {
1000 // Invalid bitfield range...
1001 return ValueObjectSP();
1002 }
1003
1004 // Erase the bitfield member specification '[%i-%i]' where
1005 // %i is the index
1006 var_path.erase(0, (real_end - var_path.c_str()) + 1);
1007 separator_idx = var_path.find_first_of(".-[");
Greg Clayton987c7eb2011-09-17 08:33:22 +00001008 if (use_dynamic != eNoDynamicValues)
Enrico Granata9762e102011-07-06 02:13:41 +00001009 {
1010 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
1011 if (dynamic_value_sp)
1012 child_valobj_sp = dynamic_value_sp;
1013 }
1014 // Break out early from the switch since we were
1015 // able to find the child member
1016 break;
1017
1018 }
1019 }
1020 else
1021 {
1022 error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
1023 var_expr_path_strm.GetString().c_str(),
1024 var_path.c_str());
Greg Claytonc3b61d22010-12-15 05:08:08 +00001025 }
1026 return ValueObjectSP();
1027
1028 default:
1029 // Failure...
1030 {
Greg Claytonb01000f2011-01-17 03:46:26 +00001031 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
Greg Claytonc3b61d22010-12-15 05:08:08 +00001032 error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
1033 separator_type,
1034 var_expr_path_strm.GetString().c_str(),
1035 var_path.c_str());
1036
1037 return ValueObjectSP();
Greg Clayton427f2902010-12-14 02:59:59 +00001038 }
1039 }
Greg Clayton427f2902010-12-14 02:59:59 +00001040
Greg Claytonc3b61d22010-12-15 05:08:08 +00001041 if (child_valobj_sp)
1042 valobj_sp = child_valobj_sp;
1043
1044 if (var_path.empty())
1045 break;
1046
Greg Clayton427f2902010-12-14 02:59:59 +00001047 }
Greg Claytonc3b61d22010-12-15 05:08:08 +00001048 if (valobj_sp)
1049 {
1050 if (deref)
1051 {
Greg Claytonbdcda462010-12-20 20:49:23 +00001052 ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
Greg Claytonc3b61d22010-12-15 05:08:08 +00001053 valobj_sp = deref_valobj_sp;
1054 }
1055 else if (address_of)
1056 {
1057 ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
1058 valobj_sp = address_of_valobj_sp;
1059 }
1060 }
1061 return valobj_sp;
Greg Clayton427f2902010-12-14 02:59:59 +00001062 }
Greg Claytonc3b61d22010-12-15 05:08:08 +00001063 else
Greg Clayton427f2902010-12-14 02:59:59 +00001064 {
Jim Ingham10de7d12011-05-04 03:43:18 +00001065 error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
1066 name_const_string.GetCString());
Greg Clayton427f2902010-12-14 02:59:59 +00001067 }
Greg Clayton427f2902010-12-14 02:59:59 +00001068 }
1069 }
Greg Claytonc3b61d22010-12-15 05:08:08 +00001070 else
1071 {
1072 error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
1073 }
Greg Clayton427f2902010-12-14 02:59:59 +00001074 return ValueObjectSP();
1075}
Chris Lattner24943d22010-06-08 16:52:24 +00001076
1077bool
1078StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
1079{
1080 if (m_flags.IsClear(GOT_FRAME_BASE))
1081 {
1082 if (m_sc.function)
1083 {
1084 m_frame_base.Clear();
1085 m_frame_base_error.Clear();
1086
1087 m_flags.Set(GOT_FRAME_BASE);
Greg Clayton289afcb2012-02-18 05:35:26 +00001088 ExecutionContext exe_ctx (shared_from_this());
Chris Lattner24943d22010-06-08 16:52:24 +00001089 Value expr_value;
Greg Clayton178710c2010-09-14 02:20:48 +00001090 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1091 if (m_sc.function->GetFrameBaseExpression().IsLocationList())
Greg Clayton289afcb2012-02-18 05:35:26 +00001092 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
Greg Clayton178710c2010-09-14 02:20:48 +00001093
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001094 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 +00001095 {
1096 // We should really have an error if evaluate returns, but in case
1097 // we don't, lets set the error to something at least.
1098 if (m_frame_base_error.Success())
1099 m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
1100 }
1101 else
1102 {
1103 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
1104 }
1105 }
1106 else
1107 {
1108 m_frame_base_error.SetErrorString ("No function in symbol context.");
1109 }
1110 }
1111
1112 if (m_frame_base_error.Success())
1113 frame_base = m_frame_base;
1114
1115 if (error_ptr)
1116 *error_ptr = m_frame_base_error;
1117 return m_frame_base_error.Success();
1118}
1119
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001120RegisterContextSP
Chris Lattner24943d22010-06-08 16:52:24 +00001121StackFrame::GetRegisterContext ()
1122{
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001123 if (!m_reg_context_sp)
Greg Clayton289afcb2012-02-18 05:35:26 +00001124 {
1125 ThreadSP thread_sp (GetThread());
1126 if (thread_sp)
1127 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
1128 }
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001129 return m_reg_context_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001130}
1131
1132bool
1133StackFrame::HasDebugInformation ()
1134{
Greg Claytonb04e7a82010-08-24 21:05:24 +00001135 GetSymbolContext (eSymbolContextLineEntry);
Chris Lattner24943d22010-06-08 16:52:24 +00001136 return m_sc.line_entry.IsValid();
1137}
1138
Greg Clayton17dae082010-09-02 02:59:18 +00001139
1140ValueObjectSP
Greg Clayton987c7eb2011-09-17 08:33:22 +00001141StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
Chris Lattner24943d22010-06-08 16:52:24 +00001142{
Greg Clayton17dae082010-09-02 02:59:18 +00001143 ValueObjectSP valobj_sp;
1144 VariableList *var_list = GetVariableList (true);
1145 if (var_list)
1146 {
1147 // Make sure the variable is a frame variable
1148 const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
1149 const uint32_t num_variables = var_list->GetSize();
1150 if (var_idx < num_variables)
1151 {
1152 valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
1153 if (valobj_sp.get() == NULL)
1154 {
1155 if (m_variable_list_value_objects.GetSize() < num_variables)
1156 m_variable_list_value_objects.Resize(num_variables);
Jim Ingham47da8102011-04-22 23:53:53 +00001157 valobj_sp = ValueObjectVariable::Create (this, variable_sp);
Greg Clayton17dae082010-09-02 02:59:18 +00001158 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
1159 }
1160 }
1161 }
Greg Clayton987c7eb2011-09-17 08:33:22 +00001162 if (use_dynamic != eNoDynamicValues && valobj_sp)
Jim Inghame41494a2011-04-16 00:01:13 +00001163 {
Jim Ingham10de7d12011-05-04 03:43:18 +00001164 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
Jim Inghame41494a2011-04-16 00:01:13 +00001165 if (dynamic_sp)
1166 return dynamic_sp;
1167 }
Greg Clayton17dae082010-09-02 02:59:18 +00001168 return valobj_sp;
1169}
1170
1171ValueObjectSP
Greg Clayton987c7eb2011-09-17 08:33:22 +00001172StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
Greg Clayton17dae082010-09-02 02:59:18 +00001173{
1174 // Check to make sure we aren't already tracking this variable?
Jim Inghame41494a2011-04-16 00:01:13 +00001175 ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
Greg Clayton17dae082010-09-02 02:59:18 +00001176 if (!valobj_sp)
1177 {
1178 // We aren't already tracking this global
1179 VariableList *var_list = GetVariableList (true);
1180 // If this frame has no variables, create a new list
1181 if (var_list == NULL)
1182 m_variable_list_sp.reset (new VariableList());
1183
1184 // Add the global/static variable to this frame
1185 m_variable_list_sp->AddVariable (variable_sp);
1186
1187 // Now make a value object for it so we can track its changes
Jim Inghame41494a2011-04-16 00:01:13 +00001188 valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
Greg Clayton17dae082010-09-02 02:59:18 +00001189 }
1190 return valobj_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001191}
1192
Jim Ingham2154da42010-08-26 20:44:45 +00001193bool
1194StackFrame::IsInlined ()
1195{
Greg Clayton4fb08152010-08-30 18:11:35 +00001196 if (m_sc.block == NULL)
1197 GetSymbolContext (eSymbolContextBlock);
1198 if (m_sc.block)
1199 return m_sc.block->GetContainingInlinedBlock() != NULL;
1200 return false;
Jim Ingham2154da42010-08-26 20:44:45 +00001201}
1202
Greg Clayton289afcb2012-02-18 05:35:26 +00001203TargetSP
Chris Lattner24943d22010-06-08 16:52:24 +00001204StackFrame::CalculateTarget ()
1205{
Greg Clayton289afcb2012-02-18 05:35:26 +00001206 TargetSP target_sp;
1207 ThreadSP thread_sp(GetThread());
1208 if (thread_sp)
1209 {
1210 ProcessSP process_sp (thread_sp->CalculateProcess());
1211 if (process_sp)
1212 target_sp = process_sp->CalculateTarget();
1213 }
1214 return target_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001215}
1216
Greg Clayton289afcb2012-02-18 05:35:26 +00001217ProcessSP
Chris Lattner24943d22010-06-08 16:52:24 +00001218StackFrame::CalculateProcess ()
1219{
Greg Clayton289afcb2012-02-18 05:35:26 +00001220 ProcessSP process_sp;
1221 ThreadSP thread_sp(GetThread());
1222 if (thread_sp)
1223 process_sp = thread_sp->CalculateProcess();
1224 return process_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001225}
1226
Greg Clayton289afcb2012-02-18 05:35:26 +00001227ThreadSP
Chris Lattner24943d22010-06-08 16:52:24 +00001228StackFrame::CalculateThread ()
1229{
Greg Clayton289afcb2012-02-18 05:35:26 +00001230 return GetThread();
Chris Lattner24943d22010-06-08 16:52:24 +00001231}
1232
Greg Clayton289afcb2012-02-18 05:35:26 +00001233StackFrameSP
Chris Lattner24943d22010-06-08 16:52:24 +00001234StackFrame::CalculateStackFrame ()
1235{
Greg Clayton289afcb2012-02-18 05:35:26 +00001236 return shared_from_this();
Chris Lattner24943d22010-06-08 16:52:24 +00001237}
1238
1239
1240void
Greg Claytona830adb2010-10-04 01:05:56 +00001241StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00001242{
Greg Clayton289afcb2012-02-18 05:35:26 +00001243 exe_ctx.SetContext (shared_from_this());
Chris Lattner24943d22010-06-08 16:52:24 +00001244}
1245
1246void
Greg Claytona830adb2010-10-04 01:05:56 +00001247StackFrame::DumpUsingSettingsFormat (Stream *strm)
1248{
1249 if (strm == NULL)
1250 return;
1251
1252 GetSymbolContext(eSymbolContextEverything);
Greg Clayton289afcb2012-02-18 05:35:26 +00001253 ExecutionContext exe_ctx (shared_from_this());
Greg Claytona830adb2010-10-04 01:05:56 +00001254 const char *end = NULL;
1255 StreamString s;
Greg Clayton289afcb2012-02-18 05:35:26 +00001256 const char *frame_format = NULL;
1257 Target *target = exe_ctx.GetTargetPtr();
1258 if (target)
1259 frame_format = target->GetDebugger().GetFrameFormat();
Greg Claytona830adb2010-10-04 01:05:56 +00001260 if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end))
1261 {
1262 strm->Write(s.GetData(), s.GetSize());
1263 }
1264 else
1265 {
1266 Dump (strm, true, false);
1267 strm->EOL();
1268 }
1269}
1270
1271void
Greg Clayton72b71582010-09-02 21:44:10 +00001272StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
Chris Lattner24943d22010-06-08 16:52:24 +00001273{
1274 if (strm == NULL)
1275 return;
1276
1277 if (show_frame_index)
Greg Clayton33ed1702010-08-24 00:45:41 +00001278 strm->Printf("frame #%u: ", m_frame_index);
Greg Clayton289afcb2012-02-18 05:35:26 +00001279 ExecutionContext exe_ctx (shared_from_this());
1280 Target *target = exe_ctx.GetTargetPtr();
1281 strm->Printf("0x%0*llx ",
1282 target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
1283 GetFrameCodeAddress().GetLoadAddress(target));
Greg Claytonb04e7a82010-08-24 21:05:24 +00001284 GetSymbolContext(eSymbolContextEverything);
Greg Clayton33ed1702010-08-24 00:45:41 +00001285 const bool show_module = true;
1286 const bool show_inline = true;
Greg Clayton289afcb2012-02-18 05:35:26 +00001287 m_sc.DumpStopContext (strm,
1288 exe_ctx.GetBestExecutionContextScope(),
1289 GetFrameCodeAddress(),
1290 show_fullpaths,
1291 show_module,
1292 show_inline);
Chris Lattner24943d22010-06-08 16:52:24 +00001293}
1294
Greg Clayton1d66ef52010-08-27 18:24:16 +00001295void
Greg Clayton4fb08152010-08-30 18:11:35 +00001296StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
Greg Clayton1d66ef52010-08-27 18:24:16 +00001297{
Greg Clayton4fb08152010-08-30 18:11:35 +00001298 assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing
1299 m_variable_list_sp = prev_frame.m_variable_list_sp;
Greg Clayton17dae082010-09-02 02:59:18 +00001300 m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
Greg Clayton870a1cd2010-08-27 21:47:54 +00001301 if (!m_disassembly.GetString().empty())
1302 m_disassembly.GetString().swap (m_disassembly.GetString());
Greg Clayton1d66ef52010-08-27 18:24:16 +00001303}
Greg Clayton870a1cd2010-08-27 21:47:54 +00001304
1305
Greg Clayton4fb08152010-08-30 18:11:35 +00001306void
1307StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
1308{
Greg Clayton5205f0b2010-09-03 17:10:42 +00001309 assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing
1310 m_id.SetPC (curr_frame.m_id.GetPC()); // Update the Stack ID PC value
Greg Clayton289afcb2012-02-18 05:35:26 +00001311 assert (GetThread() == curr_frame.GetThread());
Greg Clayton4fb08152010-08-30 18:11:35 +00001312 m_frame_index = curr_frame.m_frame_index;
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001313 m_concrete_frame_index = curr_frame.m_concrete_frame_index;
Greg Clayton4fb08152010-08-30 18:11:35 +00001314 m_reg_context_sp = curr_frame.m_reg_context_sp;
1315 m_frame_code_addr = curr_frame.m_frame_code_addr;
1316 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());
1317 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());
1318 assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1319 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 +00001320 m_sc = curr_frame.m_sc;
1321 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1322 m_flags.Set (m_sc.GetResolvedMask());
1323 m_frame_base.Clear();
1324 m_frame_base_error.Clear();
1325}
1326
1327
Greg Clayton5205f0b2010-09-03 17:10:42 +00001328bool
1329StackFrame::HasCachedData () const
1330{
1331 if (m_variable_list_sp.get())
1332 return true;
1333 if (m_variable_list_value_objects.GetSize() > 0)
1334 return true;
1335 if (!m_disassembly.GetString().empty())
1336 return true;
1337 return false;
Jim Inghamccd584d2010-09-23 17:40:12 +00001338}
1339
Greg Claytonabe0fed2011-04-18 08:33:37 +00001340bool
1341StackFrame::GetStatus (Stream& strm,
1342 bool show_frame_info,
Greg Claytona7d3dc72012-07-11 20:33:48 +00001343 bool show_source)
Greg Claytonabe0fed2011-04-18 08:33:37 +00001344{
Greg Claytona7d3dc72012-07-11 20:33:48 +00001345
Greg Claytonabe0fed2011-04-18 08:33:37 +00001346 if (show_frame_info)
1347 {
1348 strm.Indent();
1349 DumpUsingSettingsFormat (&strm);
1350 }
1351
1352 if (show_source)
1353 {
Greg Clayton289afcb2012-02-18 05:35:26 +00001354 ExecutionContext exe_ctx (shared_from_this());
Greg Claytonbe9875d2011-11-21 21:44:34 +00001355 bool have_source = false;
Greg Clayton73844aa2012-08-22 17:17:09 +00001356 Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
Greg Clayton289afcb2012-02-18 05:35:26 +00001357 Target *target = exe_ctx.GetTargetPtr();
Greg Claytona7d3dc72012-07-11 20:33:48 +00001358 if (target)
Greg Claytonabe0fed2011-04-18 08:33:37 +00001359 {
Greg Claytona7d3dc72012-07-11 20:33:48 +00001360 Debugger &debugger = target->GetDebugger();
1361 const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
1362 const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
1363 disasm_display = debugger.GetStopDisassemblyDisplay ();
Greg Claytonbe9875d2011-11-21 21:44:34 +00001364
Greg Claytona7d3dc72012-07-11 20:33:48 +00001365 if (source_lines_before > 0 || source_lines_after > 0)
Greg Claytonbe9875d2011-11-21 21:44:34 +00001366 {
Greg Claytona7d3dc72012-07-11 20:33:48 +00001367 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1368
1369 if (m_sc.comp_unit && m_sc.line_entry.IsValid())
Greg Claytonbe9875d2011-11-21 21:44:34 +00001370 {
Greg Claytona7d3dc72012-07-11 20:33:48 +00001371 if (target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
1372 m_sc.line_entry.line,
1373 source_lines_before,
1374 source_lines_after,
1375 "->",
1376 &strm))
1377 {
1378 have_source = true;
1379 }
Greg Claytonbe9875d2011-11-21 21:44:34 +00001380 }
1381 }
Greg Claytona7d3dc72012-07-11 20:33:48 +00001382 switch (disasm_display)
1383 {
Greg Clayton73844aa2012-08-22 17:17:09 +00001384 case Debugger::eStopDisassemblyTypeNever:
Greg Claytonbe9875d2011-11-21 21:44:34 +00001385 break;
Greg Claytona7d3dc72012-07-11 20:33:48 +00001386
Greg Clayton73844aa2012-08-22 17:17:09 +00001387 case Debugger::eStopDisassemblyTypeNoSource:
Greg Claytona7d3dc72012-07-11 20:33:48 +00001388 if (have_source)
1389 break;
1390 // Fall through to next case
Greg Clayton73844aa2012-08-22 17:17:09 +00001391 case Debugger::eStopDisassemblyTypeAlways:
Greg Claytona7d3dc72012-07-11 20:33:48 +00001392 if (target)
Greg Claytonbe9875d2011-11-21 21:44:34 +00001393 {
Greg Claytona7d3dc72012-07-11 20:33:48 +00001394 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
1395 if (disasm_lines > 0)
1396 {
1397 const ArchSpec &target_arch = target->GetArchitecture();
1398 AddressRange pc_range;
1399 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1400 pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
1401 Disassembler::Disassemble (target->GetDebugger(),
1402 target_arch,
1403 NULL,
1404 exe_ctx,
1405 pc_range,
1406 disasm_lines,
1407 0,
1408 Disassembler::eOptionMarkPCAddress,
1409 strm);
1410 }
Greg Claytonbe9875d2011-11-21 21:44:34 +00001411 }
Greg Claytona7d3dc72012-07-11 20:33:48 +00001412 break;
Greg Claytonbe9875d2011-11-21 21:44:34 +00001413 }
Greg Claytonabe0fed2011-04-18 08:33:37 +00001414 }
1415 }
1416 return true;
1417}
1418