blob: 6676279dabf2c6bdad60aa728a6d1c2688ca5dca [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Block.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/Symbol/Block.h"
11#include "lldb/Symbol/Function.h"
12#include "lldb/Core/Module.h"
13#include "lldb/Core/Section.h"
Sean Callananc617a4c2011-08-05 23:43:37 +000014#include "lldb/Symbol/SymbolFile.h"
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Symbol/SymbolVendor.h"
16#include "lldb/Symbol/VariableList.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
Greg Clayton75ccf502010-08-21 02:22:51 +000021Block::Block(lldb::user_id_t uid) :
Chris Lattner24943d22010-06-08 16:52:24 +000022 UserID(uid),
Greg Clayton75ccf502010-08-21 02:22:51 +000023 m_parent_scope (NULL),
24 m_sibling (NULL),
25 m_children (),
26 m_ranges (),
27 m_inlineInfoSP (),
Greg Claytonb04e7a82010-08-24 21:05:24 +000028 m_variable_list_sp (),
Greg Clayton75ccf502010-08-21 02:22:51 +000029 m_parsed_block_info (false),
30 m_parsed_block_variables (false),
31 m_parsed_child_blocks (false)
Chris Lattner24943d22010-06-08 16:52:24 +000032{
33}
34
Chris Lattner24943d22010-06-08 16:52:24 +000035Block::~Block ()
36{
37}
38
39void
Greg Claytoneea26402010-09-14 23:36:40 +000040Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +000041{
Greg Claytonc67b7d12010-09-10 01:30:46 +000042 *s << "id = " << ((const UserID&)*this);
43
Greg Clayton12bec712010-06-28 21:30:43 +000044 size_t num_ranges = m_ranges.size();
45 if (num_ranges)
46 {
47
48 addr_t base_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneea26402010-09-14 23:36:40 +000049 if (target)
50 base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
Greg Clayton12bec712010-06-28 21:30:43 +000051 if (base_addr == LLDB_INVALID_ADDRESS)
Greg Clayton75ccf502010-08-21 02:22:51 +000052 base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
Greg Clayton12bec712010-06-28 21:30:43 +000053
Greg Claytonc67b7d12010-09-10 01:30:46 +000054 s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
Greg Clayton12bec712010-06-28 21:30:43 +000055 std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
56 for (pos = m_ranges.begin(); pos != end; ++pos)
57 pos->Dump(s, base_addr, 4);
58 }
Greg Clayton12bec712010-06-28 21:30:43 +000059
60 if (m_inlineInfoSP.get() != NULL)
Greg Clayton1924e242010-09-15 05:51:24 +000061 {
62 bool show_fullpaths = (level == eDescriptionLevelVerbose);
63 m_inlineInfoSP->Dump(s, show_fullpaths);
64 }
Greg Clayton12bec712010-06-28 21:30:43 +000065}
66
67void
Chris Lattner24943d22010-06-08 16:52:24 +000068Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
69{
70 if (depth < 0)
71 {
Greg Clayton75ccf502010-08-21 02:22:51 +000072 Block *parent = GetParent();
73 if (parent)
74 {
75 // We have a depth that is less than zero, print our parent blocks
76 // first
77 parent->Dump(s, base_addr, depth + 1, show_context);
78 }
Chris Lattner24943d22010-06-08 16:52:24 +000079 }
80
Jason Molenda7e5fa7f2011-09-20 21:44:10 +000081 s->Printf("%p: ", this);
Chris Lattner24943d22010-06-08 16:52:24 +000082 s->Indent();
83 *s << "Block" << ((const UserID&)*this);
Greg Clayton12bec712010-06-28 21:30:43 +000084 const Block* parent_block = GetParent();
85 if (parent_block)
Chris Lattner24943d22010-06-08 16:52:24 +000086 {
Greg Clayton12bec712010-06-28 21:30:43 +000087 s->Printf(", parent = {0x%8.8x}", parent_block->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +000088 }
89 if (m_inlineInfoSP.get() != NULL)
Greg Clayton1924e242010-09-15 05:51:24 +000090 {
91 bool show_fullpaths = false;
92 m_inlineInfoSP->Dump(s, show_fullpaths);
93 }
Chris Lattner24943d22010-06-08 16:52:24 +000094
95 if (!m_ranges.empty())
96 {
97 *s << ", ranges =";
98 std::vector<VMRange>::const_iterator pos;
99 std::vector<VMRange>::const_iterator end = m_ranges.end();
100 for (pos = m_ranges.begin(); pos != end; ++pos)
101 {
102 if (parent_block != NULL && parent_block->Contains(*pos) == false)
103 *s << '!';
104 else
105 *s << ' ';
106 pos->Dump(s, base_addr);
107 }
108 }
109 s->EOL();
110
111 if (depth > 0)
112 {
113 s->IndentMore();
114
Greg Claytonb04e7a82010-08-24 21:05:24 +0000115 if (m_variable_list_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000116 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000117 m_variable_list_sp->Dump(s, show_context);
Chris Lattner24943d22010-06-08 16:52:24 +0000118 }
119
Greg Clayton75ccf502010-08-21 02:22:51 +0000120 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
Chris Lattner24943d22010-06-08 16:52:24 +0000121 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000122 child_block->Dump(s, base_addr, depth - 1, show_context);
Chris Lattner24943d22010-06-08 16:52:24 +0000123 }
124
125 s->IndentLess();
126 }
127
128}
129
130
Greg Clayton75ccf502010-08-21 02:22:51 +0000131Block *
132Block::FindBlockByID (user_id_t block_id)
133{
134 if (block_id == GetID())
135 return this;
136
137 Block *matching_block = NULL;
138 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
139 {
140 matching_block = child_block->FindBlockByID (block_id);
141 if (matching_block)
142 break;
143 }
144 return matching_block;
145}
146
Chris Lattner24943d22010-06-08 16:52:24 +0000147void
Greg Claytonb04e7a82010-08-24 21:05:24 +0000148Block::CalculateSymbolContext (SymbolContext* sc)
Chris Lattner24943d22010-06-08 16:52:24 +0000149{
Greg Clayton75ccf502010-08-21 02:22:51 +0000150 if (m_parent_scope)
151 m_parent_scope->CalculateSymbolContext(sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000152 sc->block = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000153}
154
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000155Module *
156Block::CalculateSymbolContextModule ()
157{
158 if (m_parent_scope)
159 return m_parent_scope->CalculateSymbolContextModule ();
160 return NULL;
161}
162
163CompileUnit *
164Block::CalculateSymbolContextCompileUnit ()
165{
166 if (m_parent_scope)
167 return m_parent_scope->CalculateSymbolContextCompileUnit ();
168 return NULL;
169}
170
171Function *
172Block::CalculateSymbolContextFunction ()
173{
174 if (m_parent_scope)
175 return m_parent_scope->CalculateSymbolContextFunction ();
176 return NULL;
177}
178
179Block *
180Block::CalculateSymbolContextBlock ()
181{
182 return this;
183}
184
Chris Lattner24943d22010-06-08 16:52:24 +0000185void
Greg Clayton69aa5d92010-09-07 04:20:48 +0000186Block::DumpStopContext
187(
188 Stream *s,
189 const SymbolContext *sc_ptr,
190 const Declaration *child_inline_call_site,
191 bool show_fullpaths,
192 bool show_inline_blocks)
Chris Lattner24943d22010-06-08 16:52:24 +0000193{
Greg Claytonff44ab42011-04-23 02:04:55 +0000194 const InlineFunctionInfo* inline_info = NULL;
195 Block* inlined_block;
196 if (sc_ptr)
197 inlined_block = GetContainingInlinedBlock ();
198 else
199 inlined_block = GetInlinedParent();
Chris Lattner24943d22010-06-08 16:52:24 +0000200
Greg Claytonff44ab42011-04-23 02:04:55 +0000201 if (inlined_block)
202 inline_info = inlined_block->GetInlinedFunctionInfo();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000203 const Declaration *inline_call_site = child_inline_call_site;
Chris Lattner24943d22010-06-08 16:52:24 +0000204 if (inline_info)
205 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000206 inline_call_site = &inline_info->GetCallSite();
207 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000208 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000209 // First frame in a frame with inlined functions
Chris Lattner24943d22010-06-08 16:52:24 +0000210 s->PutCString (" [inlined]");
211 }
Greg Clayton3c126042011-02-08 02:40:32 +0000212 if (show_inline_blocks && child_inline_call_site)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000213 s->EOL();
214 else
215 s->PutChar(' ');
Greg Claytonff44ab42011-04-23 02:04:55 +0000216
217 if (sc_ptr == NULL)
218 s->Indent();
219
Greg Clayton69aa5d92010-09-07 04:20:48 +0000220 s->PutCString(inline_info->GetName ().AsCString());
221
222 if (child_inline_call_site && child_inline_call_site->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000223 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000224 s->PutCString(" at ");
225 child_inline_call_site->DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000226 }
227 }
228
Greg Claytonff44ab42011-04-23 02:04:55 +0000229 // The first call to this function from something that has a symbol
230 // context will pass in a valid sc_ptr. Subsequent calls to this function
231 // from this function for inline purposes will NULL out sc_ptr. So on the
232 // first time through we dump the line table entry (which is always at the
233 // deepest inline code block). And subsequent calls to this function we
234 // will use hte inline call site information to print line numbers.
Greg Clayton69aa5d92010-09-07 04:20:48 +0000235 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000236 {
237 // If we have any inlined functions, this will be the deepest most
238 // inlined location
Greg Clayton69aa5d92010-09-07 04:20:48 +0000239 if (sc_ptr->line_entry.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000240 {
241 s->PutCString(" at ");
Greg Clayton69aa5d92010-09-07 04:20:48 +0000242 sc_ptr->line_entry.DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000243 }
244 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000245
246 if (show_inline_blocks)
247 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000248 if (inlined_block)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000249 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000250 inlined_block->Block::DumpStopContext (s,
251 NULL,
252 inline_call_site,
253 show_fullpaths,
254 show_inline_blocks);
Greg Clayton69aa5d92010-09-07 04:20:48 +0000255 }
256 else if (child_inline_call_site)
257 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000258 Function *function = CalculateSymbolContextFunction();
259 if (function)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000260 {
261 s->EOL();
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000262 s->Indent (function->GetMangled().GetName().AsCString());
Greg Clayton69aa5d92010-09-07 04:20:48 +0000263 if (child_inline_call_site && child_inline_call_site->IsValid())
264 {
265 s->PutCString(" at ");
266 child_inline_call_site->DumpStopContext (s, show_fullpaths);
267 }
268 }
269 }
270 }
Chris Lattner24943d22010-06-08 16:52:24 +0000271}
272
273
274void
275Block::DumpSymbolContext(Stream *s)
276{
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000277 Function *function = CalculateSymbolContextFunction();
278 if (function)
279 function->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +0000280 s->Printf(", Block{0x%8.8x}", GetID());
281}
282
Caroline Tice98f930f2010-09-20 05:20:02 +0000283void
284Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
285{
286 if (!m_ranges.empty())
287 {
288 std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
289 for (pos = m_ranges.begin(); pos != end; ++pos)
290 pos->Dump (s, base_addr);
291 }
292}
293
Chris Lattner24943d22010-06-08 16:52:24 +0000294bool
295Block::Contains (addr_t range_offset) const
296{
297 return VMRange::ContainsValue(m_ranges, range_offset);
298}
299
300bool
Greg Clayton72b71582010-09-02 21:44:10 +0000301Block::Contains (const Block *block) const
302{
Greg Clayton72b71582010-09-02 21:44:10 +0000303 if (this == block)
Greg Claytona357ecf2010-09-14 03:16:58 +0000304 return false; // This block doesn't contain itself...
Greg Clayton72b71582010-09-02 21:44:10 +0000305
Greg Claytona357ecf2010-09-14 03:16:58 +0000306 // Walk the parent chain for "block" and see if any if them match this block
Greg Clayton72b71582010-09-02 21:44:10 +0000307 const Block *block_parent;
308 for (block_parent = block->GetParent();
309 block_parent != NULL;
310 block_parent = block_parent->GetParent())
311 {
Greg Claytona357ecf2010-09-14 03:16:58 +0000312 if (this == block_parent)
313 return true; // One of the parents of "block" is this object!
Greg Clayton72b71582010-09-02 21:44:10 +0000314 }
315 return false;
316}
317
318bool
Chris Lattner24943d22010-06-08 16:52:24 +0000319Block::Contains (const VMRange& range) const
320{
321 return VMRange::ContainsRange(m_ranges, range);
322}
323
Greg Clayton75ccf502010-08-21 02:22:51 +0000324Block *
325Block::GetParent () const
Chris Lattner24943d22010-06-08 16:52:24 +0000326{
Greg Clayton75ccf502010-08-21 02:22:51 +0000327 if (m_parent_scope)
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000328 return m_parent_scope->CalculateSymbolContextBlock();
Greg Clayton75ccf502010-08-21 02:22:51 +0000329 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000330}
331
Greg Clayton33ed1702010-08-24 00:45:41 +0000332Block *
Greg Claytonb04e7a82010-08-24 21:05:24 +0000333Block::GetContainingInlinedBlock ()
334{
Greg Clayton69aa5d92010-09-07 04:20:48 +0000335 if (GetInlinedFunctionInfo())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000336 return this;
337 return GetInlinedParent ();
338}
339
340Block *
341Block::GetInlinedParent ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000342{
343 Block *parent_block = GetParent ();
344 if (parent_block)
345 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000346 if (parent_block->GetInlinedFunctionInfo())
Greg Clayton33ed1702010-08-24 00:45:41 +0000347 return parent_block;
348 else
349 return parent_block->GetInlinedParent();
350 }
351 return NULL;
352}
353
354
355bool
Greg Claytonb04e7a82010-08-24 21:05:24 +0000356Block::GetRangeContainingOffset (const addr_t offset, VMRange &range)
357{
358 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
359 if (range_idx < m_ranges.size())
360 {
361 range = m_ranges[range_idx];
362 return true;
363 }
364 range.Clear();
365 return false;
366}
367
368
369bool
Greg Clayton23b8abb2011-09-26 07:11:27 +0000370Block::GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr)
Greg Clayton33ed1702010-08-24 00:45:41 +0000371{
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000372 Function *function = CalculateSymbolContextFunction();
373 if (function)
Greg Clayton33ed1702010-08-24 00:45:41 +0000374 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000375 const AddressRange &func_range = function->GetAddressRange();
Greg Clayton33ed1702010-08-24 00:45:41 +0000376 if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
377 {
378 const addr_t addr_offset = addr.GetOffset();
379 const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
380 if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
381 {
382 addr_t offset = addr_offset - func_offset;
383
384 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
385 if (range_idx < m_ranges.size())
386 {
387 range.GetBaseAddress() = func_range.GetBaseAddress();
388 range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress());
389 range.SetByteSize(m_ranges[range_idx].GetByteSize());
Greg Clayton23b8abb2011-09-26 07:11:27 +0000390 if (range_idx_ptr)
391 *range_idx_ptr = range_idx;
Greg Clayton33ed1702010-08-24 00:45:41 +0000392 return true;
393 }
394 }
395 }
396 }
Greg Clayton23b8abb2011-09-26 07:11:27 +0000397 if (range_idx_ptr)
398 *range_idx_ptr = UINT32_MAX;
Greg Clayton33ed1702010-08-24 00:45:41 +0000399 range.Clear();
400 return false;
401}
402
Greg Claytonff44ab42011-04-23 02:04:55 +0000403bool
404Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
405{
406 if (range_idx < m_ranges.size())
407 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000408 Function *function = CalculateSymbolContextFunction();
409 if (function)
Greg Claytonff44ab42011-04-23 02:04:55 +0000410 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000411 range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
Greg Claytonff44ab42011-04-23 02:04:55 +0000412 range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ());
413 range.SetByteSize (m_ranges[range_idx].GetByteSize());
414 return true;
415 }
416 }
417 return false;
418}
Greg Claytonfeb6e562010-11-14 00:22:48 +0000419
420bool
421Block::GetStartAddress (Address &addr)
422{
423 if (m_ranges.empty())
424 return false;
425
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000426 Function *function = CalculateSymbolContextFunction();
427 if (function)
Greg Claytonfeb6e562010-11-14 00:22:48 +0000428 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000429 addr = function->GetAddressRange().GetBaseAddress();
Greg Claytonfeb6e562010-11-14 00:22:48 +0000430 addr.Slide(m_ranges.front().GetBaseAddress ());
431 return true;
432 }
433 return false;
434}
435
Chris Lattner24943d22010-06-08 16:52:24 +0000436void
437Block::AddRange(addr_t start_offset, addr_t end_offset)
438{
439 m_ranges.resize(m_ranges.size()+1);
440 m_ranges.back().Reset(start_offset, end_offset);
441}
442
Chris Lattner24943d22010-06-08 16:52:24 +0000443// Return the current number of bytes that this object occupies in memory
444size_t
445Block::MemorySize() const
446{
447 size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange);
448 if (m_inlineInfoSP.get())
449 mem_size += m_inlineInfoSP->MemorySize();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000450 if (m_variable_list_sp.get())
451 mem_size += m_variable_list_sp->MemorySize();
Chris Lattner24943d22010-06-08 16:52:24 +0000452 return mem_size;
453
454}
455
Greg Clayton75ccf502010-08-21 02:22:51 +0000456void
457Block::AddChild(const BlockSP &child_block_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000458{
Greg Clayton75ccf502010-08-21 02:22:51 +0000459 if (child_block_sp)
460 {
461 Block *block_needs_sibling = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000462
Greg Clayton75ccf502010-08-21 02:22:51 +0000463 if (!m_children.empty())
464 block_needs_sibling = m_children.back().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000465
Greg Clayton75ccf502010-08-21 02:22:51 +0000466 child_block_sp->SetParentScope (this);
467 m_children.push_back (child_block_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000468
Greg Clayton75ccf502010-08-21 02:22:51 +0000469 if (block_needs_sibling)
470 block_needs_sibling->SetSibling (child_block_sp.get());
471 }
Chris Lattner24943d22010-06-08 16:52:24 +0000472}
473
474void
475Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
476{
477 m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
478}
479
Jim Ingham7382a532010-08-18 19:29:16 +0000480
481
482VariableListSP
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000483Block::GetBlockVariableList (bool can_create)
Jim Ingham7382a532010-08-18 19:29:16 +0000484{
Greg Clayton75ccf502010-08-21 02:22:51 +0000485 if (m_parsed_block_variables == false)
Jim Ingham7382a532010-08-18 19:29:16 +0000486 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000487 if (m_variable_list_sp.get() == NULL && can_create)
Greg Clayton75ccf502010-08-21 02:22:51 +0000488 {
489 m_parsed_block_variables = true;
490 SymbolContext sc;
491 CalculateSymbolContext(&sc);
492 assert(sc.module_sp);
493 sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
494 }
Jim Ingham7382a532010-08-18 19:29:16 +0000495 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000496 return m_variable_list_sp;
497}
Jim Ingham7382a532010-08-18 19:29:16 +0000498
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000499uint32_t
500Block::AppendBlockVariables (bool can_create,
501 bool get_child_block_variables,
502 bool stop_if_child_block_is_inlined_function,
503 VariableList *variable_list)
504{
505 uint32_t num_variables_added = 0;
506 VariableList *block_var_list = GetBlockVariableList (can_create).get();
507 if (block_var_list)
Jim Ingham7382a532010-08-18 19:29:16 +0000508 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000509 num_variables_added += block_var_list->GetSize();
510 variable_list->AddVariables (block_var_list);
511 }
512
513 if (get_child_block_variables)
514 {
515 for (Block *child_block = GetFirstChild();
516 child_block != NULL;
517 child_block = child_block->GetSibling())
518 {
519 if (stop_if_child_block_is_inlined_function == false ||
520 child_block->GetInlinedFunctionInfo() == NULL)
521 {
522 num_variables_added += child_block->AppendBlockVariables (can_create,
523 get_child_block_variables,
524 stop_if_child_block_is_inlined_function,
525 variable_list);
Jim Ingham7382a532010-08-18 19:29:16 +0000526 }
527 }
528 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000529 return num_variables_added;
Jim Ingham7382a532010-08-18 19:29:16 +0000530}
531
532uint32_t
Greg Clayton33ed1702010-08-24 00:45:41 +0000533Block::AppendVariables
534(
535 bool can_create,
536 bool get_parent_variables,
537 bool stop_if_block_is_inlined_function,
538 VariableList *variable_list
539)
Jim Ingham7382a532010-08-18 19:29:16 +0000540{
541 uint32_t num_variables_added = 0;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000542 VariableListSP variable_list_sp(GetBlockVariableList(can_create));
Jim Ingham7382a532010-08-18 19:29:16 +0000543
Greg Clayton69aa5d92010-09-07 04:20:48 +0000544 bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
Jim Ingham7382a532010-08-18 19:29:16 +0000545 if (variable_list_sp.get())
546 {
547 num_variables_added = variable_list_sp->GetSize();
548 variable_list->AddVariables(variable_list_sp.get());
549 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000550
Jim Ingham7382a532010-08-18 19:29:16 +0000551 if (get_parent_variables)
552 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000553 if (stop_if_block_is_inlined_function && is_inlined_function)
554 return num_variables_added;
555
Jim Ingham7382a532010-08-18 19:29:16 +0000556 Block* parent_block = GetParent();
557 if (parent_block)
Greg Clayton33ed1702010-08-24 00:45:41 +0000558 num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list);
Jim Ingham7382a532010-08-18 19:29:16 +0000559 }
560 return num_variables_added;
561}
562
Sean Callananc617a4c2011-08-05 23:43:37 +0000563clang::DeclContext *
564Block::GetClangDeclContextForInlinedFunction()
565{
566 SymbolContext sc;
567
568 CalculateSymbolContext (&sc);
569
570 if (!sc.module_sp)
571 return NULL;
572
573 SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
574
575 if (!sym_vendor)
576 return NULL;
577
578 SymbolFile *sym_file = sym_vendor->GetSymbolFile();
579
580 if (!sym_file)
581 return NULL;
582
583 return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
584}
585
Chris Lattner24943d22010-06-08 16:52:24 +0000586void
Greg Clayton75ccf502010-08-21 02:22:51 +0000587Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000588{
Greg Clayton75ccf502010-08-21 02:22:51 +0000589 m_parsed_block_info = b;
590 if (set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000591 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000592 m_parsed_child_blocks = true;
593 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
594 child_block->SetBlockInfoHasBeenParsed (b, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000595 }
Chris Lattner24943d22010-06-08 16:52:24 +0000596}
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000597
598void
599Block::SetDidParseVariables (bool b, bool set_children)
600{
601 m_parsed_block_variables = b;
602 if (set_children)
603 {
604 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
605 child_block->SetDidParseVariables (b, true);
606 }
607}
608