//===-- 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,
                                Module *module)
{
    return (new ValueObjectConstResult (exe_scope, value, name, module))->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,
                                                Module *module) :
    ValueObject (exe_scope),
    m_type_name (),
    m_byte_size (0),
    m_impl(this)
{
    m_value = value;
    m_name = name;
    ExecutionContext exe_ctx;
    exe_scope->CalculateExecutionContext(exe_ctx);
    m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module);
}

ValueObjectConstResult::~ValueObjectConstResult()
{
}

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

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

uint64_t
ValueObjectConstResult::GetByteSize()
{
    ExecutionContext exe_ctx(GetExecutionContextRef());

    if (m_byte_size == 0)
        SetByteSize(GetClangType().GetByteSize(exe_ctx.GetBestExecutionContextScope()));
    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();
}

lldb::LanguageType
ValueObjectConstResult::GetPreferredDisplayLanguage ()
{
    return lldb::eLanguageTypeUnknown;
}
