//===-- Block.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/Block.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

Block::Block(lldb::user_id_t uid)
    : UserID(uid), m_parent_scope(nullptr), m_children(), m_ranges(),
      m_inlineInfoSP(), m_variable_list_sp(), m_parsed_block_info(false),
      m_parsed_block_variables(false), m_parsed_child_blocks(false) {}

Block::~Block() = default;

void Block::GetDescription(Stream *s, Function *function,
                           lldb::DescriptionLevel level, Target *target) const {
  *s << "id = " << ((const UserID &)*this);

  size_t num_ranges = m_ranges.GetSize();
  if (num_ranges > 0) {

    addr_t base_addr = LLDB_INVALID_ADDRESS;
    if (target)
      base_addr =
          function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
    if (base_addr == LLDB_INVALID_ADDRESS)
      base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();

    s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
    for (size_t i = 0; i < num_ranges; ++i) {
      const Range &range = m_ranges.GetEntryRef(i);
      DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
                       base_addr + range.GetRangeEnd(), 4);
    }
  }

  if (m_inlineInfoSP.get() != nullptr) {
    bool show_fullpaths = (level == eDescriptionLevelVerbose);
    m_inlineInfoSP->Dump(s, show_fullpaths);
  }
}

void Block::Dump(Stream *s, addr_t base_addr, int32_t depth,
                 bool show_context) const {
  if (depth < 0) {
    Block *parent = GetParent();
    if (parent) {
      // We have a depth that is less than zero, print our parent blocks first
      parent->Dump(s, base_addr, depth + 1, show_context);
    }
  }

  s->Printf("%p: ", static_cast<const void *>(this));
  s->Indent();
  *s << "Block" << static_cast<const UserID &>(*this);
  const Block *parent_block = GetParent();
  if (parent_block) {
    s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
  }
  if (m_inlineInfoSP.get() != nullptr) {
    bool show_fullpaths = false;
    m_inlineInfoSP->Dump(s, show_fullpaths);
  }

  if (!m_ranges.IsEmpty()) {
    *s << ", ranges =";

    size_t num_ranges = m_ranges.GetSize();
    for (size_t i = 0; i < num_ranges; ++i) {
      const Range &range = m_ranges.GetEntryRef(i);
      if (parent_block != nullptr && !parent_block->Contains(range))
        *s << '!';
      else
        *s << ' ';
      DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
                       base_addr + range.GetRangeEnd(), 4);
    }
  }
  s->EOL();

  if (depth > 0) {
    s->IndentMore();

    if (m_variable_list_sp.get()) {
      m_variable_list_sp->Dump(s, show_context);
    }

    collection::const_iterator pos, end = m_children.end();
    for (pos = m_children.begin(); pos != end; ++pos)
      (*pos)->Dump(s, base_addr, depth - 1, show_context);

    s->IndentLess();
  }
}

Block *Block::FindBlockByID(user_id_t block_id) {
  if (block_id == GetID())
    return this;

  Block *matching_block = nullptr;
  collection::const_iterator pos, end = m_children.end();
  for (pos = m_children.begin(); pos != end; ++pos) {
    matching_block = (*pos)->FindBlockByID(block_id);
    if (matching_block)
      break;
  }
  return matching_block;
}

Block *Block::FindInnermostBlockByOffset(const lldb::addr_t offset) {
  if (!Contains(offset))
    return nullptr;
  for (const BlockSP &block_sp : m_children) {
    if (Block *block = block_sp->FindInnermostBlockByOffset(offset))
      return block;
  }
  return this;
}

void Block::CalculateSymbolContext(SymbolContext *sc) {
  if (m_parent_scope)
    m_parent_scope->CalculateSymbolContext(sc);
  sc->block = this;
}

lldb::ModuleSP Block::CalculateSymbolContextModule() {
  if (m_parent_scope)
    return m_parent_scope->CalculateSymbolContextModule();
  return lldb::ModuleSP();
}

CompileUnit *Block::CalculateSymbolContextCompileUnit() {
  if (m_parent_scope)
    return m_parent_scope->CalculateSymbolContextCompileUnit();
  return nullptr;
}

Function *Block::CalculateSymbolContextFunction() {
  if (m_parent_scope)
    return m_parent_scope->CalculateSymbolContextFunction();
  return nullptr;
}

Block *Block::CalculateSymbolContextBlock() { return this; }

void Block::DumpSymbolContext(Stream *s) {
  Function *function = CalculateSymbolContextFunction();
  if (function)
    function->DumpSymbolContext(s);
  s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
}

void Block::DumpAddressRanges(Stream *s, lldb::addr_t base_addr) {
  if (!m_ranges.IsEmpty()) {
    size_t num_ranges = m_ranges.GetSize();
    for (size_t i = 0; i < num_ranges; ++i) {
      const Range &range = m_ranges.GetEntryRef(i);
      DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(),
                       base_addr + range.GetRangeEnd(), 4);
    }
  }
}

bool Block::Contains(addr_t range_offset) const {
  return m_ranges.FindEntryThatContains(range_offset) != nullptr;
}

bool Block::Contains(const Block *block) const {
  if (this == block)
    return false; // This block doesn't contain itself...

  // Walk the parent chain for "block" and see if any if them match this block
  const Block *block_parent;
  for (block_parent = block->GetParent(); block_parent != nullptr;
       block_parent = block_parent->GetParent()) {
    if (this == block_parent)
      return true; // One of the parents of "block" is this object!
  }
  return false;
}

bool Block::Contains(const Range &range) const {
  return m_ranges.FindEntryThatContains(range) != nullptr;
}

Block *Block::GetParent() const {
  if (m_parent_scope)
    return m_parent_scope->CalculateSymbolContextBlock();
  return nullptr;
}

Block *Block::GetContainingInlinedBlock() {
  if (GetInlinedFunctionInfo())
    return this;
  return GetInlinedParent();
}

Block *Block::GetInlinedParent() {
  Block *parent_block = GetParent();
  if (parent_block) {
    if (parent_block->GetInlinedFunctionInfo())
      return parent_block;
    else
      return parent_block->GetInlinedParent();
  }
  return nullptr;
}

Block *Block::GetContainingInlinedBlockWithCallSite(
    const Declaration &find_call_site) {
  Block *inlined_block = GetContainingInlinedBlock();

  while (inlined_block) {
    const auto *function_info = inlined_block->GetInlinedFunctionInfo();

    if (function_info &&
        function_info->GetCallSite().FileAndLineEqual(find_call_site))
      return inlined_block;
    inlined_block = inlined_block->GetInlinedParent();
  }
  return nullptr;
}

bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
  const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
  if (range_ptr) {
    range = *range_ptr;
    return true;
  }
  range.Clear();
  return false;
}

bool Block::GetRangeContainingAddress(const Address &addr,
                                      AddressRange &range) {
  Function *function = CalculateSymbolContextFunction();
  if (function) {
    const AddressRange &func_range = function->GetAddressRange();
    if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
      const addr_t addr_offset = addr.GetOffset();
      const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
      if (addr_offset >= func_offset &&
          addr_offset < func_offset + func_range.GetByteSize()) {
        addr_t offset = addr_offset - func_offset;

        const Range *range_ptr = m_ranges.FindEntryThatContains(offset);

        if (range_ptr) {
          range.GetBaseAddress() = func_range.GetBaseAddress();
          range.GetBaseAddress().SetOffset(func_offset +
                                           range_ptr->GetRangeBase());
          range.SetByteSize(range_ptr->GetByteSize());
          return true;
        }
      }
    }
  }
  range.Clear();
  return false;
}

bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
                                          Target &target, AddressRange &range) {
  Address load_address;
  load_address.SetLoadAddress(load_addr, &target);
  AddressRange containing_range;
  return GetRangeContainingAddress(load_address, containing_range);
}

uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
  Function *function = CalculateSymbolContextFunction();
  if (function) {
    const AddressRange &func_range = function->GetAddressRange();
    if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
      const addr_t addr_offset = addr.GetOffset();
      const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
      if (addr_offset >= func_offset &&
          addr_offset < func_offset + func_range.GetByteSize()) {
        addr_t offset = addr_offset - func_offset;
        return m_ranges.FindEntryIndexThatContains(offset);
      }
    }
  }
  return UINT32_MAX;
}

bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
  if (range_idx < m_ranges.GetSize()) {
    Function *function = CalculateSymbolContextFunction();
    if (function) {
      const Range &vm_range = m_ranges.GetEntryRef(range_idx);
      range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
      range.GetBaseAddress().Slide(vm_range.GetRangeBase());
      range.SetByteSize(vm_range.GetByteSize());
      return true;
    }
  }
  return false;
}

bool Block::GetStartAddress(Address &addr) {
  if (m_ranges.IsEmpty())
    return false;

  Function *function = CalculateSymbolContextFunction();
  if (function) {
    addr = function->GetAddressRange().GetBaseAddress();
    addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
    return true;
  }
  return false;
}

void Block::FinalizeRanges() {
  m_ranges.Sort();
  m_ranges.CombineConsecutiveRanges();
}

void Block::AddRange(const Range &range) {
  Block *parent_block = GetParent();
  if (parent_block && !parent_block->Contains(range)) {
    Log *log = GetLog(LLDBLog::Symbols);
    if (log) {
      ModuleSP module_sp(m_parent_scope->CalculateSymbolContextModule());
      Function *function = m_parent_scope->CalculateSymbolContextFunction();
      const addr_t function_file_addr =
          function->GetAddressRange().GetBaseAddress().GetFileAddress();
      const addr_t block_start_addr = function_file_addr + range.GetRangeBase();
      const addr_t block_end_addr = function_file_addr + range.GetRangeEnd();
      Type *func_type = function->GetType();

      const Declaration &func_decl = func_type->GetDeclaration();
      if (func_decl.GetLine()) {
        LLDB_LOGF(log,
                  "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",
                  func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
                  GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
                  block_end_addr, parent_block->GetID(), function->GetID(),
                  module_sp->GetFileSpec().GetPath().c_str());
      } else {
        LLDB_LOGF(log,
                  "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",
                  GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
                  block_end_addr, parent_block->GetID(), function->GetID(),
                  module_sp->GetFileSpec().GetPath().c_str());
      }
    }
    parent_block->AddRange(range);
  }
  m_ranges.Append(range);
}

// Return the current number of bytes that this object occupies in memory
size_t Block::MemorySize() const {
  size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
  if (m_inlineInfoSP.get())
    mem_size += m_inlineInfoSP->MemorySize();
  if (m_variable_list_sp.get())
    mem_size += m_variable_list_sp->MemorySize();
  return mem_size;
}

void Block::AddChild(const BlockSP &child_block_sp) {
  if (child_block_sp) {
    child_block_sp->SetParentScope(this);
    m_children.push_back(child_block_sp);
  }
}

void Block::SetInlinedFunctionInfo(const char *name, const char *mangled,
                                   const Declaration *decl_ptr,
                                   const Declaration *call_decl_ptr) {
  m_inlineInfoSP = std::make_shared<InlineFunctionInfo>(name, mangled, decl_ptr,
                                                        call_decl_ptr);
}

VariableListSP Block::GetBlockVariableList(bool can_create) {
  if (!m_parsed_block_variables) {
    if (m_variable_list_sp.get() == nullptr && can_create) {
      m_parsed_block_variables = true;
      SymbolContext sc;
      CalculateSymbolContext(&sc);
      assert(sc.module_sp);
      sc.module_sp->GetSymbolFile()->ParseVariablesForContext(sc);
    }
  }
  return m_variable_list_sp;
}

uint32_t
Block::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) {
  uint32_t num_variables_added = 0;
  VariableList *block_var_list = GetBlockVariableList(can_create).get();
  if (block_var_list) {
    for (const VariableSP &var_sp : *block_var_list) {
      if (filter(var_sp.get())) {
        num_variables_added++;
        variable_list->AddVariable(var_sp);
      }
    }
  }

  if (get_child_block_variables) {
    collection::const_iterator pos, end = m_children.end();
    for (pos = m_children.begin(); pos != end; ++pos) {
      Block *child_block = pos->get();
      if (!stop_if_child_block_is_inlined_function ||
          child_block->GetInlinedFunctionInfo() == nullptr) {
        num_variables_added += child_block->AppendBlockVariables(
            can_create, get_child_block_variables,
            stop_if_child_block_is_inlined_function, filter, variable_list);
      }
    }
  }
  return num_variables_added;
}

uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables,
                                bool stop_if_block_is_inlined_function,
                                const std::function<bool(Variable *)> &filter,
                                VariableList *variable_list) {
  uint32_t num_variables_added = 0;
  VariableListSP variable_list_sp(GetBlockVariableList(can_create));

  bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
  if (variable_list_sp) {
    for (size_t i = 0; i < variable_list_sp->GetSize(); ++i) {
      VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
      if (filter(variable.get())) {
        num_variables_added++;
        variable_list->AddVariable(variable);
      }
    }
  }

  if (get_parent_variables) {
    if (stop_if_block_is_inlined_function && is_inlined_function)
      return num_variables_added;

    Block *parent_block = GetParent();
    if (parent_block)
      num_variables_added += parent_block->AppendVariables(
          can_create, get_parent_variables, stop_if_block_is_inlined_function,
          filter, variable_list);
  }
  return num_variables_added;
}

SymbolFile *Block::GetSymbolFile() {
  if (ModuleSP module_sp = CalculateSymbolContextModule())
    return module_sp->GetSymbolFile();
  return nullptr;
}

CompilerDeclContext Block::GetDeclContext() {
  if (SymbolFile *sym_file = GetSymbolFile())
    return sym_file->GetDeclContextForUID(GetID());
  return CompilerDeclContext();
}

void Block::SetBlockInfoHasBeenParsed(bool b, bool set_children) {
  m_parsed_block_info = b;
  if (set_children) {
    m_parsed_child_blocks = true;
    collection::const_iterator pos, end = m_children.end();
    for (pos = m_children.begin(); pos != end; ++pos)
      (*pos)->SetBlockInfoHasBeenParsed(b, true);
  }
}

void Block::SetDidParseVariables(bool b, bool set_children) {
  m_parsed_block_variables = b;
  if (set_children) {
    collection::const_iterator pos, end = m_children.end();
    for (pos = m_children.begin(); pos != end; ++pos)
      (*pos)->SetDidParseVariables(b, true);
  }
}

Block *Block::GetSibling() const {
  if (m_parent_scope) {
    Block *parent_block = GetParent();
    if (parent_block)
      return parent_block->GetSiblingForChild(this);
  }
  return nullptr;
}
// A parent of child blocks can be asked to find a sibling block given
// one of its child blocks
Block *Block::GetSiblingForChild(const Block *child_block) const {
  if (!m_children.empty()) {
    collection::const_iterator pos, end = m_children.end();
    for (pos = m_children.begin(); pos != end; ++pos) {
      if (pos->get() == child_block) {
        if (++pos != end)
          return pos->get();
        break;
      }
    }
  }
  return nullptr;
}
