blob: 6827473be1c752d00834c84aa3856e81a7ecb0ad [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"
14#include "lldb/Symbol/SymbolVendor.h"
15#include "lldb/Symbol/VariableList.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
Greg Clayton75ccf502010-08-21 02:22:51 +000020Block::Block(lldb::user_id_t uid) :
Chris Lattner24943d22010-06-08 16:52:24 +000021 UserID(uid),
Greg Clayton75ccf502010-08-21 02:22:51 +000022 m_parent_scope (NULL),
23 m_sibling (NULL),
24 m_children (),
25 m_ranges (),
26 m_inlineInfoSP (),
Greg Claytonb04e7a82010-08-24 21:05:24 +000027 m_variable_list_sp (),
Greg Clayton75ccf502010-08-21 02:22:51 +000028 m_parsed_block_info (false),
29 m_parsed_block_variables (false),
30 m_parsed_child_blocks (false)
Chris Lattner24943d22010-06-08 16:52:24 +000031{
32}
33
Chris Lattner24943d22010-06-08 16:52:24 +000034Block::~Block ()
35{
36}
37
38void
Greg Claytoneea26402010-09-14 23:36:40 +000039Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +000040{
Greg Claytonc67b7d12010-09-10 01:30:46 +000041 *s << "id = " << ((const UserID&)*this);
42
Greg Clayton12bec712010-06-28 21:30:43 +000043 size_t num_ranges = m_ranges.size();
44 if (num_ranges)
45 {
46
47 addr_t base_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneea26402010-09-14 23:36:40 +000048 if (target)
49 base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
Greg Clayton12bec712010-06-28 21:30:43 +000050 if (base_addr == LLDB_INVALID_ADDRESS)
Greg Clayton75ccf502010-08-21 02:22:51 +000051 base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
Greg Clayton12bec712010-06-28 21:30:43 +000052
Greg Claytonc67b7d12010-09-10 01:30:46 +000053 s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
Greg Clayton12bec712010-06-28 21:30:43 +000054 std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
55 for (pos = m_ranges.begin(); pos != end; ++pos)
56 pos->Dump(s, base_addr, 4);
57 }
Greg Clayton12bec712010-06-28 21:30:43 +000058
59 if (m_inlineInfoSP.get() != NULL)
Greg Clayton1924e242010-09-15 05:51:24 +000060 {
61 bool show_fullpaths = (level == eDescriptionLevelVerbose);
62 m_inlineInfoSP->Dump(s, show_fullpaths);
63 }
Greg Clayton12bec712010-06-28 21:30:43 +000064}
65
66void
Chris Lattner24943d22010-06-08 16:52:24 +000067Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
68{
69 if (depth < 0)
70 {
Greg Clayton75ccf502010-08-21 02:22:51 +000071 Block *parent = GetParent();
72 if (parent)
73 {
74 // We have a depth that is less than zero, print our parent blocks
75 // first
76 parent->Dump(s, base_addr, depth + 1, show_context);
77 }
Chris Lattner24943d22010-06-08 16:52:24 +000078 }
79
80 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
81 s->Indent();
82 *s << "Block" << ((const UserID&)*this);
Greg Clayton12bec712010-06-28 21:30:43 +000083 const Block* parent_block = GetParent();
84 if (parent_block)
Chris Lattner24943d22010-06-08 16:52:24 +000085 {
Greg Clayton12bec712010-06-28 21:30:43 +000086 s->Printf(", parent = {0x%8.8x}", parent_block->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +000087 }
88 if (m_inlineInfoSP.get() != NULL)
Greg Clayton1924e242010-09-15 05:51:24 +000089 {
90 bool show_fullpaths = false;
91 m_inlineInfoSP->Dump(s, show_fullpaths);
92 }
Chris Lattner24943d22010-06-08 16:52:24 +000093
94 if (!m_ranges.empty())
95 {
96 *s << ", ranges =";
97 std::vector<VMRange>::const_iterator pos;
98 std::vector<VMRange>::const_iterator end = m_ranges.end();
99 for (pos = m_ranges.begin(); pos != end; ++pos)
100 {
101 if (parent_block != NULL && parent_block->Contains(*pos) == false)
102 *s << '!';
103 else
104 *s << ' ';
105 pos->Dump(s, base_addr);
106 }
107 }
108 s->EOL();
109
110 if (depth > 0)
111 {
112 s->IndentMore();
113
Greg Claytonb04e7a82010-08-24 21:05:24 +0000114 if (m_variable_list_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000115 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000116 m_variable_list_sp->Dump(s, show_context);
Chris Lattner24943d22010-06-08 16:52:24 +0000117 }
118
Greg Clayton75ccf502010-08-21 02:22:51 +0000119 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
Chris Lattner24943d22010-06-08 16:52:24 +0000120 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000121 child_block->Dump(s, base_addr, depth - 1, show_context);
Chris Lattner24943d22010-06-08 16:52:24 +0000122 }
123
124 s->IndentLess();
125 }
126
127}
128
129
Greg Clayton75ccf502010-08-21 02:22:51 +0000130Block *
131Block::FindBlockByID (user_id_t block_id)
132{
133 if (block_id == GetID())
134 return this;
135
136 Block *matching_block = NULL;
137 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
138 {
139 matching_block = child_block->FindBlockByID (block_id);
140 if (matching_block)
141 break;
142 }
143 return matching_block;
144}
145
Chris Lattner24943d22010-06-08 16:52:24 +0000146void
Greg Claytonb04e7a82010-08-24 21:05:24 +0000147Block::CalculateSymbolContext (SymbolContext* sc)
Chris Lattner24943d22010-06-08 16:52:24 +0000148{
Greg Clayton75ccf502010-08-21 02:22:51 +0000149 if (m_parent_scope)
150 m_parent_scope->CalculateSymbolContext(sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000151 sc->block = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000152}
153
154void
Greg Clayton69aa5d92010-09-07 04:20:48 +0000155Block::DumpStopContext
156(
157 Stream *s,
158 const SymbolContext *sc_ptr,
159 const Declaration *child_inline_call_site,
160 bool show_fullpaths,
161 bool show_inline_blocks)
Chris Lattner24943d22010-06-08 16:52:24 +0000162{
Greg Claytonff44ab42011-04-23 02:04:55 +0000163 const InlineFunctionInfo* inline_info = NULL;
164 Block* inlined_block;
165 if (sc_ptr)
166 inlined_block = GetContainingInlinedBlock ();
167 else
168 inlined_block = GetInlinedParent();
Chris Lattner24943d22010-06-08 16:52:24 +0000169
Greg Claytonff44ab42011-04-23 02:04:55 +0000170 if (inlined_block)
171 inline_info = inlined_block->GetInlinedFunctionInfo();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000172 const Declaration *inline_call_site = child_inline_call_site;
Chris Lattner24943d22010-06-08 16:52:24 +0000173 if (inline_info)
174 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000175 inline_call_site = &inline_info->GetCallSite();
176 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000177 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000178 // First frame in a frame with inlined functions
Chris Lattner24943d22010-06-08 16:52:24 +0000179 s->PutCString (" [inlined]");
180 }
Greg Clayton3c126042011-02-08 02:40:32 +0000181 if (show_inline_blocks && child_inline_call_site)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000182 s->EOL();
183 else
184 s->PutChar(' ');
Greg Claytonff44ab42011-04-23 02:04:55 +0000185
186 if (sc_ptr == NULL)
187 s->Indent();
188
Greg Clayton69aa5d92010-09-07 04:20:48 +0000189 s->PutCString(inline_info->GetName ().AsCString());
190
191 if (child_inline_call_site && child_inline_call_site->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000192 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000193 s->PutCString(" at ");
194 child_inline_call_site->DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000195 }
196 }
197
Greg Claytonff44ab42011-04-23 02:04:55 +0000198 // The first call to this function from something that has a symbol
199 // context will pass in a valid sc_ptr. Subsequent calls to this function
200 // from this function for inline purposes will NULL out sc_ptr. So on the
201 // first time through we dump the line table entry (which is always at the
202 // deepest inline code block). And subsequent calls to this function we
203 // will use hte inline call site information to print line numbers.
Greg Clayton69aa5d92010-09-07 04:20:48 +0000204 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000205 {
206 // If we have any inlined functions, this will be the deepest most
207 // inlined location
Greg Clayton69aa5d92010-09-07 04:20:48 +0000208 if (sc_ptr->line_entry.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000209 {
210 s->PutCString(" at ");
Greg Clayton69aa5d92010-09-07 04:20:48 +0000211 sc_ptr->line_entry.DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000212 }
213 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000214
215 if (show_inline_blocks)
216 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000217 if (inlined_block)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000218 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000219 inlined_block->Block::DumpStopContext (s,
220 NULL,
221 inline_call_site,
222 show_fullpaths,
223 show_inline_blocks);
Greg Clayton69aa5d92010-09-07 04:20:48 +0000224 }
225 else if (child_inline_call_site)
226 {
227 SymbolContext sc;
228 CalculateSymbolContext(&sc);
229 if (sc.function)
230 {
231 s->EOL();
232 s->Indent (sc.function->GetMangled().GetName().AsCString());
233 if (child_inline_call_site && child_inline_call_site->IsValid())
234 {
235 s->PutCString(" at ");
236 child_inline_call_site->DumpStopContext (s, show_fullpaths);
237 }
238 }
239 }
240 }
Chris Lattner24943d22010-06-08 16:52:24 +0000241}
242
243
244void
245Block::DumpSymbolContext(Stream *s)
246{
Greg Clayton75ccf502010-08-21 02:22:51 +0000247 SymbolContext sc;
248 CalculateSymbolContext(&sc);
249 if (sc.function)
250 sc.function->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +0000251 s->Printf(", Block{0x%8.8x}", GetID());
252}
253
Caroline Tice98f930f2010-09-20 05:20:02 +0000254void
255Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
256{
257 if (!m_ranges.empty())
258 {
259 std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
260 for (pos = m_ranges.begin(); pos != end; ++pos)
261 pos->Dump (s, base_addr);
262 }
263}
264
Chris Lattner24943d22010-06-08 16:52:24 +0000265bool
266Block::Contains (addr_t range_offset) const
267{
268 return VMRange::ContainsValue(m_ranges, range_offset);
269}
270
271bool
Greg Clayton72b71582010-09-02 21:44:10 +0000272Block::Contains (const Block *block) const
273{
Greg Clayton72b71582010-09-02 21:44:10 +0000274 if (this == block)
Greg Claytona357ecf2010-09-14 03:16:58 +0000275 return false; // This block doesn't contain itself...
Greg Clayton72b71582010-09-02 21:44:10 +0000276
Greg Claytona357ecf2010-09-14 03:16:58 +0000277 // Walk the parent chain for "block" and see if any if them match this block
Greg Clayton72b71582010-09-02 21:44:10 +0000278 const Block *block_parent;
279 for (block_parent = block->GetParent();
280 block_parent != NULL;
281 block_parent = block_parent->GetParent())
282 {
Greg Claytona357ecf2010-09-14 03:16:58 +0000283 if (this == block_parent)
284 return true; // One of the parents of "block" is this object!
Greg Clayton72b71582010-09-02 21:44:10 +0000285 }
286 return false;
287}
288
289bool
Chris Lattner24943d22010-06-08 16:52:24 +0000290Block::Contains (const VMRange& range) const
291{
292 return VMRange::ContainsRange(m_ranges, range);
293}
294
Greg Clayton75ccf502010-08-21 02:22:51 +0000295Block *
296Block::GetParent () const
Chris Lattner24943d22010-06-08 16:52:24 +0000297{
Greg Clayton75ccf502010-08-21 02:22:51 +0000298 if (m_parent_scope)
Chris Lattner24943d22010-06-08 16:52:24 +0000299 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000300 SymbolContext sc;
301 m_parent_scope->CalculateSymbolContext(&sc);
302 if (sc.block)
303 return sc.block;
Chris Lattner24943d22010-06-08 16:52:24 +0000304 }
Greg Clayton75ccf502010-08-21 02:22:51 +0000305 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000306}
307
Greg Clayton33ed1702010-08-24 00:45:41 +0000308Block *
Greg Claytonb04e7a82010-08-24 21:05:24 +0000309Block::GetContainingInlinedBlock ()
310{
Greg Clayton69aa5d92010-09-07 04:20:48 +0000311 if (GetInlinedFunctionInfo())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000312 return this;
313 return GetInlinedParent ();
314}
315
316Block *
317Block::GetInlinedParent ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000318{
319 Block *parent_block = GetParent ();
320 if (parent_block)
321 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000322 if (parent_block->GetInlinedFunctionInfo())
Greg Clayton33ed1702010-08-24 00:45:41 +0000323 return parent_block;
324 else
325 return parent_block->GetInlinedParent();
326 }
327 return NULL;
328}
329
330
331bool
Greg Claytonb04e7a82010-08-24 21:05:24 +0000332Block::GetRangeContainingOffset (const addr_t offset, VMRange &range)
333{
334 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
335 if (range_idx < m_ranges.size())
336 {
337 range = m_ranges[range_idx];
338 return true;
339 }
340 range.Clear();
341 return false;
342}
343
344
345bool
Greg Clayton33ed1702010-08-24 00:45:41 +0000346Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
347{
348 SymbolContext sc;
349 CalculateSymbolContext(&sc);
350 if (sc.function)
351 {
352 const AddressRange &func_range = sc.function->GetAddressRange();
353 if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
354 {
355 const addr_t addr_offset = addr.GetOffset();
356 const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
357 if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
358 {
359 addr_t offset = addr_offset - func_offset;
360
361 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
362 if (range_idx < m_ranges.size())
363 {
364 range.GetBaseAddress() = func_range.GetBaseAddress();
365 range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress());
366 range.SetByteSize(m_ranges[range_idx].GetByteSize());
367 return true;
368 }
369 }
370 }
371 }
372 range.Clear();
373 return false;
374}
375
Greg Claytonff44ab42011-04-23 02:04:55 +0000376bool
377Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
378{
379 if (range_idx < m_ranges.size())
380 {
381 SymbolContext sc;
382 CalculateSymbolContext(&sc);
383 if (sc.function)
384 {
385 range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
386 range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ());
387 range.SetByteSize (m_ranges[range_idx].GetByteSize());
388 return true;
389 }
390 }
391 return false;
392}
Greg Claytonfeb6e562010-11-14 00:22:48 +0000393
394bool
395Block::GetStartAddress (Address &addr)
396{
397 if (m_ranges.empty())
398 return false;
399
400 SymbolContext sc;
401 CalculateSymbolContext(&sc);
402 if (sc.function)
403 {
404 addr = sc.function->GetAddressRange().GetBaseAddress();
405 addr.Slide(m_ranges.front().GetBaseAddress ());
406 return true;
407 }
408 return false;
409}
410
Chris Lattner24943d22010-06-08 16:52:24 +0000411void
412Block::AddRange(addr_t start_offset, addr_t end_offset)
413{
414 m_ranges.resize(m_ranges.size()+1);
415 m_ranges.back().Reset(start_offset, end_offset);
416}
417
Chris Lattner24943d22010-06-08 16:52:24 +0000418// Return the current number of bytes that this object occupies in memory
419size_t
420Block::MemorySize() const
421{
422 size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange);
423 if (m_inlineInfoSP.get())
424 mem_size += m_inlineInfoSP->MemorySize();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000425 if (m_variable_list_sp.get())
426 mem_size += m_variable_list_sp->MemorySize();
Chris Lattner24943d22010-06-08 16:52:24 +0000427 return mem_size;
428
429}
430
Greg Clayton75ccf502010-08-21 02:22:51 +0000431void
432Block::AddChild(const BlockSP &child_block_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000433{
Greg Clayton75ccf502010-08-21 02:22:51 +0000434 if (child_block_sp)
435 {
436 Block *block_needs_sibling = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000437
Greg Clayton75ccf502010-08-21 02:22:51 +0000438 if (!m_children.empty())
439 block_needs_sibling = m_children.back().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000440
Greg Clayton75ccf502010-08-21 02:22:51 +0000441 child_block_sp->SetParentScope (this);
442 m_children.push_back (child_block_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000443
Greg Clayton75ccf502010-08-21 02:22:51 +0000444 if (block_needs_sibling)
445 block_needs_sibling->SetSibling (child_block_sp.get());
446 }
Chris Lattner24943d22010-06-08 16:52:24 +0000447}
448
449void
450Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
451{
452 m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
453}
454
Jim Ingham7382a532010-08-18 19:29:16 +0000455
456
457VariableListSP
458Block::GetVariableList (bool get_child_variables, bool can_create)
459{
460 VariableListSP variable_list_sp;
Greg Clayton75ccf502010-08-21 02:22:51 +0000461 if (m_parsed_block_variables == false)
Jim Ingham7382a532010-08-18 19:29:16 +0000462 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000463 if (m_variable_list_sp.get() == NULL && can_create)
Greg Clayton75ccf502010-08-21 02:22:51 +0000464 {
465 m_parsed_block_variables = true;
466 SymbolContext sc;
467 CalculateSymbolContext(&sc);
468 assert(sc.module_sp);
469 sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
470 }
Jim Ingham7382a532010-08-18 19:29:16 +0000471 }
472
Greg Claytonb04e7a82010-08-24 21:05:24 +0000473 if (m_variable_list_sp.get())
Jim Ingham7382a532010-08-18 19:29:16 +0000474 {
475 variable_list_sp.reset(new VariableList());
476 if (variable_list_sp.get())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000477 variable_list_sp->AddVariables(m_variable_list_sp.get());
Jim Ingham7382a532010-08-18 19:29:16 +0000478
479 if (get_child_variables)
480 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000481 for (Block *child_block = GetFirstChild();
482 child_block != NULL;
483 child_block = child_block->GetSibling())
484 {
485 if (child_block->GetInlinedFunctionInfo() == NULL)
486 {
487 VariableListSP child_block_variable_list(child_block->GetVariableList(get_child_variables, can_create));
488 if (child_block_variable_list.get())
489 variable_list_sp->AddVariables(child_block_variable_list.get());
490 }
491
Jim Ingham7382a532010-08-18 19:29:16 +0000492 }
493 }
494 }
495
496 return variable_list_sp;
497}
498
499uint32_t
Greg Clayton33ed1702010-08-24 00:45:41 +0000500Block::AppendVariables
501(
502 bool can_create,
503 bool get_parent_variables,
504 bool stop_if_block_is_inlined_function,
505 VariableList *variable_list
506)
Jim Ingham7382a532010-08-18 19:29:16 +0000507{
508 uint32_t num_variables_added = 0;
509 VariableListSP variable_list_sp(GetVariableList(false, can_create));
510
Greg Clayton69aa5d92010-09-07 04:20:48 +0000511 bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
Jim Ingham7382a532010-08-18 19:29:16 +0000512 if (variable_list_sp.get())
513 {
514 num_variables_added = variable_list_sp->GetSize();
515 variable_list->AddVariables(variable_list_sp.get());
516 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000517
Jim Ingham7382a532010-08-18 19:29:16 +0000518 if (get_parent_variables)
519 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000520 if (stop_if_block_is_inlined_function && is_inlined_function)
521 return num_variables_added;
522
Jim Ingham7382a532010-08-18 19:29:16 +0000523 Block* parent_block = GetParent();
524 if (parent_block)
Greg Clayton33ed1702010-08-24 00:45:41 +0000525 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 +0000526 }
527 return num_variables_added;
528}
529
Chris Lattner24943d22010-06-08 16:52:24 +0000530void
Greg Clayton75ccf502010-08-21 02:22:51 +0000531Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000532{
Greg Clayton75ccf502010-08-21 02:22:51 +0000533 m_parsed_block_info = b;
534 if (set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000535 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000536 m_parsed_child_blocks = true;
537 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
538 child_block->SetBlockInfoHasBeenParsed (b, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 }
Chris Lattner24943d22010-06-08 16:52:24 +0000540}