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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

#pragma mark ValueObjectRegisterContext

ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP &reg_ctx) :
    ValueObject (parent),
    m_reg_ctx_sp (reg_ctx)
{
    assert (reg_ctx);
    m_name.SetCString("Registers");
    SetValueIsValid (true);
}

ValueObjectRegisterContext::~ValueObjectRegisterContext()
{
}

lldb::clang_type_t
ValueObjectRegisterContext::GetClangTypeImpl ()
{
    return NULL;
}

ConstString
ValueObjectRegisterContext::GetTypeName()
{
    return ConstString();
}

ConstString
ValueObjectRegisterContext::GetQualifiedTypeName()
{
    return ConstString();
}

size_t
ValueObjectRegisterContext::CalculateNumChildren()
{
    return m_reg_ctx_sp->GetRegisterSetCount();
}

clang::ASTContext *
ValueObjectRegisterContext::GetClangASTImpl ()
{
    return NULL;
}

uint64_t
ValueObjectRegisterContext::GetByteSize()
{
    return 0;
}

bool
ValueObjectRegisterContext::UpdateValue ()
{
    m_error.Clear();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame)
        m_reg_ctx_sp = frame->GetRegisterContext();
    else
        m_reg_ctx_sp.reset();

    if (m_reg_ctx_sp.get() == NULL)
    {
        SetValueIsValid (false);
        m_error.SetErrorToGenericError();
    }
    else
        SetValueIsValid (true);
        
    return m_error.Success();
}

ValueObject *
ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
    ValueObject *new_valobj = NULL;
    
    const size_t num_children = GetNumChildren();
    if (idx < num_children)
    {
        ExecutionContext exe_ctx(GetExecutionContextRef());
        new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
    }
    
    return new_valobj;
}


#pragma mark -
#pragma mark ValueObjectRegisterSet

ValueObjectSP
ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
{
    return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
}


ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
    ValueObject (exe_scope),
    m_reg_ctx_sp (reg_ctx),
    m_reg_set (NULL),
    m_reg_set_idx (reg_set_idx)
{
    assert (reg_ctx);
    m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
    if (m_reg_set)
    {
        m_name.SetCString (m_reg_set->name);
    }
}

ValueObjectRegisterSet::~ValueObjectRegisterSet()
{
}

lldb::clang_type_t
ValueObjectRegisterSet::GetClangTypeImpl ()
{
    return NULL;
}

ConstString
ValueObjectRegisterSet::GetTypeName()
{
    return ConstString();
}

ConstString
ValueObjectRegisterSet::GetQualifiedTypeName()
{
    return ConstString();
}

size_t
ValueObjectRegisterSet::CalculateNumChildren()
{
    const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
    if (reg_set)
        return reg_set->num_registers;
    return 0;
}

clang::ASTContext *
ValueObjectRegisterSet::GetClangASTImpl ()
{
    return NULL;
}

uint64_t
ValueObjectRegisterSet::GetByteSize()
{
    return 0;
}

bool
ValueObjectRegisterSet::UpdateValue ()
{
    m_error.Clear();
    SetValueDidChange (false);
    ExecutionContext exe_ctx(GetExecutionContextRef());
    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame == NULL)
        m_reg_ctx_sp.reset();
    else
    {
        m_reg_ctx_sp = frame->GetRegisterContext ();
        if (m_reg_ctx_sp)
        {
            const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
            if (reg_set == NULL)
                m_reg_ctx_sp.reset();
            else if (m_reg_set != reg_set)
            {
                SetValueDidChange (true);
                m_name.SetCString(reg_set->name);
            }
        }
    }
    if (m_reg_ctx_sp)
    {
        SetValueIsValid (true);
    }
    else
    {
        SetValueIsValid (false);
        m_error.SetErrorToGenericError ();
        m_children.Clear();
    }
    return m_error.Success();
}


ValueObject *
ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
    ValueObject *valobj = NULL;
    if (m_reg_ctx_sp && m_reg_set)
    {
        const size_t num_children = GetNumChildren();
        if (idx < num_children)
            valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
    }
    return valobj;
}

lldb::ValueObjectSP
ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
{
    ValueObject *valobj = NULL;
    if (m_reg_ctx_sp && m_reg_set)
    {
        const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
        if (reg_info != NULL)
            valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
    }
    if (valobj)
        return valobj->GetSP();
    else
        return ValueObjectSP();
}

size_t
ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
{
    if (m_reg_ctx_sp && m_reg_set)
    {
        const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
        if (reg_info != NULL)
            return reg_info->kinds[eRegisterKindLLDB];
    }
    return UINT32_MAX;
}

#pragma mark -
#pragma mark ValueObjectRegister

void
ValueObjectRegister::ConstructObject (uint32_t reg_num)
{
    const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
    if (reg_info)
    {
        m_reg_info = *reg_info;
        if (reg_info->name)
            m_name.SetCString(reg_info->name);
        else if (reg_info->alt_name)
            m_name.SetCString(reg_info->alt_name);
    }
}

ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num) :
    ValueObject (parent),
    m_reg_ctx_sp (reg_ctx_sp),
    m_reg_info (),
    m_reg_value (),
    m_type_name (),
    m_clang_type (NULL)
{
    assert (reg_ctx_sp.get());
    ConstructObject(reg_num);
}

ValueObjectSP
ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
{
    return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
}

ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
    ValueObject (exe_scope),
    m_reg_ctx_sp (reg_ctx),
    m_reg_info (),
    m_reg_value (),
    m_type_name (),
    m_clang_type (NULL)
{
    assert (reg_ctx);
    ConstructObject(reg_num);
}

ValueObjectRegister::~ValueObjectRegister()
{
}

lldb::clang_type_t
ValueObjectRegister::GetClangTypeImpl ()
{
    if (m_clang_type == NULL)
    {
        ExecutionContext exe_ctx (GetExecutionContextRef());
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
        {
            Module *exe_module = target->GetExecutableModulePointer();
            if (exe_module)
            {
                m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding, 
                                                                                                     m_reg_info.byte_size * 8);
            }
        }
    }
    return m_clang_type;
}

ConstString
ValueObjectRegister::GetTypeName()
{
    if (m_type_name.IsEmpty())
        m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
    return m_type_name;
}

size_t
ValueObjectRegister::CalculateNumChildren()
{
    return ClangASTContext::GetNumChildren(GetClangAST(), GetClangType(), true);
}

clang::ASTContext *
ValueObjectRegister::GetClangASTImpl ()
{
    ExecutionContext exe_ctx (GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
    {
        Module *exe_module = target->GetExecutableModulePointer();
        if (exe_module)
            return exe_module->GetClangASTContext().getASTContext();
    }
    return NULL;
}

uint64_t
ValueObjectRegister::GetByteSize()
{
    return m_reg_info.byte_size;
}

bool
ValueObjectRegister::UpdateValue ()
{
    m_error.Clear();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame == NULL)
    {
        m_reg_ctx_sp.reset();
        m_reg_value.Clear();
    }


    if (m_reg_ctx_sp)
    {
        if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
        {
            if (m_reg_value.GetData (m_data))
            {
                Process *process = exe_ctx.GetProcessPtr();
                if (process)
                    m_data.SetAddressByteSize(process->GetAddressByteSize());
                m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
                m_value.SetValueType(Value::eValueTypeHostAddress);
                m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
                SetValueIsValid (true);
                return true;
            }
        }
    }
    
    SetValueIsValid (false);
    m_error.SetErrorToGenericError ();
    return false;
}

bool
ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
{
    // The new value will be in the m_data.  Copy that into our register value.
    error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
    if (error.Success())
    {
        if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
        {
            SetNeedsUpdate();
            return true;
        }
        else
            return false;
    }
    else
        return false;
}

bool
ValueObjectRegister::SetData (DataExtractor &data, Error &error)
{
    error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
    if (error.Success())
    {
        if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
        {
            SetNeedsUpdate();
            return true;
        }
        else
            return false;
    }
    else
        return false;
}

bool
ValueObjectRegister::ResolveValue (Scalar &scalar)
{
    if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
        return m_reg_value.GetScalarValue(scalar);
    return false;
}

void
ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
{
    s.Printf("$%s", m_reg_info.name);
}


