//===-- ValueObjectConstResult.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/ValueObjectConstResult.h"

#include "lldb/Core/ValueObjectDynamicValue.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Scalar.h"

namespace lldb_private {
class Module;
}

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) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, byte_order,
                                     addr_byte_size, address))
      ->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
                                               ValueObjectManager &manager,
                                               ByteOrder byte_order,
                                               uint32_t addr_byte_size,
                                               lldb::addr_t address)
    : ValueObject(exe_scope, manager), 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 CompilerType &compiler_type,
                                             ConstString name,
                                             const DataExtractor &data,
                                             lldb::addr_t address) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,
                                     name, data, address))
      ->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult(
    ExecutionContextScope *exe_scope, ValueObjectManager &manager,
    const CompilerType &compiler_type, ConstString name,
    const DataExtractor &data, lldb::addr_t address)
    : ValueObject(exe_scope, manager), 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::ValueType::HostAddress);
  m_value.SetCompilerType(compiler_type);
  m_name = name;
  SetIsConstant();
  SetValueIsValid(true);
  SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
                                             const CompilerType &compiler_type,
                                             ConstString name,
                                             const lldb::DataBufferSP &data_sp,
                                             lldb::ByteOrder data_byte_order,
                                             uint32_t data_addr_size,
                                             lldb::addr_t address) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,
                                     name, data_sp, data_byte_order,
                                     data_addr_size, address))
      ->GetSP();
}

ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
                                             Value &value,
                                             ConstString name,
                                             Module *module) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, value, name,
                                     module))
      ->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult(
    ExecutionContextScope *exe_scope, ValueObjectManager &manager,
    const CompilerType &compiler_type, ConstString name,
    const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order,
    uint32_t data_addr_size, lldb::addr_t address)
    : ValueObject(exe_scope, manager), 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::ValueType::HostAddress);
  m_value.SetCompilerType(compiler_type);
  m_name = name;
  SetIsConstant();
  SetValueIsValid(true);
  SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
                                             const CompilerType &compiler_type,
                                             ConstString name,
                                             lldb::addr_t address,
                                             AddressType address_type,
                                             uint32_t addr_byte_size) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,
                                     name, address, address_type,
                                     addr_byte_size))
      ->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult(
    ExecutionContextScope *exe_scope, ValueObjectManager &manager,
    const CompilerType &compiler_type, ConstString name, lldb::addr_t address,
    AddressType address_type, uint32_t addr_byte_size)
    : ValueObject(exe_scope, manager), m_type_name(),
      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::ValueType::HostAddress);
  switch (address_type) {
  case eAddressTypeInvalid:
    m_value.SetValueType(Value::ValueType::Scalar);
    break;
  case eAddressTypeFile:
    m_value.SetValueType(Value::ValueType::FileAddress);
    break;
  case eAddressTypeLoad:
    m_value.SetValueType(Value::ValueType::LoadAddress);
    break;
  case eAddressTypeHost:
    m_value.SetValueType(Value::ValueType::HostAddress);
    break;
  }
  m_value.SetCompilerType(compiler_type);
  m_name = name;
  SetIsConstant();
  SetValueIsValid(true);
  SetAddressTypeOfChildren(eAddressTypeLoad);
}

ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
                                             const Status &error) {
  auto manager_sp = ValueObjectManager::Create();
  return (new ValueObjectConstResult(exe_scope, *manager_sp, error))->GetSP();
}

ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
                                               ValueObjectManager &manager,
                                               const Status &error)
    : ValueObject(exe_scope, manager), m_impl(this) {
  m_error = error;
  SetIsConstant();
}

ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
                                               ValueObjectManager &manager,
                                               const Value &value,
                                               ConstString name, Module *module)
    : ValueObject(exe_scope, manager), 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, module);
}

ValueObjectConstResult::~ValueObjectConstResult() {}

CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {
  return m_value.GetCompilerType();
}

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

llvm::Optional<uint64_t> ValueObjectConstResult::GetByteSize() {
  ExecutionContext exe_ctx(GetExecutionContextRef());
  if (!m_byte_size) {
    if (auto size =
        GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()))
      SetByteSize(*size);
  }
  return m_byte_size;
}

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

size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) {
  ExecutionContext exe_ctx(GetExecutionContextRef());
  auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
  return children_count <= max ? children_count : max;
}

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

ConstString ValueObjectConstResult::GetDisplayTypeName() {
  return GetCompilerType().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(Status &error) {
  return m_impl.Dereference(error);
}

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

lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Status &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::ValueObjectSP
ValueObjectConstResult::Cast(const CompilerType &compiler_type) {
  return m_impl.Cast(compiler_type);
}

lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage() {
  if (m_preferred_display_language != lldb::eLanguageTypeUnknown)
    return m_preferred_display_language;
  return GetCompilerTypeImpl().GetMinimumLanguage();
}
