//===-- Block.cpp -----------------------------------------------*- C++ -*-===//
//
// 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/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() {}

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);
      s->AddressRange(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 << ' ';
      s->AddressRange(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;
}

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);
      s->AddressRange(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(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_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 (size_t i = 0; i < block_var_list->GetSize(); ++i) {
      VariableSP variable = block_var_list->GetVariableAtIndex(i);
      if (filter(variable.get())) {
        num_variables_added++;
        variable_list->AddVariable(variable);
      }
    }
  }

  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;
}
