//===-- Block.cpp -----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/Block.h"

#include "lldb/lldb-private-log.h"

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

using namespace lldb;
using namespace lldb_private;

Block::Block(lldb::user_id_t uid) :
    UserID(uid),
    m_parent_scope (NULL),
    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() != NULL)
    {
        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: ", this);
    s->Indent();
    *s << "Block" << ((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() != NULL)
    {
        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 != NULL && parent_block->Contains(range) == false)
                *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 = NULL;
    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 NULL;
}

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

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) != NULL;
}

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 != NULL;
         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) != NULL;
}

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

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


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())
            {
                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",
                             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
            {
                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",
                             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.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
}



VariableListSP
Block::GetBlockVariableList (bool can_create)
{
    if (m_parsed_block_variables == false)
    {
        if (m_variable_list_sp.get() == NULL && can_create)
        {
            m_parsed_block_variables = true;
            SymbolContext sc;
            CalculateSymbolContext(&sc);
            assert(sc.module_sp);
            sc.module_sp->GetSymbolVendor()->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,
                             VariableList *variable_list)
{
    uint32_t num_variables_added = 0;
    VariableList *block_var_list = GetBlockVariableList (can_create).get();
    if (block_var_list)
    {
        num_variables_added += block_var_list->GetSize();
        variable_list->AddVariables (block_var_list);
    }
    
    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 == false || 
                child_block->GetInlinedFunctionInfo() == NULL)
            {
                num_variables_added += child_block->AppendBlockVariables (can_create,
                                                                          get_child_block_variables,
                                                                          stop_if_child_block_is_inlined_function,
                                                                          variable_list);
            }
        }
    }
    return num_variables_added;
}

uint32_t
Block::AppendVariables 
(
    bool can_create, 
    bool get_parent_variables, 
    bool stop_if_block_is_inlined_function,
    VariableList *variable_list
)
{
    uint32_t num_variables_added = 0;
    VariableListSP variable_list_sp(GetBlockVariableList(can_create));

    bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
    if (variable_list_sp.get())
    {
        num_variables_added = variable_list_sp->GetSize();
        variable_list->AddVariables(variable_list_sp.get());
    }
    
    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, variable_list);
    }
    return num_variables_added;
}

clang::DeclContext *
Block::GetClangDeclContext()
{
    SymbolContext sc;
    
    CalculateSymbolContext (&sc);
    
    if (!sc.module_sp)
        return NULL;
    
    SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
    
    if (!sym_vendor)
        return NULL;
    
    SymbolFile *sym_file = sym_vendor->GetSymbolFile();
    
    if (!sym_file)
        return NULL;
    
    return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
}

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

