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

#include "lldb/Core/ValueObjectChild.h"
#include "lldb/Core/ValueObjectConstResultChild.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObjectDynamicValue.h"
#include "lldb/Core/ValueObjectList.h"

#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"

#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

ValueObjectSP
ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
                                ByteOrder byte_order,
                                uint32_t addr_byte_size,
                                lldb::addr_t address)
{
    return (new ValueObjectConstResult (exe_scope,
                                        byte_order,
                                        addr_byte_size,
                                        address))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                ByteOrder byte_order,
                                                uint32_t addr_byte_size,
                                                lldb::addr_t address) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this, address)
{
    SetIsConstant ();
    SetValueIsValid(true);
    m_data.SetByteOrder(byte_order);
    m_data.SetAddressByteSize(addr_byte_size);
    SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP
ValueObjectConstResult::Create
(
    ExecutionContextScope *exe_scope,
    const ClangASTType &clang_type,
    const ConstString &name,
    const DataExtractor &data,
    lldb::addr_t address
)
{
    return (new ValueObjectConstResult (exe_scope,
                                        clang_type,
                                        name,
                                        data,
                                        address))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                const ClangASTType &clang_type,
                                                const ConstString &name,
                                                const DataExtractor &data,
                                                lldb::addr_t address) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this, address)
{
    m_data = data;
    
    if (!m_data.GetSharedDataBuffer())
    {
        DataBufferSP shared_data_buffer(new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
        m_data.SetData(shared_data_buffer);
    }
    
    m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
    m_value.SetValueType(Value::eValueTypeHostAddress);
    m_value.SetClangType(clang_type);
    m_name = name;
    SetIsConstant ();
    SetValueIsValid(true);
    SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP
ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
                                const ClangASTType &clang_type,
                                const ConstString &name,
                                const lldb::DataBufferSP &data_sp,
                                lldb::ByteOrder data_byte_order,
                                uint32_t data_addr_size,
                                lldb::addr_t address)
{
    return (new ValueObjectConstResult (exe_scope,
                                        clang_type,
                                        name,
                                        data_sp,
                                        data_byte_order,
                                        data_addr_size,
                                        address))->GetSP();
}

ValueObjectSP
ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
                                Value &value,
                                const ConstString &name)
{
    return (new ValueObjectConstResult (exe_scope, value, name))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                const ClangASTType &clang_type,
                                                const ConstString &name,
                                                const lldb::DataBufferSP &data_sp,
                                                lldb::ByteOrder data_byte_order, 
                                                uint32_t data_addr_size,
                                                lldb::addr_t address) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this, address)
{
    m_data.SetByteOrder(data_byte_order);
    m_data.SetAddressByteSize(data_addr_size);
    m_data.SetData(data_sp);
    m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
    m_value.SetValueType(Value::eValueTypeHostAddress);
    //m_value.SetContext(Value::eContextTypeClangType, clang_type);
    m_value.SetClangType (clang_type);
    m_name = name;
    SetIsConstant ();
    SetValueIsValid(true);
    SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP
ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
                                const ClangASTType &clang_type,
                                const ConstString &name,
                                lldb::addr_t address,
                                AddressType address_type,
                                uint32_t addr_byte_size)
{
    return (new ValueObjectConstResult (exe_scope,
                                        clang_type,
                                        name,
                                        address,
                                        address_type,
                                        addr_byte_size))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                const ClangASTType &clang_type,
                                                const ConstString &name,
                                                lldb::addr_t address,
                                                AddressType address_type,
                                                uint32_t addr_byte_size) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this, address)
{
    m_value.GetScalar() = address;
    m_data.SetAddressByteSize(addr_byte_size);
    m_value.GetScalar().GetData (m_data, addr_byte_size);
    //m_value.SetValueType(Value::eValueTypeHostAddress); 
    switch (address_type)
    {
    case eAddressTypeInvalid:   m_value.SetValueType(Value::eValueTypeScalar);      break;
    case eAddressTypeFile:      m_value.SetValueType(Value::eValueTypeFileAddress); break;
    case eAddressTypeLoad:      m_value.SetValueType(Value::eValueTypeLoadAddress); break;    
    case eAddressTypeHost:      m_value.SetValueType(Value::eValueTypeHostAddress); break;
    }
//    m_value.SetContext(Value::eContextTypeClangType, clang_type);
    m_value.SetClangType (clang_type);
    m_name = name;
    SetIsConstant ();
    SetValueIsValid(true);
    SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP
ValueObjectConstResult::Create
(
    ExecutionContextScope *exe_scope,
    const Error& error
)
{
    return (new ValueObjectConstResult (exe_scope,
                                        error))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                const Error& error) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this)
{
    m_error = error;
    SetIsConstant ();
}

ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
                                                const Value &value,
                                                const ConstString &name) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this)
{
    m_value = value;
    m_value.GetData(m_data);
}

ValueObjectConstResult::~ValueObjectConstResult()
{
}

ClangASTType
ValueObjectConstResult::GetClangTypeImpl()
{
    return m_value.GetClangType();
}

lldb::ValueType
ValueObjectConstResult::GetValueType() const
{
    return eValueTypeConstResult;
}

uint64_t
ValueObjectConstResult::GetByteSize()
{
    if (m_byte_size == 0)
        m_byte_size = GetClangType().GetByteSize();
    return m_byte_size;
}

void
ValueObjectConstResult::SetByteSize (size_t size)
{
    m_byte_size = size;
}

size_t
ValueObjectConstResult::CalculateNumChildren()
{
    return GetClangType().GetNumChildren (true);
}

ConstString
ValueObjectConstResult::GetTypeName()
{
    if (m_type_name.IsEmpty())
        m_type_name = GetClangType().GetConstTypeName ();
    return m_type_name;
}

ConstString
ValueObjectConstResult::GetDisplayTypeName()
{
    return GetClangType().GetDisplayTypeName();
}

bool
ValueObjectConstResult::UpdateValue ()
{
    // Const value is always valid
    SetValueIsValid (true);
    return true;
}


bool
ValueObjectConstResult::IsInScope ()
{
    // A const result value is always in scope since it serializes all 
    // information needed to contain the constant value.
    return true;
}

lldb::ValueObjectSP
ValueObjectConstResult::Dereference (Error &error)
{
    return m_impl.Dereference(error);
}

lldb::ValueObjectSP
ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
{
    return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
}

lldb::ValueObjectSP
ValueObjectConstResult::AddressOf (Error &error)
{
    return m_impl.AddressOf(error);
}

lldb::addr_t
ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address,
                                      AddressType *address_type)
{
    return m_impl.GetAddressOf(scalar_is_load_address, address_type);
}

ValueObject *
ValueObjectConstResult::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
    return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
}

size_t
ValueObjectConstResult::GetPointeeData (DataExtractor& data,
                                        uint32_t item_idx,
                                        uint32_t item_count)
{
    return m_impl.GetPointeeData(data, item_idx, item_count);
}

lldb::ValueObjectSP
ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic)
{
    // Always recalculate dynamic values for const results as the memory that
    // they might point to might have changed at any time.
    if (use_dynamic != eNoDynamicValues)
    {
        if (!IsDynamic())
        {
            ExecutionContext exe_ctx (GetExecutionContextRef());
            Process *process = exe_ctx.GetProcessPtr();
            if (process && process->IsPossibleDynamicValue(*this))
                m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
        }
        if (m_dynamic_value)
            return m_dynamic_value->GetSP();
    }
    return ValueObjectSP();
}

