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

#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// Variable constructor
//----------------------------------------------------------------------
Variable::Variable 
(
    lldb::user_id_t uid,
    const char *name, 
    const char *mangled,   // The mangled variable name for variables in namespaces
    const lldb::SymbolFileTypeSP &symfile_type_sp,
    ValueType scope,
    SymbolContextScope *context,
    Declaration* decl_ptr,
    const DWARFExpression& location,
    bool external,
    bool artificial
) :
    UserID(uid),
    m_name(name),
    m_mangled (ConstString(mangled), true),
    m_symfile_type_sp(symfile_type_sp),
    m_scope(scope),
    m_owner_scope(context),
    m_declaration(decl_ptr),
    m_location(location),
    m_external(external),
    m_artificial(artificial)
{
}

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


const ConstString&
Variable::GetName() const
{
    if (m_mangled)
        return m_mangled.GetName();
    return m_name;
}

bool
Variable::NameMatches (const RegularExpression& regex) const
{
    if (regex.Execute (m_name.AsCString()))
        return true;
    return m_mangled.NameMatches (regex);
}

Type *
Variable::GetType()
{
    if (m_symfile_type_sp)
        return m_symfile_type_sp->GetType();
    return nullptr;
}

void
Variable::Dump(Stream *s, bool show_context) const
{
    s->Printf("%p: ", static_cast<const void*>(this));
    s->Indent();
    *s << "Variable" << (const UserID&)*this;

    if (m_name)
        *s << ", name = \"" << m_name << "\"";

    if (m_symfile_type_sp)
    {
        Type *type = m_symfile_type_sp->GetType();
        if (type)
        {
            *s << ", type = {" << type->GetID() << "} " << (void*)type << " (";
            type->DumpTypeName(s);
            s->PutChar(')');
        }
    }

    if (m_scope != eValueTypeInvalid)
    {
        s->PutCString(", scope = ");
        switch (m_scope)
        {
        case eValueTypeVariableGlobal:       s->PutCString(m_external ? "global" : "static"); break;
        case eValueTypeVariableArgument:    s->PutCString("parameter"); break;
        case eValueTypeVariableLocal:        s->PutCString("local"); break;
        default:            *s << "??? (" << m_scope << ')';
        }
    }

    if (show_context && m_owner_scope != nullptr)
    {
        s->PutCString(", context = ( ");
        m_owner_scope->DumpSymbolContext(s);
        s->PutCString(" )");
    }

    bool show_fullpaths = false;
    m_declaration.Dump(s, show_fullpaths);

    if (m_location.IsValid())
    {
        s->PutCString(", location = ");
        lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
        if (m_location.IsLocationList())
        {
            SymbolContext variable_sc;
            m_owner_scope->CalculateSymbolContext(&variable_sc);
            if (variable_sc.function)
                loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
        }
        ABI *abi = nullptr;
        if (m_owner_scope)
        {
            ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule());
            if (module_sp)
                abi = ABI::FindPlugin (module_sp->GetArchitecture()).get();
        }
        m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr, abi);
    }

    if (m_external)
        s->PutCString(", external");

    if (m_artificial)
        s->PutCString(", artificial");

    s->EOL();
}

bool
Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module)
{
    bool dumped_declaration_info = false;
    if (m_owner_scope)
    {
        SymbolContext sc;
        m_owner_scope->CalculateSymbolContext(&sc);
        sc.block = nullptr;
        sc.line_entry.Clear();
        bool show_inlined_frames = false;
    
        dumped_declaration_info = sc.DumpStopContext (s, 
                                                      nullptr,
                                                      Address(), 
                                                      show_fullpaths, 
                                                      show_module, 
                                                      show_inlined_frames);
        
        if (sc.function)
            s->PutChar(':');
    }
    if (m_declaration.DumpStopContext (s, false))
        dumped_declaration_info = true;
    return dumped_declaration_info;
}

size_t
Variable::MemorySize() const
{
    return sizeof(Variable);
}


void
Variable::CalculateSymbolContext (SymbolContext *sc)
{
    if (m_owner_scope)
        m_owner_scope->CalculateSymbolContext(sc);
    else
        sc->Clear(false);
}

bool
Variable::LocationIsValidForFrame (StackFrame *frame)
{
    // Is the variable is described by a single location?
    if (!m_location.IsLocationList())
    {
        // Yes it is, the location is valid. 
        return true;
    }

    if (frame)
    {
        Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
        if (function)
        {
            TargetSP target_sp (frame->CalculateTarget());
            
            addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target_sp.get());
            if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
                return false;
            // It is a location list. We just need to tell if the location
            // list contains the current address when converted to a load
            // address
            return m_location.LocationListContainsAddress (loclist_base_load_addr, 
                                                           frame->GetFrameCodeAddress().GetLoadAddress (target_sp.get()));
        }
    }
    return false;
}

bool
Variable::LocationIsValidForAddress (const Address &address)
{
    // Be sure to resolve the address to section offset prior to 
    // calling this function.
    if (address.IsSectionOffset())
    {
        SymbolContext sc;
        CalculateSymbolContext(&sc);
        if (sc.module_sp == address.GetModule())
        {
            // Is the variable is described by a single location?
            if (!m_location.IsLocationList())
            {
                // Yes it is, the location is valid. 
                return true;
            }
            
            if (sc.function)
            {
                addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
                if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
                    return false;
                // It is a location list. We just need to tell if the location
                // list contains the current address when converted to a load
                // address
                return m_location.LocationListContainsAddress (loclist_base_file_addr, 
                                                               address.GetFileAddress());
            }
        }
    }
    return false;
}

bool
Variable::IsInScope (StackFrame *frame)
{
    switch (m_scope)
    {
    case eValueTypeRegister:
    case eValueTypeRegisterSet:
        return frame != nullptr;

    case eValueTypeConstResult:
    case eValueTypeVariableGlobal:
    case eValueTypeVariableStatic:
        return true;

    case eValueTypeVariableArgument:
    case eValueTypeVariableLocal:
        if (frame)
        {
            // We don't have a location list, we just need to see if the block
            // that this variable was defined in is currently
            Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
            if (deepest_frame_block)
            {
                SymbolContext variable_sc;
                CalculateSymbolContext (&variable_sc);
                // Check for static or global variable defined at the compile unit 
                // level that wasn't defined in a block
                if (variable_sc.block == nullptr)
                    return true;    

                if (variable_sc.block == deepest_frame_block)
                    return true;
                return variable_sc.block->Contains (deepest_frame_block);
            }
        }
        break;

    default:
        break;
    }
    return false;
}

Error
Variable::GetValuesForVariableExpressionPath (const char *variable_expr_path,
                                              ExecutionContextScope *scope,
                                              GetVariableCallback callback,
                                              void *baton,
                                              VariableList &variable_list,
                                              ValueObjectList &valobj_list)
{
    Error error;
    if (variable_expr_path && callback)
    {
        switch (variable_expr_path[0])
        {
        case '*':
            {
                error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1,
                                                                      scope,
                                                                      callback,
                                                                      baton,
                                                                      variable_list,
                                                                      valobj_list);
                if (error.Success())
                {
                    for (uint32_t i=0; i<valobj_list.GetSize(); )
                    {
                        Error tmp_error;
                        ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error));
                        if (tmp_error.Fail())
                        {
                            variable_list.RemoveVariableAtIndex (i);
                            valobj_list.RemoveValueObjectAtIndex (i);
                        }
                        else
                        {
                            valobj_list.SetValueObjectAtIndex (i, valobj_sp);
                            ++i;
                        }
                    }
                }
                else
                {
                    error.SetErrorString ("unknown error");
                }
                return error;
            }
            break;
        
        case '&':
            {
                error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1,
                                                                      scope,
                                                                      callback,
                                                                      baton,
                                                                      variable_list,
                                                                      valobj_list);
                if (error.Success())
                {
                    for (uint32_t i=0; i<valobj_list.GetSize(); )
                    {
                        Error tmp_error;
                        ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error));
                        if (tmp_error.Fail())
                        {
                            variable_list.RemoveVariableAtIndex (i);
                            valobj_list.RemoveValueObjectAtIndex (i);
                        }
                        else
                        {
                            valobj_list.SetValueObjectAtIndex (i, valobj_sp);
                            ++i;
                        }
                    }
                }
                else
                {
                    error.SetErrorString ("unknown error");
                }
                return error;
            }
            break;
            
        default:
            {
                static RegularExpression g_regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
                RegularExpression::Match regex_match(1);
                if (g_regex.Execute(variable_expr_path, &regex_match))
                {
                    std::string variable_name;
                    if (regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name))
                    {
                        variable_list.Clear();
                        if (callback (baton, variable_name.c_str(), variable_list))
                        {
                            uint32_t i=0;
                            while (i < variable_list.GetSize())
                            {
                                VariableSP var_sp (variable_list.GetVariableAtIndex (i));
                                ValueObjectSP valobj_sp;
                                if (var_sp)
                                {
                                    ValueObjectSP variable_valobj_sp(ValueObjectVariable::Create (scope, var_sp));
                                    if (variable_valobj_sp)
                                    {
                                        const char *variable_sub_expr_path = variable_expr_path + variable_name.size();
                                        if (*variable_sub_expr_path)
                                        {
                                            const char* first_unparsed = nullptr;
                                            ValueObject::ExpressionPathScanEndReason reason_to_stop;
                                            ValueObject::ExpressionPathEndResultType final_value_type;
                                            ValueObject::GetValueForExpressionPathOptions options;
                                            ValueObject::ExpressionPathAftermath final_task_on_target;

                                            valobj_sp = variable_valobj_sp->GetValueForExpressionPath (variable_sub_expr_path,
                                                                                                       &first_unparsed,
                                                                                                       &reason_to_stop,
                                                                                                       &final_value_type,
                                                                                                       options,
                                                                                                       &final_task_on_target);
                                            if (!valobj_sp)
                                            {
                                                error.SetErrorStringWithFormat ("invalid expression path '%s' for variable '%s'",
                                                                                variable_sub_expr_path,
                                                                                var_sp->GetName().GetCString());
                                            }
                                        }
                                        else
                                        {
                                            // Just the name of a variable with no extras
                                            valobj_sp = variable_valobj_sp;
                                        }
                                    }
                                }

                                if (!var_sp || !valobj_sp)
                                {
                                    variable_list.RemoveVariableAtIndex (i);
                                }
                                else
                                {
                                    valobj_list.Append(valobj_sp);
                                    ++i;
                                }
                            }
                            
                            if (variable_list.GetSize() > 0)
                            {
                                error.Clear();
                                return error;
                            }
                        }
                    }
                }
                error.SetErrorStringWithFormat ("unable to extract a variable name from '%s'", variable_expr_path);
            }
            break;
        }
    }
    error.SetErrorString ("unknown error");
    return error;
}

bool
Variable::DumpLocationForAddress (Stream *s, const Address &address)
{
    // Be sure to resolve the address to section offset prior to 
    // calling this function.
    if (address.IsSectionOffset())
    {
        SymbolContext sc;
        CalculateSymbolContext(&sc);
        if (sc.module_sp == address.GetModule())
        {
            ABI *abi = nullptr;
            if (m_owner_scope)
            {
                ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule());
                if (module_sp)
                    abi = ABI::FindPlugin (module_sp->GetArchitecture()).get();
            }

            const addr_t file_addr = address.GetFileAddress();
            if (sc.function)
            {
                if (sc.function->GetAddressRange().ContainsFileAddress(address))
                {
                    addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
                    if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
                        return false;
                    return m_location.DumpLocationForAddress (s, 
                                                              eDescriptionLevelBrief, 
                                                              loclist_base_file_addr, 
                                                              file_addr,
                                                              abi);
                }
            }
            return m_location.DumpLocationForAddress (s, 
                                                      eDescriptionLevelBrief, 
                                                      LLDB_INVALID_ADDRESS, 
                                                      file_addr,
                                                      abi);
        }
    }
    return false;
}


static void
PrivateAutoComplete (StackFrame *frame,
                     const std::string &partial_path,
                     const std::string &prefix_path, // Anything that has been resolved already will be in here
                     const ClangASTType& clang_type,
                     StringList &matches,
                     bool &word_complete);

static void
PrivateAutoCompleteMembers (StackFrame *frame,
                            const std::string &partial_member_name,
                            const std::string &partial_path,
                            const std::string &prefix_path, // Anything that has been resolved already will be in here
                            const ClangASTType& clang_type,
                            StringList &matches,
                            bool &word_complete);

static void
PrivateAutoCompleteMembers (StackFrame *frame,
                            const std::string &partial_member_name,
                            const std::string &partial_path,
                            const std::string &prefix_path, // Anything that has been resolved already will be in here
                            const ClangASTType& clang_type,
                            StringList &matches,
                            bool &word_complete)
{

    // We are in a type parsing child members
    const uint32_t num_bases = clang_type.GetNumDirectBaseClasses();
    
    if (num_bases > 0)
    {
        for (uint32_t i = 0; i < num_bases; ++i)
        {
            ClangASTType base_class_type (clang_type.GetDirectBaseClassAtIndex (i, nullptr));
            
            PrivateAutoCompleteMembers (frame,
                                        partial_member_name,
                                        partial_path,
                                        prefix_path,
                                        base_class_type.GetCanonicalType(),
                                        matches,
                                        word_complete);
        }
    }

    const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses();
    
    if (num_vbases > 0)
    {
        for (uint32_t i = 0; i < num_vbases; ++i)
        {
            ClangASTType vbase_class_type (clang_type.GetVirtualBaseClassAtIndex(i,nullptr));
            
            PrivateAutoCompleteMembers (frame,
                                        partial_member_name,
                                        partial_path,
                                        prefix_path,
                                        vbase_class_type.GetCanonicalType(),
                                        matches,
                                        word_complete);
        }
    }

    // We are in a type parsing child members
    const uint32_t num_fields = clang_type.GetNumFields();
    
    if (num_fields > 0)
    {
        for (uint32_t i = 0; i < num_fields; ++i)
        {
            std::string member_name;
            
            ClangASTType member_clang_type = clang_type.GetFieldAtIndex (i, member_name, nullptr, nullptr, nullptr);
            
            if (partial_member_name.empty() ||
                member_name.find(partial_member_name) == 0)
            {
                if (member_name == partial_member_name)
                {
                    PrivateAutoComplete (frame,
                                         partial_path,
                                         prefix_path + member_name, // Anything that has been resolved already will be in here
                                         member_clang_type.GetCanonicalType(),
                                         matches,
                                         word_complete);
                }
                else
                {
                    matches.AppendString (prefix_path + member_name);
                }
            }
        }
    }
}

static void
PrivateAutoComplete (StackFrame *frame,
                     const std::string &partial_path,
                     const std::string &prefix_path, // Anything that has been resolved already will be in here
                     const ClangASTType& clang_type,
                     StringList &matches,
                     bool &word_complete)
{
//    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str());
    std::string remaining_partial_path;

    const lldb::TypeClass type_class = clang_type.GetTypeClass();
    if (partial_path.empty())
    {
        if (clang_type.IsValid())
        {
            switch (type_class)
            {
                default:
                case eTypeClassArray:
                case eTypeClassBlockPointer:
                case eTypeClassBuiltin:
                case eTypeClassComplexFloat:
                case eTypeClassComplexInteger:
                case eTypeClassEnumeration:
                case eTypeClassFunction:
                case eTypeClassMemberPointer:
                case eTypeClassReference:
                case eTypeClassTypedef:
                case eTypeClassVector:
                    {
                        matches.AppendString (prefix_path);
                        word_complete = matches.GetSize() == 1;
                    }
                    break;
                    
                case eTypeClassClass:
                case eTypeClassStruct:
                case eTypeClassUnion:
                    if (prefix_path.back() != '.')
                        matches.AppendString (prefix_path + '.');
                    break;

                case eTypeClassObjCObject:
                case eTypeClassObjCInterface:
                    break;
                case eTypeClassObjCObjectPointer:
                case eTypeClassPointer:
                    {
                        bool omit_empty_base_classes = true;
                        if (clang_type.GetNumChildren (omit_empty_base_classes) > 0)
                            matches.AppendString (prefix_path + "->");
                        else
                        {
                            matches.AppendString (prefix_path);
                            word_complete = true;
                        }
                    }
                    break;
            }
        }
        else
        {
            if (frame)
            {
                const bool get_file_globals = true;
                
                VariableList *variable_list = frame->GetVariableList(get_file_globals);
                
                if (variable_list)
                {
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        matches.AppendString (variable->GetName().AsCString());
                    }
                }
            }
        }
    }
    else
    {
        const char ch = partial_path[0];
        switch (ch)
        {
        case '*':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("*"),
                                     clang_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '&':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("&"),
                                     clang_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '-':
            if (partial_path[1] == '>' && !prefix_path.empty())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassPointer:
                        {
                            ClangASTType pointee_type(clang_type.GetPointeeType());
                            if (partial_path[2])
                            {
                                // If there is more after the "->", then search deeper
                                PrivateAutoComplete (frame,
                                                     partial_path.substr(2),
                                                     prefix_path + "->",
                                                     pointee_type.GetCanonicalType(),
                                                     matches,
                                                     word_complete);
                            }
                            else
                            {
                                // Nothing after the "->", so list all members
                                PrivateAutoCompleteMembers (frame,
                                                            std::string(),
                                                            std::string(),
                                                            prefix_path + "->",
                                                            pointee_type.GetCanonicalType(),
                                                            matches,
                                                            word_complete);                            
                            }
                        }
                    default:
                        break;
                }
            }
            break;
            
        case '.':
            if (clang_type.IsValid())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassUnion:
                    case lldb::eTypeClassStruct:
                    case lldb::eTypeClassClass:
                        if (partial_path[1])
                        {
                            // If there is more after the ".", then search deeper
                            PrivateAutoComplete (frame,
                                                 partial_path.substr(1),
                                                 prefix_path + ".",
                                                 clang_type,
                                                 matches,
                                                 word_complete);
                            
                        }
                        else
                        {
                            // Nothing after the ".", so list all members
                            PrivateAutoCompleteMembers (frame,
                                                        std::string(),
                                                        partial_path,
                                                        prefix_path + ".",
                                                        clang_type,
                                                        matches,
                                                        word_complete);
                        }
                    default:
                        break;
                }
            }
            break;
        default:
            if (isalpha(ch) || ch == '_' || ch == '$')
            {
                const size_t partial_path_len = partial_path.size();
                size_t pos = 1;
                while (pos < partial_path_len)
                {
                    const char curr_ch = partial_path[pos];
                    if (isalnum(curr_ch) || curr_ch == '_'  || curr_ch == '$')
                    {
                        ++pos;
                        continue;
                    }
                    break;
                }

                std::string token(partial_path, 0, pos);
                remaining_partial_path = partial_path.substr(pos);
                
                if (clang_type.IsValid())
                {
                    PrivateAutoCompleteMembers (frame,
                                                token,
                                                remaining_partial_path,
                                                prefix_path,
                                                clang_type,
                                                matches,
                                                word_complete);
                }
                else if (frame)
                {
                    // We haven't found our variable yet
                    const bool get_file_globals = true;
                    
                    VariableList *variable_list = frame->GetVariableList(get_file_globals);
                    
                    if (!variable_list)
                        break;
                    
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        
                        if (!variable)
                            continue;
                        
                        const char *variable_name = variable->GetName().AsCString();
                        if (strstr(variable_name, token.c_str()) == variable_name)
                        {
                            if (strcmp (variable_name, token.c_str()) == 0)
                            {
                                Type *variable_type = variable->GetType();
                                if (variable_type)
                                {
                                    ClangASTType variable_clang_type (variable_type->GetClangForwardType());
                                    PrivateAutoComplete (frame,
                                                         remaining_partial_path,
                                                         prefix_path + token, // Anything that has been resolved already will be in here
                                                         variable_clang_type.GetCanonicalType(),
                                                         matches,
                                                         word_complete);
                                }
                                else
                                {
                                    matches.AppendString (prefix_path + variable_name);
                                }
                            }
                            else if (remaining_partial_path.empty())
                            {
                                matches.AppendString (prefix_path + variable_name);
                            }
                        }
                    }
                }
            }
            break;
        }
    }
}



size_t
Variable::AutoComplete (const ExecutionContext &exe_ctx,
                        const char *partial_path_cstr,
                        StringList &matches,
                        bool &word_complete)
{
    word_complete = false;
    std::string partial_path;
    std::string prefix_path;
    ClangASTType clang_type;
    if (partial_path_cstr && partial_path_cstr[0])
        partial_path = partial_path_cstr;

    PrivateAutoComplete (exe_ctx.GetFramePtr(),
                         partial_path,
                         prefix_path,
                         clang_type,
                         matches,
                         word_complete);

    return matches.GetSize();
}

