blob: f410bd62de3a099809fcce365f9ac3cbfa06b767 [file] [log] [blame]
Chris Lattner30fdc8d2010-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"
Greg Clayton6c7f5612011-09-29 23:41:34 +000011
12#include "lldb/lldb-private-log.h"
13
14#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/Section.h"
Greg Clayton6c7f5612011-09-29 23:41:34 +000017#include "lldb/Symbol/Function.h"
Sean Callanan72e49402011-08-05 23:43:37 +000018#include "lldb/Symbol/SymbolFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Symbol/SymbolVendor.h"
20#include "lldb/Symbol/VariableList.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
Greg Clayton0b76a2c2010-08-21 02:22:51 +000025Block::Block(lldb::user_id_t uid) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026 UserID(uid),
Greg Clayton0b76a2c2010-08-21 02:22:51 +000027 m_parent_scope (NULL),
Greg Clayton0b76a2c2010-08-21 02:22:51 +000028 m_children (),
29 m_ranges (),
30 m_inlineInfoSP (),
Greg Clayton9da7bd02010-08-24 21:05:24 +000031 m_variable_list_sp (),
Greg Clayton0b76a2c2010-08-21 02:22:51 +000032 m_parsed_block_info (false),
33 m_parsed_block_variables (false),
34 m_parsed_child_blocks (false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035{
36}
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038Block::~Block ()
39{
40}
41
42void
Greg Claytonf5e56de2010-09-14 23:36:40 +000043Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +000044{
Greg Claytonc9800662010-09-10 01:30:46 +000045 *s << "id = " << ((const UserID&)*this);
46
Greg Claytonea3e7d52011-10-08 00:49:15 +000047 size_t num_ranges = m_ranges.GetSize();
48 if (num_ranges > 0)
Greg Clayton0c5cd902010-06-28 21:30:43 +000049 {
50
51 addr_t base_addr = LLDB_INVALID_ADDRESS;
Greg Claytonf5e56de2010-09-14 23:36:40 +000052 if (target)
53 base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
Greg Clayton0c5cd902010-06-28 21:30:43 +000054 if (base_addr == LLDB_INVALID_ADDRESS)
Greg Clayton0b76a2c2010-08-21 02:22:51 +000055 base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
Greg Clayton0c5cd902010-06-28 21:30:43 +000056
Greg Claytonc9800662010-09-10 01:30:46 +000057 s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
Greg Claytonea3e7d52011-10-08 00:49:15 +000058 for (size_t i=0; i<num_ranges; ++i)
59 {
60 const Range &range = m_ranges.GetEntryRef(i);
61 s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
62 }
Greg Clayton0c5cd902010-06-28 21:30:43 +000063 }
Greg Clayton0c5cd902010-06-28 21:30:43 +000064
65 if (m_inlineInfoSP.get() != NULL)
Greg Clayton6dbd3982010-09-15 05:51:24 +000066 {
67 bool show_fullpaths = (level == eDescriptionLevelVerbose);
68 m_inlineInfoSP->Dump(s, show_fullpaths);
69 }
Greg Clayton0c5cd902010-06-28 21:30:43 +000070}
71
72void
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
74{
75 if (depth < 0)
76 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +000077 Block *parent = GetParent();
78 if (parent)
79 {
80 // We have a depth that is less than zero, print our parent blocks
81 // first
82 parent->Dump(s, base_addr, depth + 1, show_context);
83 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 }
85
Jason Molendafd54b362011-09-20 21:44:10 +000086 s->Printf("%p: ", this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 s->Indent();
88 *s << "Block" << ((const UserID&)*this);
Greg Clayton0c5cd902010-06-28 21:30:43 +000089 const Block* parent_block = GetParent();
90 if (parent_block)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091 {
Daniel Malead01b2952012-11-29 21:49:15 +000092 s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 }
94 if (m_inlineInfoSP.get() != NULL)
Greg Clayton6dbd3982010-09-15 05:51:24 +000095 {
96 bool show_fullpaths = false;
97 m_inlineInfoSP->Dump(s, show_fullpaths);
98 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099
Greg Claytonea3e7d52011-10-08 00:49:15 +0000100 if (!m_ranges.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 {
102 *s << ", ranges =";
Greg Claytonea3e7d52011-10-08 00:49:15 +0000103
104 size_t num_ranges = m_ranges.GetSize();
105 for (size_t i=0; i<num_ranges; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000107 const Range &range = m_ranges.GetEntryRef(i);
108 if (parent_block != NULL && parent_block->Contains(range) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109 *s << '!';
110 else
111 *s << ' ';
Greg Claytonea3e7d52011-10-08 00:49:15 +0000112 s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113 }
114 }
115 s->EOL();
116
117 if (depth > 0)
118 {
119 s->IndentMore();
120
Greg Clayton9da7bd02010-08-24 21:05:24 +0000121 if (m_variable_list_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000123 m_variable_list_sp->Dump(s, show_context);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124 }
125
Greg Clayton624784a2011-09-29 21:19:25 +0000126 collection::const_iterator pos, end = m_children.end();
127 for (pos = m_children.begin(); pos != end; ++pos)
128 (*pos)->Dump(s, base_addr, depth - 1, show_context);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129
130 s->IndentLess();
131 }
132
133}
134
135
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000136Block *
137Block::FindBlockByID (user_id_t block_id)
138{
139 if (block_id == GetID())
140 return this;
141
142 Block *matching_block = NULL;
Greg Clayton624784a2011-09-29 21:19:25 +0000143 collection::const_iterator pos, end = m_children.end();
144 for (pos = m_children.begin(); pos != end; ++pos)
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000145 {
Greg Clayton624784a2011-09-29 21:19:25 +0000146 matching_block = (*pos)->FindBlockByID (block_id);
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000147 if (matching_block)
148 break;
149 }
150 return matching_block;
151}
152
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153void
Greg Clayton9da7bd02010-08-24 21:05:24 +0000154Block::CalculateSymbolContext (SymbolContext* sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000156 if (m_parent_scope)
157 m_parent_scope->CalculateSymbolContext(sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 sc->block = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
Greg Claytone72dfb32012-02-24 01:59:29 +0000161lldb::ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000162Block::CalculateSymbolContextModule ()
163{
164 if (m_parent_scope)
165 return m_parent_scope->CalculateSymbolContextModule ();
Greg Claytone72dfb32012-02-24 01:59:29 +0000166 return lldb::ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000167}
168
169CompileUnit *
170Block::CalculateSymbolContextCompileUnit ()
171{
172 if (m_parent_scope)
173 return m_parent_scope->CalculateSymbolContextCompileUnit ();
174 return NULL;
175}
176
177Function *
178Block::CalculateSymbolContextFunction ()
179{
180 if (m_parent_scope)
181 return m_parent_scope->CalculateSymbolContextFunction ();
182 return NULL;
183}
184
185Block *
186Block::CalculateSymbolContextBlock ()
187{
188 return this;
189}
190
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192Block::DumpSymbolContext(Stream *s)
193{
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000194 Function *function = CalculateSymbolContextFunction();
195 if (function)
196 function->DumpSymbolContext(s);
Daniel Malead01b2952012-11-29 21:49:15 +0000197 s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198}
199
Caroline Ticedde9cff2010-09-20 05:20:02 +0000200void
201Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
202{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000203 if (!m_ranges.IsEmpty())
Caroline Ticedde9cff2010-09-20 05:20:02 +0000204 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000205 size_t num_ranges = m_ranges.GetSize();
206 for (size_t i=0; i<num_ranges; ++i)
207 {
208 const Range &range = m_ranges.GetEntryRef(i);
209 s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
210 }
Caroline Ticedde9cff2010-09-20 05:20:02 +0000211 }
212}
213
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214bool
215Block::Contains (addr_t range_offset) const
216{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000217 return m_ranges.FindEntryThatContains(range_offset) != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218}
219
220bool
Greg Clayton6dadd502010-09-02 21:44:10 +0000221Block::Contains (const Block *block) const
222{
Greg Clayton6dadd502010-09-02 21:44:10 +0000223 if (this == block)
Greg Clayton6f00abd2010-09-14 03:16:58 +0000224 return false; // This block doesn't contain itself...
Greg Clayton6dadd502010-09-02 21:44:10 +0000225
Greg Clayton6f00abd2010-09-14 03:16:58 +0000226 // Walk the parent chain for "block" and see if any if them match this block
Greg Clayton6dadd502010-09-02 21:44:10 +0000227 const Block *block_parent;
228 for (block_parent = block->GetParent();
229 block_parent != NULL;
230 block_parent = block_parent->GetParent())
231 {
Greg Clayton6f00abd2010-09-14 03:16:58 +0000232 if (this == block_parent)
233 return true; // One of the parents of "block" is this object!
Greg Clayton6dadd502010-09-02 21:44:10 +0000234 }
235 return false;
236}
237
238bool
Greg Claytonea3e7d52011-10-08 00:49:15 +0000239Block::Contains (const Range& range) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000241 return m_ranges.FindEntryThatContains (range) != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242}
243
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000244Block *
245Block::GetParent () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000247 if (m_parent_scope)
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000248 return m_parent_scope->CalculateSymbolContextBlock();
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000249 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250}
251
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000252Block *
Greg Clayton9da7bd02010-08-24 21:05:24 +0000253Block::GetContainingInlinedBlock ()
254{
Greg Clayton95897c62010-09-07 04:20:48 +0000255 if (GetInlinedFunctionInfo())
Greg Clayton9da7bd02010-08-24 21:05:24 +0000256 return this;
257 return GetInlinedParent ();
258}
259
260Block *
261Block::GetInlinedParent ()
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000262{
263 Block *parent_block = GetParent ();
264 if (parent_block)
265 {
Greg Clayton95897c62010-09-07 04:20:48 +0000266 if (parent_block->GetInlinedFunctionInfo())
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000267 return parent_block;
268 else
269 return parent_block->GetInlinedParent();
270 }
271 return NULL;
272}
273
274
275bool
Greg Claytonea3e7d52011-10-08 00:49:15 +0000276Block::GetRangeContainingOffset (const addr_t offset, Range &range)
Greg Clayton9da7bd02010-08-24 21:05:24 +0000277{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000278 const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
279 if (range_ptr)
Greg Clayton9da7bd02010-08-24 21:05:24 +0000280 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000281 range = *range_ptr;
Greg Clayton9da7bd02010-08-24 21:05:24 +0000282 return true;
283 }
284 range.Clear();
285 return false;
286}
287
288
289bool
Greg Claytonea3e7d52011-10-08 00:49:15 +0000290Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000291{
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000292 Function *function = CalculateSymbolContextFunction();
293 if (function)
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000294 {
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000295 const AddressRange &func_range = function->GetAddressRange();
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000296 if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
297 {
298 const addr_t addr_offset = addr.GetOffset();
299 const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
300 if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
301 {
302 addr_t offset = addr_offset - func_offset;
303
Greg Claytonea3e7d52011-10-08 00:49:15 +0000304 const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
305
306 if (range_ptr)
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000307 {
308 range.GetBaseAddress() = func_range.GetBaseAddress();
Greg Claytonea3e7d52011-10-08 00:49:15 +0000309 range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
310 range.SetByteSize(range_ptr->GetByteSize());
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000311 return true;
312 }
313 }
314 }
315 }
316 range.Clear();
317 return false;
318}
319
Jim Inghamfcb59bc2012-08-31 23:49:32 +0000320bool
321Block::GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range)
322{
323 Address load_address;
324 load_address.SetLoadAddress(load_addr, &target);
325 AddressRange containing_range;
326 return GetRangeContainingAddress(load_address, containing_range);
327}
328
329
Greg Claytonea3e7d52011-10-08 00:49:15 +0000330uint32_t
331Block::GetRangeIndexContainingAddress (const Address& addr)
332{
333 Function *function = CalculateSymbolContextFunction();
334 if (function)
335 {
336 const AddressRange &func_range = function->GetAddressRange();
337 if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
338 {
339 const addr_t addr_offset = addr.GetOffset();
340 const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
341 if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
342 {
343 addr_t offset = addr_offset - func_offset;
344 return m_ranges.FindEntryIndexThatContains (offset);
345 }
346 }
347 }
348 return UINT32_MAX;
349}
350
Greg Clayton7e14f912011-04-23 02:04:55 +0000351bool
352Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
353{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000354 if (range_idx < m_ranges.GetSize())
Greg Clayton7e14f912011-04-23 02:04:55 +0000355 {
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000356 Function *function = CalculateSymbolContextFunction();
357 if (function)
Greg Clayton7e14f912011-04-23 02:04:55 +0000358 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000359 const Range &vm_range = m_ranges.GetEntryRef(range_idx);
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000360 range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
Greg Claytonea3e7d52011-10-08 00:49:15 +0000361 range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
362 range.SetByteSize (vm_range.GetByteSize());
Greg Clayton7e14f912011-04-23 02:04:55 +0000363 return true;
364 }
365 }
366 return false;
367}
Greg Claytond7e05462010-11-14 00:22:48 +0000368
369bool
370Block::GetStartAddress (Address &addr)
371{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000372 if (m_ranges.IsEmpty())
Greg Claytond7e05462010-11-14 00:22:48 +0000373 return false;
374
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000375 Function *function = CalculateSymbolContextFunction();
376 if (function)
Greg Claytond7e05462010-11-14 00:22:48 +0000377 {
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000378 addr = function->GetAddressRange().GetBaseAddress();
Greg Claytonea3e7d52011-10-08 00:49:15 +0000379 addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ());
Greg Claytond7e05462010-11-14 00:22:48 +0000380 return true;
381 }
382 return false;
383}
384
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385void
Greg Claytonea3e7d52011-10-08 00:49:15 +0000386Block::FinalizeRanges ()
387{
388 m_ranges.Sort();
389 m_ranges.CombineConsecutiveRanges ();
390}
391
392void
393Block::AddRange (const Range& range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394{
Greg Clayton6c7f5612011-09-29 23:41:34 +0000395 Block *parent_block = GetParent ();
Greg Claytonea3e7d52011-10-08 00:49:15 +0000396 if (parent_block && !parent_block->Contains(range))
Greg Clayton6c7f5612011-09-29 23:41:34 +0000397 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000398 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton6c7f5612011-09-29 23:41:34 +0000399 if (log)
400 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000401 ModuleSP module_sp (m_parent_scope->CalculateSymbolContextModule());
Greg Clayton6c7f5612011-09-29 23:41:34 +0000402 Function *function = m_parent_scope->CalculateSymbolContextFunction();
403 const addr_t function_file_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
Greg Claytonea3e7d52011-10-08 00:49:15 +0000404 const addr_t block_start_addr = function_file_addr + range.GetRangeBase ();
405 const addr_t block_end_addr = function_file_addr + range.GetRangeEnd ();
Greg Clayton6c7f5612011-09-29 23:41:34 +0000406 Type *func_type = function->GetType();
407
408 const Declaration &func_decl = func_type->GetDeclaration();
409 if (func_decl.GetLine())
410 {
Daniel Malead01b2952012-11-29 21:49:15 +0000411 log->Printf ("warning: %s/%s:%u block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s/%s",
Greg Clayton6c7f5612011-09-29 23:41:34 +0000412 func_decl.GetFile().GetDirectory().GetCString(),
413 func_decl.GetFile().GetFilename().GetCString(),
414 func_decl.GetLine(),
415 GetID(),
Greg Claytonea3e7d52011-10-08 00:49:15 +0000416 (uint32_t)m_ranges.GetSize(),
Greg Clayton6c7f5612011-09-29 23:41:34 +0000417 block_start_addr,
418 block_end_addr,
419 parent_block->GetID(),
420 function->GetID(),
Greg Claytone72dfb32012-02-24 01:59:29 +0000421 module_sp->GetFileSpec().GetDirectory().GetCString(),
422 module_sp->GetFileSpec().GetFilename().GetCString());
Greg Clayton6c7f5612011-09-29 23:41:34 +0000423 }
424 else
425 {
Daniel Malead01b2952012-11-29 21:49:15 +0000426 log->Printf ("warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s/%s",
Greg Clayton6c7f5612011-09-29 23:41:34 +0000427 GetID(),
Greg Claytonea3e7d52011-10-08 00:49:15 +0000428 (uint32_t)m_ranges.GetSize(),
Greg Clayton6c7f5612011-09-29 23:41:34 +0000429 block_start_addr,
430 block_end_addr,
431 parent_block->GetID(),
432 function->GetID(),
Greg Claytone72dfb32012-02-24 01:59:29 +0000433 module_sp->GetFileSpec().GetDirectory().GetCString(),
434 module_sp->GetFileSpec().GetFilename().GetCString());
Greg Clayton6c7f5612011-09-29 23:41:34 +0000435 }
436 }
Greg Claytonea3e7d52011-10-08 00:49:15 +0000437 parent_block->AddRange (range);
Greg Clayton6c7f5612011-09-29 23:41:34 +0000438 }
Greg Claytonea3e7d52011-10-08 00:49:15 +0000439 m_ranges.Append(range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440}
441
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442// Return the current number of bytes that this object occupies in memory
443size_t
444Block::MemorySize() const
445{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000446 size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447 if (m_inlineInfoSP.get())
448 mem_size += m_inlineInfoSP->MemorySize();
Greg Clayton9da7bd02010-08-24 21:05:24 +0000449 if (m_variable_list_sp.get())
450 mem_size += m_variable_list_sp->MemorySize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 return mem_size;
452
453}
454
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000455void
456Block::AddChild(const BlockSP &child_block_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000458 if (child_block_sp)
459 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000460 child_block_sp->SetParentScope (this);
461 m_children.push_back (child_block_sp);
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000462 }
Chris Lattner30fdc8d2010-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 Inghame1be14d2010-08-18 19:29:16 +0000471
472
473VariableListSP
Greg Claytonc662ec82011-06-17 22:10:16 +0000474Block::GetBlockVariableList (bool can_create)
Jim Inghame1be14d2010-08-18 19:29:16 +0000475{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000476 if (m_parsed_block_variables == false)
Jim Inghame1be14d2010-08-18 19:29:16 +0000477 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000478 if (m_variable_list_sp.get() == NULL && can_create)
Greg Clayton0b76a2c2010-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 Inghame1be14d2010-08-18 19:29:16 +0000486 }
Greg Claytonc662ec82011-06-17 22:10:16 +0000487 return m_variable_list_sp;
488}
Jim Inghame1be14d2010-08-18 19:29:16 +0000489
Greg Claytonc662ec82011-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 Inghame1be14d2010-08-18 19:29:16 +0000499 {
Greg Claytonc662ec82011-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 Clayton624784a2011-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 Claytonc662ec82011-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 Inghame1be14d2010-08-18 19:29:16 +0000517 }
518 }
519 }
Greg Claytonc662ec82011-06-17 22:10:16 +0000520 return num_variables_added;
Jim Inghame1be14d2010-08-18 19:29:16 +0000521}
522
523uint32_t
Greg Clayton1b72fcb2010-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 Inghame1be14d2010-08-18 19:29:16 +0000531{
532 uint32_t num_variables_added = 0;
Greg Claytonc662ec82011-06-17 22:10:16 +0000533 VariableListSP variable_list_sp(GetBlockVariableList(can_create));
Jim Inghame1be14d2010-08-18 19:29:16 +0000534
Greg Clayton95897c62010-09-07 04:20:48 +0000535 bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
Jim Inghame1be14d2010-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 Clayton1b72fcb2010-08-24 00:45:41 +0000541
Jim Inghame1be14d2010-08-18 19:29:16 +0000542 if (get_parent_variables)
543 {
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000544 if (stop_if_block_is_inlined_function && is_inlined_function)
545 return num_variables_added;
546
Jim Inghame1be14d2010-08-18 19:29:16 +0000547 Block* parent_block = GetParent();
548 if (parent_block)
Greg Clayton1b72fcb2010-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 Inghame1be14d2010-08-18 19:29:16 +0000550 }
551 return num_variables_added;
552}
553
Sean Callanan72e49402011-08-05 23:43:37 +0000554clang::DeclContext *
Greg Clayton685c88c2012-07-14 00:53:55 +0000555Block::GetClangDeclContext()
Sean Callanan72e49402011-08-05 23:43:37 +0000556{
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 Lattner30fdc8d2010-06-08 16:52:24 +0000577void
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000578Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000580 m_parsed_block_info = b;
581 if (set_children)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000583 m_parsed_child_blocks = true;
Greg Clayton624784a2011-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 Lattner30fdc8d2010-06-08 16:52:24 +0000587 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588}
Greg Claytonc662ec82011-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 Clayton624784a2011-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 Claytonc662ec82011-06-17 22:10:16 +0000599 }
600}
601
Greg Clayton624784a2011-09-29 21:19:25 +0000602
603Block *
604Block::GetSibling() const
605{
606 if (m_parent_scope)
607 {
Greg Clayton6c7f5612011-09-29 23:41:34 +0000608 Block *parent_block = GetParent();
Greg Clayton624784a2011-09-29 21:19:25 +0000609 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