1254721Semaste//===-- Block.cpp -----------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Symbol/Block.h"
11254721Semaste
12254721Semaste#include "lldb/lldb-private-log.h"
13254721Semaste
14254721Semaste#include "lldb/Core/Log.h"
15254721Semaste#include "lldb/Core/Module.h"
16254721Semaste#include "lldb/Core/Section.h"
17254721Semaste#include "lldb/Symbol/Function.h"
18254721Semaste#include "lldb/Symbol/SymbolFile.h"
19254721Semaste#include "lldb/Symbol/SymbolVendor.h"
20254721Semaste#include "lldb/Symbol/VariableList.h"
21254721Semaste
22254721Semasteusing namespace lldb;
23254721Semasteusing namespace lldb_private;
24254721Semaste
25254721SemasteBlock::Block(lldb::user_id_t uid) :
26254721Semaste    UserID(uid),
27254721Semaste    m_parent_scope (NULL),
28254721Semaste    m_children (),
29254721Semaste    m_ranges (),
30254721Semaste    m_inlineInfoSP (),
31254721Semaste    m_variable_list_sp (),
32254721Semaste    m_parsed_block_info (false),
33254721Semaste    m_parsed_block_variables (false),
34254721Semaste    m_parsed_child_blocks (false)
35254721Semaste{
36254721Semaste}
37254721Semaste
38254721SemasteBlock::~Block ()
39254721Semaste{
40254721Semaste}
41254721Semaste
42254721Semastevoid
43254721SemasteBlock::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
44254721Semaste{
45254721Semaste    *s << "id = " << ((const UserID&)*this);
46254721Semaste
47254721Semaste    size_t num_ranges = m_ranges.GetSize();
48254721Semaste    if (num_ranges > 0)
49254721Semaste    {
50254721Semaste
51254721Semaste        addr_t base_addr = LLDB_INVALID_ADDRESS;
52254721Semaste        if (target)
53254721Semaste            base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
54254721Semaste        if (base_addr == LLDB_INVALID_ADDRESS)
55254721Semaste            base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
56254721Semaste
57254721Semaste        s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
58254721Semaste        for (size_t i=0; i<num_ranges; ++i)
59254721Semaste        {
60254721Semaste            const Range &range = m_ranges.GetEntryRef(i);
61254721Semaste            s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
62254721Semaste        }
63254721Semaste    }
64254721Semaste
65254721Semaste    if (m_inlineInfoSP.get() != NULL)
66254721Semaste    {
67254721Semaste        bool show_fullpaths = (level == eDescriptionLevelVerbose);
68254721Semaste        m_inlineInfoSP->Dump(s, show_fullpaths);
69254721Semaste    }
70254721Semaste}
71254721Semaste
72254721Semastevoid
73254721SemasteBlock::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
74254721Semaste{
75254721Semaste    if (depth < 0)
76254721Semaste    {
77254721Semaste        Block *parent = GetParent();
78254721Semaste        if (parent)
79254721Semaste        {
80254721Semaste            // We have a depth that is less than zero, print our parent blocks
81254721Semaste            // first
82254721Semaste            parent->Dump(s, base_addr, depth + 1, show_context);
83254721Semaste        }
84254721Semaste    }
85254721Semaste
86254721Semaste    s->Printf("%p: ", this);
87254721Semaste    s->Indent();
88254721Semaste    *s << "Block" << ((const UserID&)*this);
89254721Semaste    const Block* parent_block = GetParent();
90254721Semaste    if (parent_block)
91254721Semaste    {
92254721Semaste        s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
93254721Semaste    }
94254721Semaste    if (m_inlineInfoSP.get() != NULL)
95254721Semaste    {
96254721Semaste        bool show_fullpaths = false;
97254721Semaste        m_inlineInfoSP->Dump(s, show_fullpaths);
98254721Semaste    }
99254721Semaste
100254721Semaste    if (!m_ranges.IsEmpty())
101254721Semaste    {
102254721Semaste        *s << ", ranges =";
103254721Semaste
104254721Semaste        size_t num_ranges = m_ranges.GetSize();
105254721Semaste        for (size_t i=0; i<num_ranges; ++i)
106254721Semaste        {
107254721Semaste            const Range &range = m_ranges.GetEntryRef(i);
108254721Semaste            if (parent_block != NULL && parent_block->Contains(range) == false)
109254721Semaste                *s << '!';
110254721Semaste            else
111254721Semaste                *s << ' ';
112254721Semaste            s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
113254721Semaste        }
114254721Semaste    }
115254721Semaste    s->EOL();
116254721Semaste
117254721Semaste    if (depth > 0)
118254721Semaste    {
119254721Semaste        s->IndentMore();
120254721Semaste
121254721Semaste        if (m_variable_list_sp.get())
122254721Semaste        {
123254721Semaste            m_variable_list_sp->Dump(s, show_context);
124254721Semaste        }
125254721Semaste
126254721Semaste        collection::const_iterator pos, end = m_children.end();
127254721Semaste        for (pos = m_children.begin(); pos != end; ++pos)
128254721Semaste            (*pos)->Dump(s, base_addr, depth - 1, show_context);
129254721Semaste
130254721Semaste        s->IndentLess();
131254721Semaste    }
132254721Semaste
133254721Semaste}
134254721Semaste
135254721Semaste
136254721SemasteBlock *
137254721SemasteBlock::FindBlockByID (user_id_t block_id)
138254721Semaste{
139254721Semaste    if (block_id == GetID())
140254721Semaste        return this;
141254721Semaste
142254721Semaste    Block *matching_block = NULL;
143254721Semaste    collection::const_iterator pos, end = m_children.end();
144254721Semaste    for (pos = m_children.begin(); pos != end; ++pos)
145254721Semaste    {
146254721Semaste        matching_block = (*pos)->FindBlockByID (block_id);
147254721Semaste        if (matching_block)
148254721Semaste            break;
149254721Semaste    }
150254721Semaste    return matching_block;
151254721Semaste}
152254721Semaste
153254721Semastevoid
154254721SemasteBlock::CalculateSymbolContext (SymbolContext* sc)
155254721Semaste{
156254721Semaste    if (m_parent_scope)
157254721Semaste        m_parent_scope->CalculateSymbolContext(sc);
158254721Semaste    sc->block = this;
159254721Semaste}
160254721Semaste
161254721Semastelldb::ModuleSP
162254721SemasteBlock::CalculateSymbolContextModule ()
163254721Semaste{
164254721Semaste    if (m_parent_scope)
165254721Semaste        return m_parent_scope->CalculateSymbolContextModule ();
166254721Semaste    return lldb::ModuleSP();
167254721Semaste}
168254721Semaste
169254721SemasteCompileUnit *
170254721SemasteBlock::CalculateSymbolContextCompileUnit ()
171254721Semaste{
172254721Semaste    if (m_parent_scope)
173254721Semaste        return m_parent_scope->CalculateSymbolContextCompileUnit ();
174254721Semaste    return NULL;
175254721Semaste}
176254721Semaste
177254721SemasteFunction *
178254721SemasteBlock::CalculateSymbolContextFunction ()
179254721Semaste{
180254721Semaste    if (m_parent_scope)
181254721Semaste        return m_parent_scope->CalculateSymbolContextFunction ();
182254721Semaste    return NULL;
183254721Semaste}
184254721Semaste
185254721SemasteBlock *
186254721SemasteBlock::CalculateSymbolContextBlock ()
187254721Semaste{
188254721Semaste    return this;
189254721Semaste}
190254721Semaste
191254721Semastevoid
192254721SemasteBlock::DumpSymbolContext(Stream *s)
193254721Semaste{
194254721Semaste    Function *function = CalculateSymbolContextFunction();
195254721Semaste    if (function)
196254721Semaste        function->DumpSymbolContext(s);
197254721Semaste    s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
198254721Semaste}
199254721Semaste
200254721Semastevoid
201254721SemasteBlock::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
202254721Semaste{
203254721Semaste    if (!m_ranges.IsEmpty())
204254721Semaste    {
205254721Semaste        size_t num_ranges = m_ranges.GetSize();
206254721Semaste        for (size_t i=0; i<num_ranges; ++i)
207254721Semaste        {
208254721Semaste            const Range &range = m_ranges.GetEntryRef(i);
209254721Semaste            s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
210254721Semaste        }
211254721Semaste    }
212254721Semaste}
213254721Semaste
214254721Semastebool
215254721SemasteBlock::Contains (addr_t range_offset) const
216254721Semaste{
217254721Semaste    return m_ranges.FindEntryThatContains(range_offset) != NULL;
218254721Semaste}
219254721Semaste
220254721Semastebool
221254721SemasteBlock::Contains (const Block *block) const
222254721Semaste{
223254721Semaste    if (this == block)
224254721Semaste        return false; // This block doesn't contain itself...
225254721Semaste
226254721Semaste    // Walk the parent chain for "block" and see if any if them match this block
227254721Semaste    const Block *block_parent;
228254721Semaste    for (block_parent = block->GetParent();
229254721Semaste         block_parent != NULL;
230254721Semaste         block_parent = block_parent->GetParent())
231254721Semaste    {
232254721Semaste        if (this == block_parent)
233254721Semaste            return true; // One of the parents of "block" is this object!
234254721Semaste    }
235254721Semaste    return false;
236254721Semaste}
237254721Semaste
238254721Semastebool
239254721SemasteBlock::Contains (const Range& range) const
240254721Semaste{
241254721Semaste    return m_ranges.FindEntryThatContains (range) != NULL;
242254721Semaste}
243254721Semaste
244254721SemasteBlock *
245254721SemasteBlock::GetParent () const
246254721Semaste{
247254721Semaste    if (m_parent_scope)
248254721Semaste        return m_parent_scope->CalculateSymbolContextBlock();
249254721Semaste    return NULL;
250254721Semaste}
251254721Semaste
252254721SemasteBlock *
253254721SemasteBlock::GetContainingInlinedBlock ()
254254721Semaste{
255254721Semaste    if (GetInlinedFunctionInfo())
256254721Semaste        return this;
257254721Semaste    return GetInlinedParent ();
258254721Semaste}
259254721Semaste
260254721SemasteBlock *
261254721SemasteBlock::GetInlinedParent ()
262254721Semaste{
263254721Semaste    Block *parent_block = GetParent ();
264254721Semaste    if (parent_block)
265254721Semaste    {
266254721Semaste        if (parent_block->GetInlinedFunctionInfo())
267254721Semaste            return parent_block;
268254721Semaste        else
269254721Semaste            return parent_block->GetInlinedParent();
270254721Semaste    }
271254721Semaste    return NULL;
272254721Semaste}
273254721Semaste
274254721Semaste
275254721Semastebool
276254721SemasteBlock::GetRangeContainingOffset (const addr_t offset, Range &range)
277254721Semaste{
278254721Semaste    const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
279254721Semaste    if (range_ptr)
280254721Semaste    {
281254721Semaste        range = *range_ptr;
282254721Semaste        return true;
283254721Semaste    }
284254721Semaste    range.Clear();
285254721Semaste    return false;
286254721Semaste}
287254721Semaste
288254721Semaste
289254721Semastebool
290254721SemasteBlock::GetRangeContainingAddress (const Address& addr, AddressRange &range)
291254721Semaste{
292254721Semaste    Function *function = CalculateSymbolContextFunction();
293254721Semaste    if (function)
294254721Semaste    {
295254721Semaste        const AddressRange &func_range = function->GetAddressRange();
296254721Semaste        if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
297254721Semaste        {
298254721Semaste            const addr_t addr_offset = addr.GetOffset();
299254721Semaste            const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
300254721Semaste            if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
301254721Semaste            {
302254721Semaste                addr_t offset = addr_offset - func_offset;
303254721Semaste
304254721Semaste                const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
305254721Semaste
306254721Semaste                if (range_ptr)
307254721Semaste                {
308254721Semaste                    range.GetBaseAddress() = func_range.GetBaseAddress();
309254721Semaste                    range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
310254721Semaste                    range.SetByteSize(range_ptr->GetByteSize());
311254721Semaste                    return true;
312254721Semaste                }
313254721Semaste            }
314254721Semaste        }
315254721Semaste    }
316254721Semaste    range.Clear();
317254721Semaste    return false;
318254721Semaste}
319254721Semaste
320254721Semastebool
321254721SemasteBlock::GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range)
322254721Semaste{
323254721Semaste    Address load_address;
324254721Semaste    load_address.SetLoadAddress(load_addr, &target);
325254721Semaste    AddressRange containing_range;
326254721Semaste    return GetRangeContainingAddress(load_address, containing_range);
327254721Semaste}
328254721Semaste
329254721Semaste
330254721Semasteuint32_t
331254721SemasteBlock::GetRangeIndexContainingAddress (const Address& addr)
332254721Semaste{
333254721Semaste    Function *function = CalculateSymbolContextFunction();
334254721Semaste    if (function)
335254721Semaste    {
336254721Semaste        const AddressRange &func_range = function->GetAddressRange();
337254721Semaste        if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
338254721Semaste        {
339254721Semaste            const addr_t addr_offset = addr.GetOffset();
340254721Semaste            const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
341254721Semaste            if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
342254721Semaste            {
343254721Semaste                addr_t offset = addr_offset - func_offset;
344254721Semaste                return m_ranges.FindEntryIndexThatContains (offset);
345254721Semaste            }
346254721Semaste        }
347254721Semaste    }
348254721Semaste    return UINT32_MAX;
349254721Semaste}
350254721Semaste
351254721Semastebool
352254721SemasteBlock::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
353254721Semaste{
354254721Semaste    if (range_idx < m_ranges.GetSize())
355254721Semaste    {
356254721Semaste        Function *function = CalculateSymbolContextFunction();
357254721Semaste        if (function)
358254721Semaste        {
359254721Semaste            const Range &vm_range = m_ranges.GetEntryRef(range_idx);
360254721Semaste            range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
361254721Semaste            range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
362254721Semaste            range.SetByteSize (vm_range.GetByteSize());
363254721Semaste            return true;
364254721Semaste        }
365254721Semaste    }
366254721Semaste    return false;
367254721Semaste}
368254721Semaste
369254721Semastebool
370254721SemasteBlock::GetStartAddress (Address &addr)
371254721Semaste{
372254721Semaste    if (m_ranges.IsEmpty())
373254721Semaste        return false;
374254721Semaste
375254721Semaste    Function *function = CalculateSymbolContextFunction();
376254721Semaste    if (function)
377254721Semaste    {
378254721Semaste        addr = function->GetAddressRange().GetBaseAddress();
379254721Semaste        addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ());
380254721Semaste        return true;
381254721Semaste    }
382254721Semaste    return false;
383254721Semaste}
384254721Semaste
385254721Semastevoid
386254721SemasteBlock::FinalizeRanges ()
387254721Semaste{
388254721Semaste    m_ranges.Sort();
389254721Semaste    m_ranges.CombineConsecutiveRanges ();
390254721Semaste}
391254721Semaste
392254721Semastevoid
393254721SemasteBlock::AddRange (const Range& range)
394254721Semaste{
395254721Semaste    Block *parent_block = GetParent ();
396254721Semaste    if (parent_block && !parent_block->Contains(range))
397254721Semaste    {
398254721Semaste        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
399254721Semaste        if (log)
400254721Semaste        {
401254721Semaste            ModuleSP module_sp (m_parent_scope->CalculateSymbolContextModule());
402254721Semaste            Function *function = m_parent_scope->CalculateSymbolContextFunction();
403254721Semaste            const addr_t function_file_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
404254721Semaste            const addr_t block_start_addr = function_file_addr + range.GetRangeBase ();
405254721Semaste            const addr_t block_end_addr = function_file_addr + range.GetRangeEnd ();
406254721Semaste            Type *func_type = function->GetType();
407254721Semaste
408254721Semaste            const Declaration &func_decl = func_type->GetDeclaration();
409254721Semaste            if (func_decl.GetLine())
410254721Semaste            {
411254721Semaste                log->Printf ("warning: %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",
412254721Semaste                             func_decl.GetFile().GetPath().c_str(),
413254721Semaste                             func_decl.GetLine(),
414254721Semaste                             GetID(),
415254721Semaste                             (uint32_t)m_ranges.GetSize(),
416254721Semaste                             block_start_addr,
417254721Semaste                             block_end_addr,
418254721Semaste                             parent_block->GetID(),
419254721Semaste                             function->GetID(),
420254721Semaste                             module_sp->GetFileSpec().GetPath().c_str());
421254721Semaste            }
422254721Semaste            else
423254721Semaste            {
424254721Semaste                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",
425254721Semaste                             GetID(),
426254721Semaste                             (uint32_t)m_ranges.GetSize(),
427254721Semaste                             block_start_addr,
428254721Semaste                             block_end_addr,
429254721Semaste                             parent_block->GetID(),
430254721Semaste                             function->GetID(),
431254721Semaste                             module_sp->GetFileSpec().GetPath().c_str());
432254721Semaste            }
433254721Semaste        }
434254721Semaste        parent_block->AddRange (range);
435254721Semaste    }
436254721Semaste    m_ranges.Append(range);
437254721Semaste}
438254721Semaste
439254721Semaste// Return the current number of bytes that this object occupies in memory
440254721Semastesize_t
441254721SemasteBlock::MemorySize() const
442254721Semaste{
443254721Semaste    size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
444254721Semaste    if (m_inlineInfoSP.get())
445254721Semaste        mem_size += m_inlineInfoSP->MemorySize();
446254721Semaste    if (m_variable_list_sp.get())
447254721Semaste        mem_size += m_variable_list_sp->MemorySize();
448254721Semaste    return mem_size;
449254721Semaste
450254721Semaste}
451254721Semaste
452254721Semastevoid
453254721SemasteBlock::AddChild(const BlockSP &child_block_sp)
454254721Semaste{
455254721Semaste    if (child_block_sp)
456254721Semaste    {
457254721Semaste        child_block_sp->SetParentScope (this);
458254721Semaste        m_children.push_back (child_block_sp);
459254721Semaste    }
460254721Semaste}
461254721Semaste
462254721Semastevoid
463254721SemasteBlock::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
464254721Semaste{
465254721Semaste    m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
466254721Semaste}
467254721Semaste
468254721Semaste
469254721Semaste
470254721SemasteVariableListSP
471254721SemasteBlock::GetBlockVariableList (bool can_create)
472254721Semaste{
473254721Semaste    if (m_parsed_block_variables == false)
474254721Semaste    {
475254721Semaste        if (m_variable_list_sp.get() == NULL && can_create)
476254721Semaste        {
477254721Semaste            m_parsed_block_variables = true;
478254721Semaste            SymbolContext sc;
479254721Semaste            CalculateSymbolContext(&sc);
480254721Semaste            assert(sc.module_sp);
481254721Semaste            sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
482254721Semaste        }
483254721Semaste    }
484254721Semaste    return m_variable_list_sp;
485254721Semaste}
486254721Semaste
487254721Semasteuint32_t
488254721SemasteBlock::AppendBlockVariables (bool can_create,
489254721Semaste                             bool get_child_block_variables,
490254721Semaste                             bool stop_if_child_block_is_inlined_function,
491254721Semaste                             VariableList *variable_list)
492254721Semaste{
493254721Semaste    uint32_t num_variables_added = 0;
494254721Semaste    VariableList *block_var_list = GetBlockVariableList (can_create).get();
495254721Semaste    if (block_var_list)
496254721Semaste    {
497254721Semaste        num_variables_added += block_var_list->GetSize();
498254721Semaste        variable_list->AddVariables (block_var_list);
499254721Semaste    }
500254721Semaste
501254721Semaste    if (get_child_block_variables)
502254721Semaste    {
503254721Semaste        collection::const_iterator pos, end = m_children.end();
504254721Semaste        for (pos = m_children.begin(); pos != end; ++pos)
505254721Semaste        {
506254721Semaste            Block *child_block = pos->get();
507254721Semaste            if (stop_if_child_block_is_inlined_function == false ||
508254721Semaste                child_block->GetInlinedFunctionInfo() == NULL)
509254721Semaste            {
510254721Semaste                num_variables_added += child_block->AppendBlockVariables (can_create,
511254721Semaste                                                                          get_child_block_variables,
512254721Semaste                                                                          stop_if_child_block_is_inlined_function,
513254721Semaste                                                                          variable_list);
514254721Semaste            }
515254721Semaste        }
516254721Semaste    }
517254721Semaste    return num_variables_added;
518254721Semaste}
519254721Semaste
520254721Semasteuint32_t
521254721SemasteBlock::AppendVariables
522254721Semaste(
523254721Semaste    bool can_create,
524254721Semaste    bool get_parent_variables,
525254721Semaste    bool stop_if_block_is_inlined_function,
526254721Semaste    VariableList *variable_list
527254721Semaste)
528254721Semaste{
529254721Semaste    uint32_t num_variables_added = 0;
530254721Semaste    VariableListSP variable_list_sp(GetBlockVariableList(can_create));
531254721Semaste
532254721Semaste    bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
533254721Semaste    if (variable_list_sp.get())
534254721Semaste    {
535254721Semaste        num_variables_added = variable_list_sp->GetSize();
536254721Semaste        variable_list->AddVariables(variable_list_sp.get());
537254721Semaste    }
538254721Semaste
539254721Semaste    if (get_parent_variables)
540254721Semaste    {
541254721Semaste        if (stop_if_block_is_inlined_function && is_inlined_function)
542254721Semaste            return num_variables_added;
543254721Semaste
544254721Semaste        Block* parent_block = GetParent();
545254721Semaste        if (parent_block)
546254721Semaste            num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list);
547254721Semaste    }
548254721Semaste    return num_variables_added;
549254721Semaste}
550254721Semaste
551254721Semasteclang::DeclContext *
552254721SemasteBlock::GetClangDeclContext()
553254721Semaste{
554254721Semaste    SymbolContext sc;
555254721Semaste
556254721Semaste    CalculateSymbolContext (&sc);
557254721Semaste
558254721Semaste    if (!sc.module_sp)
559254721Semaste        return NULL;
560254721Semaste
561254721Semaste    SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
562254721Semaste
563254721Semaste    if (!sym_vendor)
564254721Semaste        return NULL;
565254721Semaste
566254721Semaste    SymbolFile *sym_file = sym_vendor->GetSymbolFile();
567254721Semaste
568254721Semaste    if (!sym_file)
569254721Semaste        return NULL;
570254721Semaste
571254721Semaste    return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
572254721Semaste}
573254721Semaste
574254721Semastevoid
575254721SemasteBlock::SetBlockInfoHasBeenParsed (bool b, bool set_children)
576254721Semaste{
577254721Semaste    m_parsed_block_info = b;
578254721Semaste    if (set_children)
579254721Semaste    {
580254721Semaste        m_parsed_child_blocks = true;
581254721Semaste        collection::const_iterator pos, end = m_children.end();
582254721Semaste        for (pos = m_children.begin(); pos != end; ++pos)
583254721Semaste            (*pos)->SetBlockInfoHasBeenParsed (b, true);
584254721Semaste    }
585254721Semaste}
586254721Semaste
587254721Semastevoid
588254721SemasteBlock::SetDidParseVariables (bool b, bool set_children)
589254721Semaste{
590254721Semaste    m_parsed_block_variables = b;
591254721Semaste    if (set_children)
592254721Semaste    {
593254721Semaste        collection::const_iterator pos, end = m_children.end();
594254721Semaste        for (pos = m_children.begin(); pos != end; ++pos)
595254721Semaste            (*pos)->SetDidParseVariables (b, true);
596254721Semaste    }
597254721Semaste}
598254721Semaste
599254721Semaste
600254721SemasteBlock *
601254721SemasteBlock::GetSibling() const
602254721Semaste{
603254721Semaste    if (m_parent_scope)
604254721Semaste    {
605254721Semaste        Block *parent_block = GetParent();
606254721Semaste        if (parent_block)
607254721Semaste            return parent_block->GetSiblingForChild (this);
608254721Semaste    }
609254721Semaste    return NULL;
610254721Semaste}
611254721Semaste// A parent of child blocks can be asked to find a sibling block given
612254721Semaste// one of its child blocks
613254721SemasteBlock *
614254721SemasteBlock::GetSiblingForChild (const Block *child_block) const
615254721Semaste{
616254721Semaste    if (!m_children.empty())
617254721Semaste    {
618254721Semaste        collection::const_iterator pos, end = m_children.end();
619254721Semaste        for (pos = m_children.begin(); pos != end; ++pos)
620254721Semaste        {
621254721Semaste            if (pos->get() == child_block)
622254721Semaste            {
623254721Semaste                if (++pos != end)
624254721Semaste                    return pos->get();
625254721Semaste                break;
626254721Semaste            }
627254721Semaste        }
628254721Semaste    }
629254721Semaste    return NULL;
630254721Semaste}
631254721Semaste
632