180814287SRaphael Isemann //===-- Block.cpp ---------------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Symbol/Block.h"
106c7f5619SGreg Clayton
1130fdc8d8SChris Lattner #include "lldb/Core/Module.h"
1230fdc8d8SChris Lattner #include "lldb/Core/Section.h"
136c7f5619SGreg Clayton #include "lldb/Symbol/Function.h"
1472e4940bSSean Callanan #include "lldb/Symbol/SymbolFile.h"
1530fdc8d8SChris Lattner #include "lldb/Symbol/VariableList.h"
16*c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
176f9e6901SZachary Turner #include "lldb/Utility/Log.h"
1830fdc8d8SChris Lattner
19796ac80bSJonas Devlieghere #include <memory>
20796ac80bSJonas Devlieghere
2130fdc8d8SChris Lattner using namespace lldb;
2230fdc8d8SChris Lattner using namespace lldb_private;
2330fdc8d8SChris Lattner
Block(lldb::user_id_t uid)24b9c1b51eSKate Stone Block::Block(lldb::user_id_t uid)
25b9c1b51eSKate Stone : UserID(uid), m_parent_scope(nullptr), m_children(), m_ranges(),
26b9c1b51eSKate Stone m_inlineInfoSP(), m_variable_list_sp(), m_parsed_block_info(false),
27b9c1b51eSKate Stone m_parsed_block_variables(false), m_parsed_child_blocks(false) {}
2830fdc8d8SChris Lattner
29fd2433e1SJonas Devlieghere Block::~Block() = default;
3030fdc8d8SChris Lattner
GetDescription(Stream * s,Function * function,lldb::DescriptionLevel level,Target * target) const31b9c1b51eSKate Stone void Block::GetDescription(Stream *s, Function *function,
32b9c1b51eSKate Stone lldb::DescriptionLevel level, Target *target) const {
33c9800667SGreg Clayton *s << "id = " << ((const UserID &)*this);
34c9800667SGreg Clayton
35ea3e7d5cSGreg Clayton size_t num_ranges = m_ranges.GetSize();
36b9c1b51eSKate Stone if (num_ranges > 0) {
370c5cd90dSGreg Clayton
380c5cd90dSGreg Clayton addr_t base_addr = LLDB_INVALID_ADDRESS;
39f5e56de0SGreg Clayton if (target)
40b9c1b51eSKate Stone base_addr =
41b9c1b51eSKate Stone function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
420c5cd90dSGreg Clayton if (base_addr == LLDB_INVALID_ADDRESS)
430b76a2c2SGreg Clayton base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
440c5cd90dSGreg Clayton
45c9800667SGreg Clayton s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
46b9c1b51eSKate Stone for (size_t i = 0; i < num_ranges; ++i) {
47ea3e7d5cSGreg Clayton const Range &range = m_ranges.GetEntryRef(i);
481462f5a4SRaphael Isemann DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
49b9c1b51eSKate Stone base_addr + range.GetRangeEnd(), 4);
50ea3e7d5cSGreg Clayton }
510c5cd90dSGreg Clayton }
520c5cd90dSGreg Clayton
53b9c1b51eSKate Stone if (m_inlineInfoSP.get() != nullptr) {
546dbd3983SGreg Clayton bool show_fullpaths = (level == eDescriptionLevelVerbose);
556dbd3983SGreg Clayton m_inlineInfoSP->Dump(s, show_fullpaths);
566dbd3983SGreg Clayton }
570c5cd90dSGreg Clayton }
580c5cd90dSGreg Clayton
Dump(Stream * s,addr_t base_addr,int32_t depth,bool show_context) const59b9c1b51eSKate Stone void Block::Dump(Stream *s, addr_t base_addr, int32_t depth,
60b9c1b51eSKate Stone bool show_context) const {
61b9c1b51eSKate Stone if (depth < 0) {
620b76a2c2SGreg Clayton Block *parent = GetParent();
63b9c1b51eSKate Stone if (parent) {
6405097246SAdrian Prantl // We have a depth that is less than zero, print our parent blocks first
650b76a2c2SGreg Clayton parent->Dump(s, base_addr, depth + 1, show_context);
660b76a2c2SGreg Clayton }
6730fdc8d8SChris Lattner }
6830fdc8d8SChris Lattner
69324a1036SSaleem Abdulrasool s->Printf("%p: ", static_cast<const void *>(this));
7030fdc8d8SChris Lattner s->Indent();
71324a1036SSaleem Abdulrasool *s << "Block" << static_cast<const UserID &>(*this);
720c5cd90dSGreg Clayton const Block *parent_block = GetParent();
73b9c1b51eSKate Stone if (parent_block) {
74d01b2953SDaniel Malea s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
7530fdc8d8SChris Lattner }
76b9c1b51eSKate Stone if (m_inlineInfoSP.get() != nullptr) {
776dbd3983SGreg Clayton bool show_fullpaths = false;
786dbd3983SGreg Clayton m_inlineInfoSP->Dump(s, show_fullpaths);
796dbd3983SGreg Clayton }
8030fdc8d8SChris Lattner
81b9c1b51eSKate Stone if (!m_ranges.IsEmpty()) {
8230fdc8d8SChris Lattner *s << ", ranges =";
83ea3e7d5cSGreg Clayton
84ea3e7d5cSGreg Clayton size_t num_ranges = m_ranges.GetSize();
85b9c1b51eSKate Stone for (size_t i = 0; i < num_ranges; ++i) {
86ea3e7d5cSGreg Clayton const Range &range = m_ranges.GetEntryRef(i);
87a6682a41SJonas Devlieghere if (parent_block != nullptr && !parent_block->Contains(range))
8830fdc8d8SChris Lattner *s << '!';
8930fdc8d8SChris Lattner else
9030fdc8d8SChris Lattner *s << ' ';
911462f5a4SRaphael Isemann DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
92b9c1b51eSKate Stone base_addr + range.GetRangeEnd(), 4);
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner }
9530fdc8d8SChris Lattner s->EOL();
9630fdc8d8SChris Lattner
97b9c1b51eSKate Stone if (depth > 0) {
9830fdc8d8SChris Lattner s->IndentMore();
9930fdc8d8SChris Lattner
100b9c1b51eSKate Stone if (m_variable_list_sp.get()) {
1019da7bd07SGreg Clayton m_variable_list_sp->Dump(s, show_context);
10230fdc8d8SChris Lattner }
10330fdc8d8SChris Lattner
104624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
105624784a9SGreg Clayton for (pos = m_children.begin(); pos != end; ++pos)
106624784a9SGreg Clayton (*pos)->Dump(s, base_addr, depth - 1, show_context);
10730fdc8d8SChris Lattner
10830fdc8d8SChris Lattner s->IndentLess();
10930fdc8d8SChris Lattner }
11030fdc8d8SChris Lattner }
11130fdc8d8SChris Lattner
FindBlockByID(user_id_t block_id)112b9c1b51eSKate Stone Block *Block::FindBlockByID(user_id_t block_id) {
1130b76a2c2SGreg Clayton if (block_id == GetID())
1140b76a2c2SGreg Clayton return this;
1150b76a2c2SGreg Clayton
116d4612ad0SEd Maste Block *matching_block = nullptr;
117624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
118b9c1b51eSKate Stone for (pos = m_children.begin(); pos != end; ++pos) {
119624784a9SGreg Clayton matching_block = (*pos)->FindBlockByID(block_id);
1200b76a2c2SGreg Clayton if (matching_block)
1210b76a2c2SGreg Clayton break;
1220b76a2c2SGreg Clayton }
1230b76a2c2SGreg Clayton return matching_block;
1240b76a2c2SGreg Clayton }
1250b76a2c2SGreg Clayton
FindInnermostBlockByOffset(const lldb::addr_t offset)126cc9ced0eSZequan Wu Block *Block::FindInnermostBlockByOffset(const lldb::addr_t offset) {
127cc9ced0eSZequan Wu if (!Contains(offset))
128cc9ced0eSZequan Wu return nullptr;
129cc9ced0eSZequan Wu for (const BlockSP &block_sp : m_children) {
130cc9ced0eSZequan Wu if (Block *block = block_sp->FindInnermostBlockByOffset(offset))
131cc9ced0eSZequan Wu return block;
132cc9ced0eSZequan Wu }
133cc9ced0eSZequan Wu return this;
134cc9ced0eSZequan Wu }
135cc9ced0eSZequan Wu
CalculateSymbolContext(SymbolContext * sc)136b9c1b51eSKate Stone void Block::CalculateSymbolContext(SymbolContext *sc) {
1370b76a2c2SGreg Clayton if (m_parent_scope)
1380b76a2c2SGreg Clayton m_parent_scope->CalculateSymbolContext(sc);
13930fdc8d8SChris Lattner sc->block = this;
14030fdc8d8SChris Lattner }
14130fdc8d8SChris Lattner
CalculateSymbolContextModule()142b9c1b51eSKate Stone lldb::ModuleSP Block::CalculateSymbolContextModule() {
1437e9b1fd0SGreg Clayton if (m_parent_scope)
1447e9b1fd0SGreg Clayton return m_parent_scope->CalculateSymbolContextModule();
145e72dfb32SGreg Clayton return lldb::ModuleSP();
1467e9b1fd0SGreg Clayton }
1477e9b1fd0SGreg Clayton
CalculateSymbolContextCompileUnit()148b9c1b51eSKate Stone CompileUnit *Block::CalculateSymbolContextCompileUnit() {
1497e9b1fd0SGreg Clayton if (m_parent_scope)
1507e9b1fd0SGreg Clayton return m_parent_scope->CalculateSymbolContextCompileUnit();
151d4612ad0SEd Maste return nullptr;
1527e9b1fd0SGreg Clayton }
1537e9b1fd0SGreg Clayton
CalculateSymbolContextFunction()154b9c1b51eSKate Stone Function *Block::CalculateSymbolContextFunction() {
1557e9b1fd0SGreg Clayton if (m_parent_scope)
1567e9b1fd0SGreg Clayton return m_parent_scope->CalculateSymbolContextFunction();
157d4612ad0SEd Maste return nullptr;
1587e9b1fd0SGreg Clayton }
1597e9b1fd0SGreg Clayton
CalculateSymbolContextBlock()160b9c1b51eSKate Stone Block *Block::CalculateSymbolContextBlock() { return this; }
1617e9b1fd0SGreg Clayton
DumpSymbolContext(Stream * s)162b9c1b51eSKate Stone void Block::DumpSymbolContext(Stream *s) {
1637e9b1fd0SGreg Clayton Function *function = CalculateSymbolContextFunction();
1647e9b1fd0SGreg Clayton if (function)
1657e9b1fd0SGreg Clayton function->DumpSymbolContext(s);
166d01b2953SDaniel Malea s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
16730fdc8d8SChris Lattner }
16830fdc8d8SChris Lattner
DumpAddressRanges(Stream * s,lldb::addr_t base_addr)169b9c1b51eSKate Stone void Block::DumpAddressRanges(Stream *s, lldb::addr_t base_addr) {
170b9c1b51eSKate Stone if (!m_ranges.IsEmpty()) {
171ea3e7d5cSGreg Clayton size_t num_ranges = m_ranges.GetSize();
172b9c1b51eSKate Stone for (size_t i = 0; i < num_ranges; ++i) {
173ea3e7d5cSGreg Clayton const Range &range = m_ranges.GetEntryRef(i);
1741462f5a4SRaphael Isemann DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
175b9c1b51eSKate Stone base_addr + range.GetRangeEnd(), 4);
176ea3e7d5cSGreg Clayton }
177dde9cff3SCaroline Tice }
178dde9cff3SCaroline Tice }
179dde9cff3SCaroline Tice
Contains(addr_t range_offset) const180b9c1b51eSKate Stone bool Block::Contains(addr_t range_offset) const {
181d4612ad0SEd Maste return m_ranges.FindEntryThatContains(range_offset) != nullptr;
18230fdc8d8SChris Lattner }
18330fdc8d8SChris Lattner
Contains(const Block * block) const184b9c1b51eSKate Stone bool Block::Contains(const Block *block) const {
1856dadd508SGreg Clayton if (this == block)
1866f00abd5SGreg Clayton return false; // This block doesn't contain itself...
1876dadd508SGreg Clayton
1886f00abd5SGreg Clayton // Walk the parent chain for "block" and see if any if them match this block
1896dadd508SGreg Clayton const Block *block_parent;
190b9c1b51eSKate Stone for (block_parent = block->GetParent(); block_parent != nullptr;
191b9c1b51eSKate Stone block_parent = block_parent->GetParent()) {
1926f00abd5SGreg Clayton if (this == block_parent)
1936f00abd5SGreg Clayton return true; // One of the parents of "block" is this object!
1946dadd508SGreg Clayton }
1956dadd508SGreg Clayton return false;
1966dadd508SGreg Clayton }
1976dadd508SGreg Clayton
Contains(const Range & range) const198b9c1b51eSKate Stone bool Block::Contains(const Range &range) const {
199d4612ad0SEd Maste return m_ranges.FindEntryThatContains(range) != nullptr;
20030fdc8d8SChris Lattner }
20130fdc8d8SChris Lattner
GetParent() const202b9c1b51eSKate Stone Block *Block::GetParent() const {
2030b76a2c2SGreg Clayton if (m_parent_scope)
2047e9b1fd0SGreg Clayton return m_parent_scope->CalculateSymbolContextBlock();
205d4612ad0SEd Maste return nullptr;
20630fdc8d8SChris Lattner }
20730fdc8d8SChris Lattner
GetContainingInlinedBlock()208b9c1b51eSKate Stone Block *Block::GetContainingInlinedBlock() {
20995897c6aSGreg Clayton if (GetInlinedFunctionInfo())
2109da7bd07SGreg Clayton return this;
2119da7bd07SGreg Clayton return GetInlinedParent();
2129da7bd07SGreg Clayton }
2139da7bd07SGreg Clayton
GetInlinedParent()214b9c1b51eSKate Stone Block *Block::GetInlinedParent() {
2151b72fcb7SGreg Clayton Block *parent_block = GetParent();
216b9c1b51eSKate Stone if (parent_block) {
21795897c6aSGreg Clayton if (parent_block->GetInlinedFunctionInfo())
2181b72fcb7SGreg Clayton return parent_block;
2191b72fcb7SGreg Clayton else
2201b72fcb7SGreg Clayton return parent_block->GetInlinedParent();
2211b72fcb7SGreg Clayton }
222d4612ad0SEd Maste return nullptr;
2231b72fcb7SGreg Clayton }
2241b72fcb7SGreg Clayton
GetContainingInlinedBlockWithCallSite(const Declaration & find_call_site)2258a777920SGreg Clayton Block *Block::GetContainingInlinedBlockWithCallSite(
2268a777920SGreg Clayton const Declaration &find_call_site) {
227a83e94ebSFangrui Song Block *inlined_block = GetContainingInlinedBlock();
2288a777920SGreg Clayton
2298a777920SGreg Clayton while (inlined_block) {
230a83e94ebSFangrui Song const auto *function_info = inlined_block->GetInlinedFunctionInfo();
2318a777920SGreg Clayton
2328a777920SGreg Clayton if (function_info &&
2338a777920SGreg Clayton function_info->GetCallSite().FileAndLineEqual(find_call_site))
2348a777920SGreg Clayton return inlined_block;
2358a777920SGreg Clayton inlined_block = inlined_block->GetInlinedParent();
2368a777920SGreg Clayton }
2378a777920SGreg Clayton return nullptr;
2388a777920SGreg Clayton }
2398a777920SGreg Clayton
GetRangeContainingOffset(const addr_t offset,Range & range)240b9c1b51eSKate Stone bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
241ea3e7d5cSGreg Clayton const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
242b9c1b51eSKate Stone if (range_ptr) {
243ea3e7d5cSGreg Clayton range = *range_ptr;
2449da7bd07SGreg Clayton return true;
2459da7bd07SGreg Clayton }
2469da7bd07SGreg Clayton range.Clear();
2479da7bd07SGreg Clayton return false;
2489da7bd07SGreg Clayton }
2499da7bd07SGreg Clayton
GetRangeContainingAddress(const Address & addr,AddressRange & range)250b9c1b51eSKate Stone bool Block::GetRangeContainingAddress(const Address &addr,
251b9c1b51eSKate Stone AddressRange &range) {
2527e9b1fd0SGreg Clayton Function *function = CalculateSymbolContextFunction();
253b9c1b51eSKate Stone if (function) {
2547e9b1fd0SGreg Clayton const AddressRange &func_range = function->GetAddressRange();
255b9c1b51eSKate Stone if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
2561b72fcb7SGreg Clayton const addr_t addr_offset = addr.GetOffset();
2571b72fcb7SGreg Clayton const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
258b9c1b51eSKate Stone if (addr_offset >= func_offset &&
259b9c1b51eSKate Stone addr_offset < func_offset + func_range.GetByteSize()) {
2601b72fcb7SGreg Clayton addr_t offset = addr_offset - func_offset;
2611b72fcb7SGreg Clayton
262ea3e7d5cSGreg Clayton const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
263ea3e7d5cSGreg Clayton
264b9c1b51eSKate Stone if (range_ptr) {
2651b72fcb7SGreg Clayton range.GetBaseAddress() = func_range.GetBaseAddress();
266b9c1b51eSKate Stone range.GetBaseAddress().SetOffset(func_offset +
267b9c1b51eSKate Stone range_ptr->GetRangeBase());
268ea3e7d5cSGreg Clayton range.SetByteSize(range_ptr->GetByteSize());
2691b72fcb7SGreg Clayton return true;
2701b72fcb7SGreg Clayton }
2711b72fcb7SGreg Clayton }
2721b72fcb7SGreg Clayton }
2731b72fcb7SGreg Clayton }
2741b72fcb7SGreg Clayton range.Clear();
2751b72fcb7SGreg Clayton return false;
2761b72fcb7SGreg Clayton }
2771b72fcb7SGreg Clayton
GetRangeContainingLoadAddress(lldb::addr_t load_addr,Target & target,AddressRange & range)278b9c1b51eSKate Stone bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
279b9c1b51eSKate Stone Target &target, AddressRange &range) {
280fcb59bcfSJim Ingham Address load_address;
281fcb59bcfSJim Ingham load_address.SetLoadAddress(load_addr, &target);
282fcb59bcfSJim Ingham AddressRange containing_range;
283fcb59bcfSJim Ingham return GetRangeContainingAddress(load_address, containing_range);
284fcb59bcfSJim Ingham }
285fcb59bcfSJim Ingham
GetRangeIndexContainingAddress(const Address & addr)286b9c1b51eSKate Stone uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
287ea3e7d5cSGreg Clayton Function *function = CalculateSymbolContextFunction();
288b9c1b51eSKate Stone if (function) {
289ea3e7d5cSGreg Clayton const AddressRange &func_range = function->GetAddressRange();
290b9c1b51eSKate Stone if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
291ea3e7d5cSGreg Clayton const addr_t addr_offset = addr.GetOffset();
292ea3e7d5cSGreg Clayton const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
293b9c1b51eSKate Stone if (addr_offset >= func_offset &&
294b9c1b51eSKate Stone addr_offset < func_offset + func_range.GetByteSize()) {
295ea3e7d5cSGreg Clayton addr_t offset = addr_offset - func_offset;
296ea3e7d5cSGreg Clayton return m_ranges.FindEntryIndexThatContains(offset);
297ea3e7d5cSGreg Clayton }
298ea3e7d5cSGreg Clayton }
299ea3e7d5cSGreg Clayton }
300ea3e7d5cSGreg Clayton return UINT32_MAX;
301ea3e7d5cSGreg Clayton }
302ea3e7d5cSGreg Clayton
GetRangeAtIndex(uint32_t range_idx,AddressRange & range)303b9c1b51eSKate Stone bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
304b9c1b51eSKate Stone if (range_idx < m_ranges.GetSize()) {
3057e9b1fd0SGreg Clayton Function *function = CalculateSymbolContextFunction();
306b9c1b51eSKate Stone if (function) {
307ea3e7d5cSGreg Clayton const Range &vm_range = m_ranges.GetEntryRef(range_idx);
3087e9b1fd0SGreg Clayton range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
309ea3e7d5cSGreg Clayton range.GetBaseAddress().Slide(vm_range.GetRangeBase());
310ea3e7d5cSGreg Clayton range.SetByteSize(vm_range.GetByteSize());
3117e14f91dSGreg Clayton return true;
3127e14f91dSGreg Clayton }
3137e14f91dSGreg Clayton }
3147e14f91dSGreg Clayton return false;
3157e14f91dSGreg Clayton }
316d7e05469SGreg Clayton
GetStartAddress(Address & addr)317b9c1b51eSKate Stone bool Block::GetStartAddress(Address &addr) {
318ea3e7d5cSGreg Clayton if (m_ranges.IsEmpty())
319d7e05469SGreg Clayton return false;
320d7e05469SGreg Clayton
3217e9b1fd0SGreg Clayton Function *function = CalculateSymbolContextFunction();
322b9c1b51eSKate Stone if (function) {
3237e9b1fd0SGreg Clayton addr = function->GetAddressRange().GetBaseAddress();
324ea3e7d5cSGreg Clayton addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
325d7e05469SGreg Clayton return true;
326d7e05469SGreg Clayton }
327d7e05469SGreg Clayton return false;
328d7e05469SGreg Clayton }
329d7e05469SGreg Clayton
FinalizeRanges()330b9c1b51eSKate Stone void Block::FinalizeRanges() {
331ea3e7d5cSGreg Clayton m_ranges.Sort();
332ea3e7d5cSGreg Clayton m_ranges.CombineConsecutiveRanges();
333ea3e7d5cSGreg Clayton }
334ea3e7d5cSGreg Clayton
AddRange(const Range & range)335b9c1b51eSKate Stone void Block::AddRange(const Range &range) {
3366c7f5619SGreg Clayton Block *parent_block = GetParent();
337b9c1b51eSKate Stone if (parent_block && !parent_block->Contains(range)) {
338a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Symbols);
339b9c1b51eSKate Stone if (log) {
340e72dfb32SGreg Clayton ModuleSP module_sp(m_parent_scope->CalculateSymbolContextModule());
3416c7f5619SGreg Clayton Function *function = m_parent_scope->CalculateSymbolContextFunction();
342b9c1b51eSKate Stone const addr_t function_file_addr =
343b9c1b51eSKate Stone function->GetAddressRange().GetBaseAddress().GetFileAddress();
344ea3e7d5cSGreg Clayton const addr_t block_start_addr = function_file_addr + range.GetRangeBase();
345ea3e7d5cSGreg Clayton const addr_t block_end_addr = function_file_addr + range.GetRangeEnd();
3466c7f5619SGreg Clayton Type *func_type = function->GetType();
3476c7f5619SGreg Clayton
3486c7f5619SGreg Clayton const Declaration &func_decl = func_type->GetDeclaration();
349b9c1b51eSKate Stone if (func_decl.GetLine()) {
35063e5fb76SJonas Devlieghere LLDB_LOGF(log,
35163e5fb76SJonas Devlieghere "warning: %s:%u block {0x%8.8" PRIx64
352b9c1b51eSKate Stone "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
353b9c1b51eSKate Stone ") which is not contained in parent block {0x%8.8" PRIx64
354b9c1b51eSKate Stone "} in function {0x%8.8" PRIx64 "} from %s",
355b9c1b51eSKate Stone func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
356b9c1b51eSKate Stone GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
357b9c1b51eSKate Stone block_end_addr, parent_block->GetID(), function->GetID(),
358b5ad4ec7SGreg Clayton module_sp->GetFileSpec().GetPath().c_str());
359b9c1b51eSKate Stone } else {
36063e5fb76SJonas Devlieghere LLDB_LOGF(log,
36163e5fb76SJonas Devlieghere "warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64
36263e5fb76SJonas Devlieghere " - 0x%" PRIx64
363b9c1b51eSKate Stone ") which is not contained in parent block {0x%8.8" PRIx64
364b9c1b51eSKate Stone "} in function {0x%8.8" PRIx64 "} from %s",
365b9c1b51eSKate Stone GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
366b9c1b51eSKate Stone block_end_addr, parent_block->GetID(), function->GetID(),
367b5ad4ec7SGreg Clayton module_sp->GetFileSpec().GetPath().c_str());
3686c7f5619SGreg Clayton }
3696c7f5619SGreg Clayton }
370ea3e7d5cSGreg Clayton parent_block->AddRange(range);
3716c7f5619SGreg Clayton }
372ea3e7d5cSGreg Clayton m_ranges.Append(range);
37330fdc8d8SChris Lattner }
37430fdc8d8SChris Lattner
37530fdc8d8SChris Lattner // Return the current number of bytes that this object occupies in memory
MemorySize() const376b9c1b51eSKate Stone size_t Block::MemorySize() const {
377ea3e7d5cSGreg Clayton size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
37830fdc8d8SChris Lattner if (m_inlineInfoSP.get())
37930fdc8d8SChris Lattner mem_size += m_inlineInfoSP->MemorySize();
3809da7bd07SGreg Clayton if (m_variable_list_sp.get())
3819da7bd07SGreg Clayton mem_size += m_variable_list_sp->MemorySize();
38230fdc8d8SChris Lattner return mem_size;
38330fdc8d8SChris Lattner }
38430fdc8d8SChris Lattner
AddChild(const BlockSP & child_block_sp)385b9c1b51eSKate Stone void Block::AddChild(const BlockSP &child_block_sp) {
386b9c1b51eSKate Stone if (child_block_sp) {
3870b76a2c2SGreg Clayton child_block_sp->SetParentScope(this);
3880b76a2c2SGreg Clayton m_children.push_back(child_block_sp);
3890b76a2c2SGreg Clayton }
39030fdc8d8SChris Lattner }
39130fdc8d8SChris Lattner
SetInlinedFunctionInfo(const char * name,const char * mangled,const Declaration * decl_ptr,const Declaration * call_decl_ptr)392b9c1b51eSKate Stone void Block::SetInlinedFunctionInfo(const char *name, const char *mangled,
393b9c1b51eSKate Stone const Declaration *decl_ptr,
394b9c1b51eSKate Stone const Declaration *call_decl_ptr) {
395796ac80bSJonas Devlieghere m_inlineInfoSP = std::make_shared<InlineFunctionInfo>(name, mangled, decl_ptr,
396796ac80bSJonas Devlieghere call_decl_ptr);
39730fdc8d8SChris Lattner }
39830fdc8d8SChris Lattner
GetBlockVariableList(bool can_create)399b9c1b51eSKate Stone VariableListSP Block::GetBlockVariableList(bool can_create) {
400a6682a41SJonas Devlieghere if (!m_parsed_block_variables) {
401b9c1b51eSKate Stone if (m_variable_list_sp.get() == nullptr && can_create) {
4020b76a2c2SGreg Clayton m_parsed_block_variables = true;
403e1be14dfSJim Ingham SymbolContext sc;
404e1be14dfSJim Ingham CalculateSymbolContext(&sc);
405e1be14dfSJim Ingham assert(sc.module_sp);
406465eae36SPavel Labath sc.module_sp->GetSymbolFile()->ParseVariablesForContext(sc);
407e1be14dfSJim Ingham }
4080b76a2c2SGreg Clayton }
409c662ec8bSGreg Clayton return m_variable_list_sp;
410c662ec8bSGreg Clayton }
411e1be14dfSJim Ingham
412c662ec8bSGreg Clayton uint32_t
AppendBlockVariables(bool can_create,bool get_child_block_variables,bool stop_if_child_block_is_inlined_function,const std::function<bool (Variable *)> & filter,VariableList * variable_list)413b9c1b51eSKate Stone Block::AppendBlockVariables(bool can_create, bool get_child_block_variables,
414c662ec8bSGreg Clayton bool stop_if_child_block_is_inlined_function,
41572ac8a84STamas Berghammer const std::function<bool(Variable *)> &filter,
416b9c1b51eSKate Stone VariableList *variable_list) {
417c662ec8bSGreg Clayton uint32_t num_variables_added = 0;
418c662ec8bSGreg Clayton VariableList *block_var_list = GetBlockVariableList(can_create).get();
419b9c1b51eSKate Stone if (block_var_list) {
420d1782133SRaphael Isemann for (const VariableSP &var_sp : *block_var_list) {
421d1782133SRaphael Isemann if (filter(var_sp.get())) {
42272ac8a84STamas Berghammer num_variables_added++;
423d1782133SRaphael Isemann variable_list->AddVariable(var_sp);
42472ac8a84STamas Berghammer }
42572ac8a84STamas Berghammer }
426c662ec8bSGreg Clayton }
427e1be14dfSJim Ingham
428b9c1b51eSKate Stone if (get_child_block_variables) {
429624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
430b9c1b51eSKate Stone for (pos = m_children.begin(); pos != end; ++pos) {
431624784a9SGreg Clayton Block *child_block = pos->get();
432a6682a41SJonas Devlieghere if (!stop_if_child_block_is_inlined_function ||
433b9c1b51eSKate Stone child_block->GetInlinedFunctionInfo() == nullptr) {
434b9c1b51eSKate Stone num_variables_added += child_block->AppendBlockVariables(
435b9c1b51eSKate Stone can_create, get_child_block_variables,
436b9c1b51eSKate Stone stop_if_child_block_is_inlined_function, filter, variable_list);
437e1be14dfSJim Ingham }
438e1be14dfSJim Ingham }
439e1be14dfSJim Ingham }
440c662ec8bSGreg Clayton return num_variables_added;
441e1be14dfSJim Ingham }
442e1be14dfSJim Ingham
AppendVariables(bool can_create,bool get_parent_variables,bool stop_if_block_is_inlined_function,const std::function<bool (Variable *)> & filter,VariableList * variable_list)443b9c1b51eSKate Stone uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables,
4441b72fcb7SGreg Clayton bool stop_if_block_is_inlined_function,
44572ac8a84STamas Berghammer const std::function<bool(Variable *)> &filter,
446b9c1b51eSKate Stone VariableList *variable_list) {
447e1be14dfSJim Ingham uint32_t num_variables_added = 0;
448c662ec8bSGreg Clayton VariableListSP variable_list_sp(GetBlockVariableList(can_create));
449e1be14dfSJim Ingham
450d4612ad0SEd Maste bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
451b9c1b51eSKate Stone if (variable_list_sp) {
452b9c1b51eSKate Stone for (size_t i = 0; i < variable_list_sp->GetSize(); ++i) {
45372ac8a84STamas Berghammer VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
454b9c1b51eSKate Stone if (filter(variable.get())) {
45572ac8a84STamas Berghammer num_variables_added++;
45672ac8a84STamas Berghammer variable_list->AddVariable(variable);
45772ac8a84STamas Berghammer }
45872ac8a84STamas Berghammer }
459e1be14dfSJim Ingham }
460e1be14dfSJim Ingham
461b9c1b51eSKate Stone if (get_parent_variables) {
4621b72fcb7SGreg Clayton if (stop_if_block_is_inlined_function && is_inlined_function)
4631b72fcb7SGreg Clayton return num_variables_added;
4641b72fcb7SGreg Clayton
465e1be14dfSJim Ingham Block *parent_block = GetParent();
466e1be14dfSJim Ingham if (parent_block)
467b9c1b51eSKate Stone num_variables_added += parent_block->AppendVariables(
468b9c1b51eSKate Stone can_create, get_parent_variables, stop_if_block_is_inlined_function,
469b9c1b51eSKate Stone filter, variable_list);
470e1be14dfSJim Ingham }
471e1be14dfSJim Ingham return num_variables_added;
472e1be14dfSJim Ingham }
473e1be14dfSJim Ingham
GetSymbolFile()4744b36f791SVedant Kumar SymbolFile *Block::GetSymbolFile() {
4754b36f791SVedant Kumar if (ModuleSP module_sp = CalculateSymbolContextModule())
47623f70e83SPavel Labath return module_sp->GetSymbolFile();
4774b36f791SVedant Kumar return nullptr;
4784b36f791SVedant Kumar }
4794b36f791SVedant Kumar
GetDeclContext()480b9c1b51eSKate Stone CompilerDeclContext Block::GetDeclContext() {
4814b36f791SVedant Kumar if (SymbolFile *sym_file = GetSymbolFile())
48299558cc4SGreg Clayton return sym_file->GetDeclContextForUID(GetID());
48399558cc4SGreg Clayton return CompilerDeclContext();
48472e4940bSSean Callanan }
48572e4940bSSean Callanan
SetBlockInfoHasBeenParsed(bool b,bool set_children)486b9c1b51eSKate Stone void Block::SetBlockInfoHasBeenParsed(bool b, bool set_children) {
4870b76a2c2SGreg Clayton m_parsed_block_info = b;
488b9c1b51eSKate Stone if (set_children) {
4890b76a2c2SGreg Clayton m_parsed_child_blocks = true;
490624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
491624784a9SGreg Clayton for (pos = m_children.begin(); pos != end; ++pos)
492624784a9SGreg Clayton (*pos)->SetBlockInfoHasBeenParsed(b, true);
49330fdc8d8SChris Lattner }
49430fdc8d8SChris Lattner }
495c662ec8bSGreg Clayton
SetDidParseVariables(bool b,bool set_children)496b9c1b51eSKate Stone void Block::SetDidParseVariables(bool b, bool set_children) {
497c662ec8bSGreg Clayton m_parsed_block_variables = b;
498b9c1b51eSKate Stone if (set_children) {
499624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
500624784a9SGreg Clayton for (pos = m_children.begin(); pos != end; ++pos)
501624784a9SGreg Clayton (*pos)->SetDidParseVariables(b, true);
502c662ec8bSGreg Clayton }
503c662ec8bSGreg Clayton }
504c662ec8bSGreg Clayton
GetSibling() const505b9c1b51eSKate Stone Block *Block::GetSibling() const {
506b9c1b51eSKate Stone if (m_parent_scope) {
5076c7f5619SGreg Clayton Block *parent_block = GetParent();
508624784a9SGreg Clayton if (parent_block)
509624784a9SGreg Clayton return parent_block->GetSiblingForChild(this);
510624784a9SGreg Clayton }
511d4612ad0SEd Maste return nullptr;
512624784a9SGreg Clayton }
513624784a9SGreg Clayton // A parent of child blocks can be asked to find a sibling block given
514624784a9SGreg Clayton // one of its child blocks
GetSiblingForChild(const Block * child_block) const515b9c1b51eSKate Stone Block *Block::GetSiblingForChild(const Block *child_block) const {
516b9c1b51eSKate Stone if (!m_children.empty()) {
517624784a9SGreg Clayton collection::const_iterator pos, end = m_children.end();
518b9c1b51eSKate Stone for (pos = m_children.begin(); pos != end; ++pos) {
519b9c1b51eSKate Stone if (pos->get() == child_block) {
520624784a9SGreg Clayton if (++pos != end)
521624784a9SGreg Clayton return pos->get();
522624784a9SGreg Clayton break;
523624784a9SGreg Clayton }
524624784a9SGreg Clayton }
525624784a9SGreg Clayton }
526d4612ad0SEd Maste return nullptr;
527624784a9SGreg Clayton }
528