//===-- ValueObjectDynamicValue.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/ValueObjectDynamicValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"

#include <cstring>
#include <optional>
namespace lldb_private {
class Declaration;
}

using namespace lldb_private;

ValueObjectDynamicValue::ValueObjectDynamicValue(
    ValueObject &parent, lldb::DynamicValueType use_dynamic)
    : ValueObject(parent), m_address(), m_dynamic_type_info(),
      m_use_dynamic(use_dynamic) {
  SetName(parent.GetName());
}

CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasType())
      return m_value.GetCompilerType();
    else
      return m_parent->GetCompilerType();
  }
  return m_parent->GetCompilerType();
}

ConstString ValueObjectDynamicValue::GetTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetTypeName();
}

TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_type_impl.IsValid()) {
    return m_type_impl;
  }
  return m_parent->GetTypeImpl();
}

ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetQualifiedTypeName();
}

ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasType())
      return GetCompilerType().GetDisplayTypeName();
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetDisplayTypeName();
}

size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_dynamic_type_info.HasType()) {
    ExecutionContext exe_ctx(GetExecutionContextRef());
    auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
    return children_count <= max ? children_count : max;
  } else
    return m_parent->GetNumChildren(max);
}

std::optional<uint64_t> ValueObjectDynamicValue::GetByteSize() {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_dynamic_type_info.HasType()) {
    ExecutionContext exe_ctx(GetExecutionContextRef());
    return m_value.GetValueByteSize(nullptr, &exe_ctx);
  } else
    return m_parent->GetByteSize();
}

lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
  return m_parent->GetValueType();
}

bool ValueObjectDynamicValue::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  if (!m_parent->UpdateValueIfNeeded(false)) {
    // The dynamic value failed to get an error, pass the error along
    if (m_error.Success() && m_parent->GetError().Fail())
      m_error = m_parent->GetError();
    return false;
  }

  // Setting our type_sp to NULL will route everything back through our parent
  // which is equivalent to not using dynamic values.
  if (m_use_dynamic == lldb::eNoDynamicValues) {
    m_dynamic_type_info.Clear();
    return true;
  }

  ExecutionContext exe_ctx(GetExecutionContextRef());
  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
    m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
  }

  // First make sure our Type and/or Address haven't changed:
  Process *process = exe_ctx.GetProcessPtr();
  if (!process)
    return false;

  TypeAndOrName class_type_or_name;
  Address dynamic_address;
  bool found_dynamic_type = false;
  Value::ValueType value_type;

  LanguageRuntime *runtime = nullptr;

  lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
  if (known_type != lldb::eLanguageTypeUnknown &&
      known_type != lldb::eLanguageTypeC) {
    runtime = process->GetLanguageRuntime(known_type);
    if (auto *preferred_runtime =
            runtime->GetPreferredLanguageRuntime(*m_parent)) {
      // Try the preferred runtime first.
      found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);
      if (found_dynamic_type)
        // Set the operative `runtime` for later use in this function.
        runtime = preferred_runtime;
    }
    if (!found_dynamic_type)
      // Fallback to the runtime for `known_type`.
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);
  } else {
    runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
    if (runtime)
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);

    if (!found_dynamic_type) {
      runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
      if (runtime)
        found_dynamic_type = runtime->GetDynamicTypeAndAddress(
            *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
            value_type);
    }
  }

  // Getting the dynamic value may have run the program a bit, and so marked us
  // as needing updating, but we really don't...

  m_update_point.SetUpdated();

  if (runtime && found_dynamic_type) {
    if (class_type_or_name.HasType()) {
      m_type_impl =
          TypeImpl(m_parent->GetCompilerType(),
                   runtime->FixUpDynamicType(class_type_or_name, *m_parent)
                       .GetCompilerType());
    } else {
      m_type_impl.Clear();
    }
  } else {
    m_type_impl.Clear();
  }

  // If we don't have a dynamic type, set ourselves to be invalid and return
  // false.  We used to try to produce a dynamic ValueObject that behaved "like"
  // its parent, but that failed for ValueObjectConstResult, which is too 
  // complex a beast to try to emulate.  If we return an invalid ValueObject,
  // clients will end up getting the static value instead, which behaves
  // correctly.
  if (!found_dynamic_type) {
    if (m_dynamic_type_info)
      SetValueDidChange(true);
    ClearDynamicTypeInformation();
    m_dynamic_type_info.Clear();
    m_error.SetErrorString("no dynamic type found");
    return false;
  }

  Value old_value(m_value);

  Log *log = GetLog(LLDBLog::Types);

  bool has_changed_type = false;

  if (!m_dynamic_type_info) {
    m_dynamic_type_info = class_type_or_name;
    has_changed_type = true;
  } else if (class_type_or_name != m_dynamic_type_info) {
    // We are another type, we need to tear down our children...
    m_dynamic_type_info = class_type_or_name;
    SetValueDidChange(true);
    has_changed_type = true;
  }

  if (has_changed_type)
    ClearDynamicTypeInformation();

  if (!m_address.IsValid() || m_address != dynamic_address) {
    if (m_address.IsValid())
      SetValueDidChange(true);

    // We've moved, so we should be fine...
    m_address = dynamic_address;
    lldb::TargetSP target_sp(GetTargetSP());
    lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
    m_value.GetScalar() = load_address;
  }

  if (runtime)
    m_dynamic_type_info =
        runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);

  m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());

  m_value.SetValueType(value_type);

  if (has_changed_type && log)
    LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(),
              static_cast<void *>(this), GetTypeName().GetCString());

  if (m_address.IsValid() && m_dynamic_type_info) {
    // The variable value is in the Scalar value inside the m_value. We can
    // point our m_data right to it.
    m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
    if (m_error.Success()) {
      if (!CanProvideValue()) {
        // this value object represents an aggregate type whose children have
        // values, but this object does not. So we say we are changed if our
        // location has changed.
        SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
                          m_value.GetScalar() != old_value.GetScalar());
      }

      SetValueIsValid(true);
      return true;
    }
  }

  // We get here if we've failed above...
  SetValueIsValid(false);
  return false;
}

bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }

bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
                                                  Status &error) {
  if (!UpdateValueIfNeeded(false)) {
    error.SetErrorString("unable to read value");
    return false;
  }

  uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
  uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

  if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
    error.SetErrorString("unable to read value");
    return false;
  }

  // if we are at an offset from our parent, in order to set ourselves
  // correctly we would need to change the new value so that it refers to the
  // correct dynamic type. we choose not to deal with that - if anything more
  // than a value overwrite is required, you should be using the expression
  // parser instead of the value editing facility
  if (my_value != parent_value) {
    // but NULL'ing out a value should always be allowed
    if (strcmp(value_str, "0")) {
      error.SetErrorString(
          "unable to modify dynamic value, use 'expression' command");
      return false;
    }
  }

  bool ret_val = m_parent->SetValueFromCString(value_str, error);
  SetNeedsUpdate();
  return ret_val;
}

bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
  if (!UpdateValueIfNeeded(false)) {
    error.SetErrorString("unable to read value");
    return false;
  }

  uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
  uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

  if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
    error.SetErrorString("unable to read value");
    return false;
  }

  // if we are at an offset from our parent, in order to set ourselves
  // correctly we would need to change the new value so that it refers to the
  // correct dynamic type. we choose not to deal with that - if anything more
  // than a value overwrite is required, you should be using the expression
  // parser instead of the value editing facility
  if (my_value != parent_value) {
    // but NULL'ing out a value should always be allowed
    lldb::offset_t offset = 0;

    if (data.GetAddress(&offset) != 0) {
      error.SetErrorString(
          "unable to modify dynamic value, use 'expression' command");
      return false;
    }
  }

  bool ret_val = m_parent->SetData(data, error);
  SetNeedsUpdate();
  return ret_val;
}

void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
    lldb::LanguageType lang) {
  this->ValueObject::SetPreferredDisplayLanguage(lang);
  if (m_parent)
    m_parent->SetPreferredDisplayLanguage(lang);
}

lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
  if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
    if (m_parent)
      return m_parent->GetPreferredDisplayLanguage();
    return lldb::eLanguageTypeUnknown;
  } else
    return m_preferred_display_language;
}

bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
  if (m_parent)
    return m_parent->IsSyntheticChildrenGenerated();
  return false;
}

void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
  if (m_parent)
    m_parent->SetSyntheticChildrenGenerated(b);
  this->ValueObject::SetSyntheticChildrenGenerated(b);
}

bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
  if (m_parent)
    return m_parent->GetDeclaration(decl);

  return ValueObject::GetDeclaration(decl);
}

uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
  if (m_parent)
    return m_parent->GetLanguageFlags();
  return this->ValueObject::GetLanguageFlags();
}

void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
  if (m_parent)
    m_parent->SetLanguageFlags(flags);
  else
    this->ValueObject::SetLanguageFlags(flags);
}
