blob: d1e4d401498801dfbe9f3c3f61a6fe8a3644ac64 [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 Clayton33ed1702010-08-24 00:45:41 +0000370Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
371{
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());
390 return true;
391 }
392 }
393 }
394 }
395 range.Clear();
396 return false;
397}
398
Greg Claytonff44ab42011-04-23 02:04:55 +0000399bool
400Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
401{
402 if (range_idx < m_ranges.size())
403 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000404 Function *function = CalculateSymbolContextFunction();
405 if (function)
Greg Claytonff44ab42011-04-23 02:04:55 +0000406 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000407 range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
Greg Claytonff44ab42011-04-23 02:04:55 +0000408 range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ());
409 range.SetByteSize (m_ranges[range_idx].GetByteSize());
410 return true;
411 }
412 }
413 return false;
414}
Greg Claytonfeb6e562010-11-14 00:22:48 +0000415
416bool
417Block::GetStartAddress (Address &addr)
418{
419 if (m_ranges.empty())
420 return false;
421
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000422 Function *function = CalculateSymbolContextFunction();
423 if (function)
Greg Claytonfeb6e562010-11-14 00:22:48 +0000424 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000425 addr = function->GetAddressRange().GetBaseAddress();
Greg Claytonfeb6e562010-11-14 00:22:48 +0000426 addr.Slide(m_ranges.front().GetBaseAddress ());
427 return true;
428 }
429 return false;
430}
431
Chris Lattner24943d22010-06-08 16:52:24 +0000432void
433Block::AddRange(addr_t start_offset, addr_t end_offset)
434{
435 m_ranges.resize(m_ranges.size()+1);
436 m_ranges.back().Reset(start_offset, end_offset);
437}
438
Chris Lattner24943d22010-06-08 16:52:24 +0000439// Return the current number of bytes that this object occupies in memory
440size_t
441Block::MemorySize() const
442{
443 size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange);
444 if (m_inlineInfoSP.get())
445 mem_size += m_inlineInfoSP->MemorySize();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000446 if (m_variable_list_sp.get())
447 mem_size += m_variable_list_sp->MemorySize();
Chris Lattner24943d22010-06-08 16:52:24 +0000448 return mem_size;
449
450}
451
Greg Clayton75ccf502010-08-21 02:22:51 +0000452void
453Block::AddChild(const BlockSP &child_block_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000454{
Greg Clayton75ccf502010-08-21 02:22:51 +0000455 if (child_block_sp)
456 {
457 Block *block_needs_sibling = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000458
Greg Clayton75ccf502010-08-21 02:22:51 +0000459 if (!m_children.empty())
460 block_needs_sibling = m_children.back().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000461
Greg Clayton75ccf502010-08-21 02:22:51 +0000462 child_block_sp->SetParentScope (this);
463 m_children.push_back (child_block_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000464
Greg Clayton75ccf502010-08-21 02:22:51 +0000465 if (block_needs_sibling)
466 block_needs_sibling->SetSibling (child_block_sp.get());
467 }
Chris Lattner24943d22010-06-08 16:52:24 +0000468}
469
470void
471Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
472{
473 m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
474}
475
Jim Ingham7382a532010-08-18 19:29:16 +0000476
477
478VariableListSP
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000479Block::GetBlockVariableList (bool can_create)
Jim Ingham7382a532010-08-18 19:29:16 +0000480{
Greg Clayton75ccf502010-08-21 02:22:51 +0000481 if (m_parsed_block_variables == false)
Jim Ingham7382a532010-08-18 19:29:16 +0000482 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000483 if (m_variable_list_sp.get() == NULL && can_create)
Greg Clayton75ccf502010-08-21 02:22:51 +0000484 {
485 m_parsed_block_variables = true;
486 SymbolContext sc;
487 CalculateSymbolContext(&sc);
488 assert(sc.module_sp);
489 sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
490 }
Jim Ingham7382a532010-08-18 19:29:16 +0000491 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000492 return m_variable_list_sp;
493}
Jim Ingham7382a532010-08-18 19:29:16 +0000494
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000495uint32_t
496Block::AppendBlockVariables (bool can_create,
497 bool get_child_block_variables,
498 bool stop_if_child_block_is_inlined_function,
499 VariableList *variable_list)
500{
501 uint32_t num_variables_added = 0;
502 VariableList *block_var_list = GetBlockVariableList (can_create).get();
503 if (block_var_list)
Jim Ingham7382a532010-08-18 19:29:16 +0000504 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000505 num_variables_added += block_var_list->GetSize();
506 variable_list->AddVariables (block_var_list);
507 }
508
509 if (get_child_block_variables)
510 {
511 for (Block *child_block = GetFirstChild();
512 child_block != NULL;
513 child_block = child_block->GetSibling())
514 {
515 if (stop_if_child_block_is_inlined_function == false ||
516 child_block->GetInlinedFunctionInfo() == NULL)
517 {
518 num_variables_added += child_block->AppendBlockVariables (can_create,
519 get_child_block_variables,
520 stop_if_child_block_is_inlined_function,
521 variable_list);
Jim Ingham7382a532010-08-18 19:29:16 +0000522 }
523 }
524 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000525 return num_variables_added;
Jim Ingham7382a532010-08-18 19:29:16 +0000526}
527
528uint32_t
Greg Clayton33ed1702010-08-24 00:45:41 +0000529Block::AppendVariables
530(
531 bool can_create,
532 bool get_parent_variables,
533 bool stop_if_block_is_inlined_function,
534 VariableList *variable_list
535)
Jim Ingham7382a532010-08-18 19:29:16 +0000536{
537 uint32_t num_variables_added = 0;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000538 VariableListSP variable_list_sp(GetBlockVariableList(can_create));
Jim Ingham7382a532010-08-18 19:29:16 +0000539
Greg Clayton69aa5d92010-09-07 04:20:48 +0000540 bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
Jim Ingham7382a532010-08-18 19:29:16 +0000541 if (variable_list_sp.get())
542 {
543 num_variables_added = variable_list_sp->GetSize();
544 variable_list->AddVariables(variable_list_sp.get());
545 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000546
Jim Ingham7382a532010-08-18 19:29:16 +0000547 if (get_parent_variables)
548 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000549 if (stop_if_block_is_inlined_function && is_inlined_function)
550 return num_variables_added;
551
Jim Ingham7382a532010-08-18 19:29:16 +0000552 Block* parent_block = GetParent();
553 if (parent_block)
Greg Clayton33ed1702010-08-24 00:45:41 +0000554 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 +0000555 }
556 return num_variables_added;
557}
558
Sean Callananc617a4c2011-08-05 23:43:37 +0000559clang::DeclContext *
560Block::GetClangDeclContextForInlinedFunction()
561{
562 SymbolContext sc;
563
564 CalculateSymbolContext (&sc);
565
566 if (!sc.module_sp)
567 return NULL;
568
569 SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
570
571 if (!sym_vendor)
572 return NULL;
573
574 SymbolFile *sym_file = sym_vendor->GetSymbolFile();
575
576 if (!sym_file)
577 return NULL;
578
579 return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
580}
581
Chris Lattner24943d22010-06-08 16:52:24 +0000582void
Greg Clayton75ccf502010-08-21 02:22:51 +0000583Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000584{
Greg Clayton75ccf502010-08-21 02:22:51 +0000585 m_parsed_block_info = b;
586 if (set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000587 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000588 m_parsed_child_blocks = true;
589 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
590 child_block->SetBlockInfoHasBeenParsed (b, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000591 }
Chris Lattner24943d22010-06-08 16:52:24 +0000592}
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000593
594void
595Block::SetDidParseVariables (bool b, bool set_children)
596{
597 m_parsed_block_variables = b;
598 if (set_children)
599 {
600 for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
601 child_block->SetDidParseVariables (b, true);
602 }
603}
604