//===-- 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();
}

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

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

size_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 (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
    ValueObject *new_valobj = NULL;
    
    const uint32_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();
}

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

size_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 (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
    ValueObject *valobj = NULL;
    if (m_reg_ctx_sp && m_reg_set)
    {
        const uint32_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();
}

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

uint32_t
ValueObjectRegister::CalculateNumChildren()
{
    return 0;
}

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

size_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::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);
}


