//===-- VariableList.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/VariableList.h"

#include "lldb/Core/RegularExpression.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/CompileUnit.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// VariableList constructor
//----------------------------------------------------------------------
VariableList::VariableList() :
    m_variables()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
VariableList::~VariableList()
{
}

void
VariableList::AddVariable(const VariableSP &var_sp)
{
    m_variables.push_back(var_sp);
}

bool
VariableList::AddVariableIfUnique (const lldb::VariableSP &var_sp)
{
    if (FindVariableIndex (var_sp) == UINT32_MAX)
    {
        m_variables.push_back(var_sp);
        return true;
    }
    return false;
}

void
VariableList::AddVariables(VariableList *variable_list)
{
    if (variable_list)
    {
        std::copy(variable_list->m_variables.begin(), // source begin
                  variable_list->m_variables.end(),   // source end
                  back_inserter(m_variables));        // destination
    }
}

void
VariableList::Clear()
{
    m_variables.clear();
}

VariableSP
VariableList::GetVariableAtIndex(size_t idx) const
{
    VariableSP var_sp;
    if (idx < m_variables.size())
        var_sp = m_variables[idx];
    return var_sp;
}

VariableSP
VariableList::RemoveVariableAtIndex(size_t idx)
{
    VariableSP var_sp;
    if (idx < m_variables.size())
    {
        var_sp = m_variables[idx];
        m_variables.erase (m_variables.begin() + idx);
    }
    return var_sp;
}

uint32_t
VariableList::FindVariableIndex (const VariableSP &var_sp)
{
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if (pos->get() == var_sp.get())
            return std::distance (m_variables.begin(), pos);
    }
    return UINT32_MAX;
}

VariableSP
VariableList::FindVariable(const ConstString& name, bool include_static_members)
{
    VariableSP var_sp;
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->NameMatches(name))
        {
            if (include_static_members || !(*pos)->IsStaticMember())
            {
                var_sp = (*pos);
                break;
            }
        }
    }
    return var_sp;
}

VariableSP
VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members)
{
    VariableSP var_sp;
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->NameMatches(name) && (*pos)->GetScope() == value_type)
        {
            if (include_static_members || !(*pos)->IsStaticMember())
            {
                var_sp = (*pos);
                break;
            }
        }
    }
    return var_sp;
}

size_t
VariableList::AppendVariablesIfUnique(VariableList &var_list)
{
    const size_t initial_size = var_list.GetSize();
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
        var_list.AddVariableIfUnique(*pos);
    return var_list.GetSize() - initial_size;
}

size_t
VariableList::AppendVariablesIfUnique (const RegularExpression& regex, VariableList &var_list, size_t& total_matches)
{
    const size_t initial_size = var_list.GetSize();
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->NameMatches (regex))
        {
            // Note the total matches found
            total_matches++;
            // Only add this variable if it isn't already in the "var_list"
            var_list.AddVariableIfUnique (*pos);
        }
    }
    // Return the number of new unique variables added to "var_list"
    return var_list.GetSize() - initial_size;
}

size_t
VariableList::AppendVariablesWithScope (lldb::ValueType type,
                                        VariableList &var_list,
                                        bool if_unique)
{
    const size_t initial_size = var_list.GetSize();
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->GetScope() == type)
        {
            if (if_unique)
                var_list.AddVariableIfUnique (*pos);
            else
                var_list.AddVariable(*pos);
        }
    }
    // Return the number of new unique variables added to "var_list"
    return var_list.GetSize() - initial_size;
}

uint32_t
VariableList::FindIndexForVariable (Variable* variable)
{
    VariableSP var_sp;
    iterator pos;
    const iterator begin = m_variables.begin();
    const iterator end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos).get() == variable)
            return std::distance (begin, pos);
    }
    return UINT32_MAX;
}

size_t
VariableList::MemorySize() const
{
    size_t mem_size = sizeof(VariableList);
    const_iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
        mem_size += (*pos)->MemorySize();
    return mem_size;
}

size_t
VariableList::GetSize() const
{
    return m_variables.size();
}

void
VariableList::Dump(Stream *s, bool show_context) const
{
//  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
//  s.Indent();
//  s << "VariableList\n";

    const_iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        (*pos)->Dump(s, show_context);
    }
}
