blob: ed7772178f0253b316ff0d9db593c45b0bcd0802 [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),
Greg Clayton75ccf502010-08-21 02:22:51 +000024 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
Jason Molenda7e5fa7f2011-09-20 21:44:10 +000080 s->Printf("%p: ", this);
Chris Lattner24943d22010-06-08 16:52:24 +000081 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 Clayton2cd9fbd2011-09-29 21:19:25 +0000119 collection::const_iterator pos, end = m_children.end();
120 for (pos = m_children.begin(); pos != end; ++pos)
121 (*pos)->Dump(s, base_addr, depth - 1, show_context);
Chris Lattner24943d22010-06-08 16:52:24 +0000122
123 s->IndentLess();
124 }
125
126}
127
128
Greg Clayton75ccf502010-08-21 02:22:51 +0000129Block *
130Block::FindBlockByID (user_id_t block_id)
131{
132 if (block_id == GetID())
133 return this;
134
135 Block *matching_block = NULL;
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000136 collection::const_iterator pos, end = m_children.end();
137 for (pos = m_children.begin(); pos != end; ++pos)
Greg Clayton75ccf502010-08-21 02:22:51 +0000138 {
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000139 matching_block = (*pos)->FindBlockByID (block_id);
Greg Clayton75ccf502010-08-21 02:22:51 +0000140 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
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000154Module *
155Block::CalculateSymbolContextModule ()
156{
157 if (m_parent_scope)
158 return m_parent_scope->CalculateSymbolContextModule ();
159 return NULL;
160}
161
162CompileUnit *
163Block::CalculateSymbolContextCompileUnit ()
164{
165 if (m_parent_scope)
166 return m_parent_scope->CalculateSymbolContextCompileUnit ();
167 return NULL;
168}
169
170Function *
171Block::CalculateSymbolContextFunction ()
172{
173 if (m_parent_scope)
174 return m_parent_scope->CalculateSymbolContextFunction ();
175 return NULL;
176}
177
178Block *
179Block::CalculateSymbolContextBlock ()
180{
181 return this;
182}
183
Chris Lattner24943d22010-06-08 16:52:24 +0000184void
Greg Clayton69aa5d92010-09-07 04:20:48 +0000185Block::DumpStopContext
186(
187 Stream *s,
188 const SymbolContext *sc_ptr,
189 const Declaration *child_inline_call_site,
190 bool show_fullpaths,
191 bool show_inline_blocks)
Chris Lattner24943d22010-06-08 16:52:24 +0000192{
Greg Claytonff44ab42011-04-23 02:04:55 +0000193 const InlineFunctionInfo* inline_info = NULL;
194 Block* inlined_block;
195 if (sc_ptr)
196 inlined_block = GetContainingInlinedBlock ();
197 else
198 inlined_block = GetInlinedParent();
Chris Lattner24943d22010-06-08 16:52:24 +0000199
Greg Claytonff44ab42011-04-23 02:04:55 +0000200 if (inlined_block)
201 inline_info = inlined_block->GetInlinedFunctionInfo();
Greg Clayton69aa5d92010-09-07 04:20:48 +0000202 const Declaration *inline_call_site = child_inline_call_site;
Chris Lattner24943d22010-06-08 16:52:24 +0000203 if (inline_info)
204 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000205 inline_call_site = &inline_info->GetCallSite();
206 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000207 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000208 // First frame in a frame with inlined functions
Chris Lattner24943d22010-06-08 16:52:24 +0000209 s->PutCString (" [inlined]");
210 }
Greg Clayton3c126042011-02-08 02:40:32 +0000211 if (show_inline_blocks && child_inline_call_site)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000212 s->EOL();
213 else
214 s->PutChar(' ');
Greg Claytonff44ab42011-04-23 02:04:55 +0000215
216 if (sc_ptr == NULL)
217 s->Indent();
218
Greg Clayton69aa5d92010-09-07 04:20:48 +0000219 s->PutCString(inline_info->GetName ().AsCString());
220
221 if (child_inline_call_site && child_inline_call_site->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000222 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000223 s->PutCString(" at ");
224 child_inline_call_site->DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000225 }
226 }
227
Greg Claytonff44ab42011-04-23 02:04:55 +0000228 // The first call to this function from something that has a symbol
229 // context will pass in a valid sc_ptr. Subsequent calls to this function
230 // from this function for inline purposes will NULL out sc_ptr. So on the
231 // first time through we dump the line table entry (which is always at the
232 // deepest inline code block). And subsequent calls to this function we
233 // will use hte inline call site information to print line numbers.
Greg Clayton69aa5d92010-09-07 04:20:48 +0000234 if (sc_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000235 {
236 // If we have any inlined functions, this will be the deepest most
237 // inlined location
Greg Clayton69aa5d92010-09-07 04:20:48 +0000238 if (sc_ptr->line_entry.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000239 {
240 s->PutCString(" at ");
Greg Clayton69aa5d92010-09-07 04:20:48 +0000241 sc_ptr->line_entry.DumpStopContext (s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000242 }
243 }
Greg Clayton69aa5d92010-09-07 04:20:48 +0000244
245 if (show_inline_blocks)
246 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000247 if (inlined_block)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000248 {
Greg Claytonff44ab42011-04-23 02:04:55 +0000249 inlined_block->Block::DumpStopContext (s,
250 NULL,
251 inline_call_site,
252 show_fullpaths,
253 show_inline_blocks);
Greg Clayton69aa5d92010-09-07 04:20:48 +0000254 }
255 else if (child_inline_call_site)
256 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000257 Function *function = CalculateSymbolContextFunction();
258 if (function)
Greg Clayton69aa5d92010-09-07 04:20:48 +0000259 {
260 s->EOL();
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000261 s->Indent (function->GetMangled().GetName().AsCString());
Greg Clayton69aa5d92010-09-07 04:20:48 +0000262 if (child_inline_call_site && child_inline_call_site->IsValid())
263 {
264 s->PutCString(" at ");
265 child_inline_call_site->DumpStopContext (s, show_fullpaths);
266 }
267 }
268 }
269 }
Chris Lattner24943d22010-06-08 16:52:24 +0000270}
271
272
273void
274Block::DumpSymbolContext(Stream *s)
275{
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000276 Function *function = CalculateSymbolContextFunction();
277 if (function)
278 function->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +0000279 s->Printf(", Block{0x%8.8x}", GetID());
280}
281
Caroline Tice98f930f2010-09-20 05:20:02 +0000282void
283Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
284{
285 if (!m_ranges.empty())
286 {
287 std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
288 for (pos = m_ranges.begin(); pos != end; ++pos)
289 pos->Dump (s, base_addr);
290 }
291}
292
Chris Lattner24943d22010-06-08 16:52:24 +0000293bool
294Block::Contains (addr_t range_offset) const
295{
296 return VMRange::ContainsValue(m_ranges, range_offset);
297}
298
299bool
Greg Clayton72b71582010-09-02 21:44:10 +0000300Block::Contains (const Block *block) const
301{
Greg Clayton72b71582010-09-02 21:44:10 +0000302 if (this == block)
Greg Claytona357ecf2010-09-14 03:16:58 +0000303 return false; // This block doesn't contain itself...
Greg Clayton72b71582010-09-02 21:44:10 +0000304
Greg Claytona357ecf2010-09-14 03:16:58 +0000305 // Walk the parent chain for "block" and see if any if them match this block
Greg Clayton72b71582010-09-02 21:44:10 +0000306 const Block *block_parent;
307 for (block_parent = block->GetParent();
308 block_parent != NULL;
309 block_parent = block_parent->GetParent())
310 {
Greg Claytona357ecf2010-09-14 03:16:58 +0000311 if (this == block_parent)
312 return true; // One of the parents of "block" is this object!
Greg Clayton72b71582010-09-02 21:44:10 +0000313 }
314 return false;
315}
316
317bool
Chris Lattner24943d22010-06-08 16:52:24 +0000318Block::Contains (const VMRange& range) const
319{
320 return VMRange::ContainsRange(m_ranges, range);
321}
322
Greg Clayton75ccf502010-08-21 02:22:51 +0000323Block *
324Block::GetParent () const
Chris Lattner24943d22010-06-08 16:52:24 +0000325{
Greg Clayton75ccf502010-08-21 02:22:51 +0000326 if (m_parent_scope)
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000327 return m_parent_scope->CalculateSymbolContextBlock();
Greg Clayton75ccf502010-08-21 02:22:51 +0000328 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000329}
330
Greg Clayton33ed1702010-08-24 00:45:41 +0000331Block *
Greg Claytonb04e7a82010-08-24 21:05:24 +0000332Block::GetContainingInlinedBlock ()
333{
Greg Clayton69aa5d92010-09-07 04:20:48 +0000334 if (GetInlinedFunctionInfo())
Greg Claytonb04e7a82010-08-24 21:05:24 +0000335 return this;
336 return GetInlinedParent ();
337}
338
339Block *
340Block::GetInlinedParent ()
Greg Clayton33ed1702010-08-24 00:45:41 +0000341{
342 Block *parent_block = GetParent ();
343 if (parent_block)
344 {
Greg Clayton69aa5d92010-09-07 04:20:48 +0000345 if (parent_block->GetInlinedFunctionInfo())
Greg Clayton33ed1702010-08-24 00:45:41 +0000346 return parent_block;
347 else
348 return parent_block->GetInlinedParent();
349 }
350 return NULL;
351}
352
353
354bool
Greg Claytonb04e7a82010-08-24 21:05:24 +0000355Block::GetRangeContainingOffset (const addr_t offset, VMRange &range)
356{
357 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
358 if (range_idx < m_ranges.size())
359 {
360 range = m_ranges[range_idx];
361 return true;
362 }
363 range.Clear();
364 return false;
365}
366
367
368bool
Greg Clayton23b8abb2011-09-26 07:11:27 +0000369Block::GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr)
Greg Clayton33ed1702010-08-24 00:45:41 +0000370{
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000371 Function *function = CalculateSymbolContextFunction();
372 if (function)
Greg Clayton33ed1702010-08-24 00:45:41 +0000373 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000374 const AddressRange &func_range = function->GetAddressRange();
Greg Clayton33ed1702010-08-24 00:45:41 +0000375 if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
376 {
377 const addr_t addr_offset = addr.GetOffset();
378 const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
379 if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
380 {
381 addr_t offset = addr_offset - func_offset;
382
383 uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
384 if (range_idx < m_ranges.size())
385 {
386 range.GetBaseAddress() = func_range.GetBaseAddress();
387 range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress());
388 range.SetByteSize(m_ranges[range_idx].GetByteSize());
Greg Clayton23b8abb2011-09-26 07:11:27 +0000389 if (range_idx_ptr)
390 *range_idx_ptr = range_idx;
Greg Clayton33ed1702010-08-24 00:45:41 +0000391 return true;
392 }
393 }
394 }
395 }
Greg Clayton23b8abb2011-09-26 07:11:27 +0000396 if (range_idx_ptr)
397 *range_idx_ptr = UINT32_MAX;
Greg Clayton33ed1702010-08-24 00:45:41 +0000398 range.Clear();
399 return false;
400}
401
Greg Claytonff44ab42011-04-23 02:04:55 +0000402bool
403Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
404{
405 if (range_idx < m_ranges.size())
406 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000407 Function *function = CalculateSymbolContextFunction();
408 if (function)
Greg Claytonff44ab42011-04-23 02:04:55 +0000409 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000410 range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
Greg Claytonff44ab42011-04-23 02:04:55 +0000411 range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ());
412 range.SetByteSize (m_ranges[range_idx].GetByteSize());
413 return true;
414 }
415 }
416 return false;
417}
Greg Claytonfeb6e562010-11-14 00:22:48 +0000418
419bool
420Block::GetStartAddress (Address &addr)
421{
422 if (m_ranges.empty())
423 return false;
424
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000425 Function *function = CalculateSymbolContextFunction();
426 if (function)
Greg Claytonfeb6e562010-11-14 00:22:48 +0000427 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000428 addr = function->GetAddressRange().GetBaseAddress();
Greg Claytonfeb6e562010-11-14 00:22:48 +0000429 addr.Slide(m_ranges.front().GetBaseAddress ());
430 return true;
431 }
432 return false;
433}
434
Chris Lattner24943d22010-06-08 16:52:24 +0000435void
436Block::AddRange(addr_t start_offset, addr_t end_offset)
437{
438 m_ranges.resize(m_ranges.size()+1);
439 m_ranges.back().Reset(start_offset, end_offset);
440}
441
Chris Lattner24943d22010-06-08 16:52:24 +0000442// Return the current number of bytes that this object occupies in memory
443size_t
444Block::MemorySize() const
445{
446 size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange);
447 if (m_inlineInfoSP.get())
448 mem_size += m_inlineInfoSP->MemorySize();
Greg Claytonb04e7a82010-08-24 21:05:24 +0000449 if (m_variable_list_sp.get())
450 mem_size += m_variable_list_sp->MemorySize();
Chris Lattner24943d22010-06-08 16:52:24 +0000451 return mem_size;
452
453}
454
Greg Clayton75ccf502010-08-21 02:22:51 +0000455void
456Block::AddChild(const BlockSP &child_block_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000457{
Greg Clayton75ccf502010-08-21 02:22:51 +0000458 if (child_block_sp)
459 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000460 child_block_sp->SetParentScope (this);
461 m_children.push_back (child_block_sp);
Greg Clayton75ccf502010-08-21 02:22:51 +0000462 }
Chris Lattner24943d22010-06-08 16:52:24 +0000463}
464
465void
466Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
467{
468 m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
469}
470
Jim Ingham7382a532010-08-18 19:29:16 +0000471
472
473VariableListSP
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000474Block::GetBlockVariableList (bool can_create)
Jim Ingham7382a532010-08-18 19:29:16 +0000475{
Greg Clayton75ccf502010-08-21 02:22:51 +0000476 if (m_parsed_block_variables == false)
Jim Ingham7382a532010-08-18 19:29:16 +0000477 {
Greg Claytonb04e7a82010-08-24 21:05:24 +0000478 if (m_variable_list_sp.get() == NULL && can_create)
Greg Clayton75ccf502010-08-21 02:22:51 +0000479 {
480 m_parsed_block_variables = true;
481 SymbolContext sc;
482 CalculateSymbolContext(&sc);
483 assert(sc.module_sp);
484 sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
485 }
Jim Ingham7382a532010-08-18 19:29:16 +0000486 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000487 return m_variable_list_sp;
488}
Jim Ingham7382a532010-08-18 19:29:16 +0000489
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000490uint32_t
491Block::AppendBlockVariables (bool can_create,
492 bool get_child_block_variables,
493 bool stop_if_child_block_is_inlined_function,
494 VariableList *variable_list)
495{
496 uint32_t num_variables_added = 0;
497 VariableList *block_var_list = GetBlockVariableList (can_create).get();
498 if (block_var_list)
Jim Ingham7382a532010-08-18 19:29:16 +0000499 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000500 num_variables_added += block_var_list->GetSize();
501 variable_list->AddVariables (block_var_list);
502 }
503
504 if (get_child_block_variables)
505 {
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000506 collection::const_iterator pos, end = m_children.end();
507 for (pos = m_children.begin(); pos != end; ++pos)
508 {
509 Block *child_block = pos->get();
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000510 if (stop_if_child_block_is_inlined_function == false ||
511 child_block->GetInlinedFunctionInfo() == NULL)
512 {
513 num_variables_added += child_block->AppendBlockVariables (can_create,
514 get_child_block_variables,
515 stop_if_child_block_is_inlined_function,
516 variable_list);
Jim Ingham7382a532010-08-18 19:29:16 +0000517 }
518 }
519 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000520 return num_variables_added;
Jim Ingham7382a532010-08-18 19:29:16 +0000521}
522
523uint32_t
Greg Clayton33ed1702010-08-24 00:45:41 +0000524Block::AppendVariables
525(
526 bool can_create,
527 bool get_parent_variables,
528 bool stop_if_block_is_inlined_function,
529 VariableList *variable_list
530)
Jim Ingham7382a532010-08-18 19:29:16 +0000531{
532 uint32_t num_variables_added = 0;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000533 VariableListSP variable_list_sp(GetBlockVariableList(can_create));
Jim Ingham7382a532010-08-18 19:29:16 +0000534
Greg Clayton69aa5d92010-09-07 04:20:48 +0000535 bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
Jim Ingham7382a532010-08-18 19:29:16 +0000536 if (variable_list_sp.get())
537 {
538 num_variables_added = variable_list_sp->GetSize();
539 variable_list->AddVariables(variable_list_sp.get());
540 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000541
Jim Ingham7382a532010-08-18 19:29:16 +0000542 if (get_parent_variables)
543 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000544 if (stop_if_block_is_inlined_function && is_inlined_function)
545 return num_variables_added;
546
Jim Ingham7382a532010-08-18 19:29:16 +0000547 Block* parent_block = GetParent();
548 if (parent_block)
Greg Clayton33ed1702010-08-24 00:45:41 +0000549 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 +0000550 }
551 return num_variables_added;
552}
553
Sean Callananc617a4c2011-08-05 23:43:37 +0000554clang::DeclContext *
555Block::GetClangDeclContextForInlinedFunction()
556{
557 SymbolContext sc;
558
559 CalculateSymbolContext (&sc);
560
561 if (!sc.module_sp)
562 return NULL;
563
564 SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
565
566 if (!sym_vendor)
567 return NULL;
568
569 SymbolFile *sym_file = sym_vendor->GetSymbolFile();
570
571 if (!sym_file)
572 return NULL;
573
574 return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
575}
576
Chris Lattner24943d22010-06-08 16:52:24 +0000577void
Greg Clayton75ccf502010-08-21 02:22:51 +0000578Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000579{
Greg Clayton75ccf502010-08-21 02:22:51 +0000580 m_parsed_block_info = b;
581 if (set_children)
Chris Lattner24943d22010-06-08 16:52:24 +0000582 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000583 m_parsed_child_blocks = true;
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000584 collection::const_iterator pos, end = m_children.end();
585 for (pos = m_children.begin(); pos != end; ++pos)
586 (*pos)->SetBlockInfoHasBeenParsed (b, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000587 }
Chris Lattner24943d22010-06-08 16:52:24 +0000588}
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000589
590void
591Block::SetDidParseVariables (bool b, bool set_children)
592{
593 m_parsed_block_variables = b;
594 if (set_children)
595 {
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000596 collection::const_iterator pos, end = m_children.end();
597 for (pos = m_children.begin(); pos != end; ++pos)
598 (*pos)->SetDidParseVariables (b, true);
Greg Clayton1bd2b2f2011-06-17 22:10:16 +0000599 }
600}
601
Greg Clayton2cd9fbd2011-09-29 21:19:25 +0000602
603Block *
604Block::GetSibling() const
605{
606 if (m_parent_scope)
607 {
608 Block *parent_block = m_parent_scope->CalculateSymbolContextBlock();
609 if (parent_block)
610 return parent_block->GetSiblingForChild (this);
611 }
612 return NULL;
613}
614// A parent of child blocks can be asked to find a sibling block given
615// one of its child blocks
616Block *
617Block::GetSiblingForChild (const Block *child_block) const
618{
619 if (!m_children.empty())
620 {
621 collection::const_iterator pos, end = m_children.end();
622 for (pos = m_children.begin(); pos != end; ++pos)
623 {
624 if (pos->get() == child_block)
625 {
626 if (++pos != end)
627 return pos->get();
628 break;
629 }
630 }
631 }
632 return NULL;
633}
634