//===-- DILEval.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/ValueObject/DILEval.h"
#include "lldb/Core/Module.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
#include "llvm/Support/ErrorExtras.h"
#include "llvm/Support/FormatAdapters.h"
#include <memory>

namespace lldb_private::dil {

static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
                                 lldb::BasicType basic_type) {
  if (type_system)
    return type_system.get()->GetBasicTypeFromAST(basic_type);

  return CompilerType();
}

static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj,
                                                    ExecutionContextScope &ctx,
                                                    llvm::StringRef name) {
  uint64_t addr = valobj.GetLoadAddress();
  ExecutionContext exe_ctx;
  ctx.CalculateExecutionContext(exe_ctx);
  return ValueObject::CreateValueObjectFromAddress(
      name, addr, exe_ctx,
      valobj.GetCompilerType().GetArrayElementType(&ctx).GetPointerType(),
      /* do_deref */ false);
}

static llvm::Expected<lldb::LanguageType>
GetSourceLanguageFromCU(StackFrame &ctx) {
  SymbolContext symbol_context =
      ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
  if (!symbol_context.comp_unit)
    return llvm::createStringErrorV("no compile unit for frame: {}",
                                    ctx.GetFunctionName());

  return symbol_context.comp_unit->GetLanguage();
}

static llvm::Expected<lldb::TypeSystemSP> GetTypeSystemFromCU(StackFrame &ctx) {
  SymbolContext symbol_context =
      ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
  if (!symbol_context.comp_unit)
    return llvm::createStringErrorV("no compile unit for frame: {}",
                                    ctx.GetFunctionName());

  lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
  symbol_context = ctx.GetSymbolContext(lldb::eSymbolContextModule);
  return symbol_context.module_sp->GetTypeSystemForLanguage(language);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location) {
  if (!valobj)
    return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
                                                location);
  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();

  CompilerType in_type = valobj->GetCompilerType();
  if (valobj->IsBitfield()) {
    // Promote bitfields. If `int` can represent the bitfield value, it is
    // converted to `int`. Otherwise, if `unsigned int` can represent it, it
    // is converted to `unsigned int`. Otherwise, it is treated as its
    // underlying type.
    uint32_t bitfield_size = valobj->GetBitfieldBitSize();
    // Some bitfields have undefined size (e.g. result of ternary operation).
    // The AST's `bitfield_size` of those is 0, and no promotion takes place.
    if (bitfield_size > 0 && in_type.IsInteger()) {
      CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
      CompilerType uint_type =
          GetBasicType(*type_system, lldb::eBasicTypeUnsignedInt);
      llvm::Expected<uint64_t> int_bit_size =
          int_type.GetBitSize(&m_stack_frame);
      if (!int_bit_size)
        return int_bit_size.takeError();
      llvm::Expected<uint64_t> uint_bit_size =
          uint_type.GetBitSize(&m_stack_frame);
      if (!uint_bit_size)
        return uint_bit_size.takeError();
      if (bitfield_size < *int_bit_size ||
          (in_type.IsSigned() && bitfield_size == *int_bit_size)) {
        auto result = valobj->CastToBasicType(int_type);
        if (result->GetError().Fail())
          return llvm::make_error<DILDiagnosticError>(
              m_expr, result->GetError().AsCString(), location);
        return result;
      }
      if (bitfield_size <= *uint_bit_size) {
        auto result = valobj->CastToBasicType(uint_type);
        if (result->GetError().Fail())
          return llvm::make_error<DILDiagnosticError>(
              m_expr, result->GetError().AsCString(), location);
        return result;
      }
      // Re-create as a const value with the same underlying type
      Scalar scalar;
      bool resolved = valobj->ResolveValue(scalar);
      if (!resolved)
        return llvm::createStringError("invalid scalar value");
      return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
                                                      in_type, "result");
    }
  }

  if (in_type.IsArrayType())
    valobj = ArrayToPointerConversion(*valobj, m_stack_frame, "result");

  CompilerType promoted_type =
      valobj->GetCompilerType().GetPromotedIntegerType();
  if (promoted_type) {
    auto result = valobj->CastToBasicType(promoted_type);
    if (result->GetError().Fail())
      return llvm::make_error<DILDiagnosticError>(
          m_expr, result->GetError().AsCString(), location);
    return result;
  }

  return valobj;
}

/// Basic types with a lower rank are converted to the basic type
/// with a higher rank.
static size_t ConversionRank(CompilerType type) {
  switch (type.GetCanonicalType().GetBasicTypeEnumeration()) {
  case lldb::eBasicTypeBool:
    return 1;
  case lldb::eBasicTypeChar:
  case lldb::eBasicTypeSignedChar:
  case lldb::eBasicTypeUnsignedChar:
    return 2;
  case lldb::eBasicTypeShort:
  case lldb::eBasicTypeUnsignedShort:
    return 3;
  case lldb::eBasicTypeInt:
  case lldb::eBasicTypeUnsignedInt:
    return 4;
  case lldb::eBasicTypeLong:
  case lldb::eBasicTypeUnsignedLong:
    return 5;
  case lldb::eBasicTypeLongLong:
  case lldb::eBasicTypeUnsignedLongLong:
    return 6;
  case lldb::eBasicTypeInt128:
  case lldb::eBasicTypeUnsignedInt128:
    return 7;
  case lldb::eBasicTypeHalf:
    return 8;
  case lldb::eBasicTypeFloat:
    return 9;
  case lldb::eBasicTypeDouble:
    return 10;
  case lldb::eBasicTypeLongDouble:
    return 11;
  default:
    break;
  }
  return 0;
}

static lldb::BasicType BasicTypeToUnsigned(lldb::BasicType basic_type) {
  switch (basic_type) {
  case lldb::eBasicTypeChar:
  case lldb::eBasicTypeSignedChar:
    return lldb::eBasicTypeUnsignedChar;
  case lldb::eBasicTypeShort:
    return lldb::eBasicTypeUnsignedShort;
  case lldb::eBasicTypeInt:
    return lldb::eBasicTypeUnsignedInt;
  case lldb::eBasicTypeLong:
    return lldb::eBasicTypeUnsignedLong;
  case lldb::eBasicTypeLongLong:
    return lldb::eBasicTypeUnsignedLongLong;
  case lldb::eBasicTypeInt128:
    return lldb::eBasicTypeUnsignedInt128;
  default:
    return basic_type;
  }
}

llvm::Expected<CompilerType>
Interpreter::PromoteSignedInteger(CompilerType &lhs_type,
                                  CompilerType &rhs_type) {
  assert(lhs_type.IsInteger() && rhs_type.IsInteger());
  if (!lhs_type.IsSigned() && rhs_type.IsSigned()) {
    llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
    if (!lhs_size)
      return lhs_size.takeError();
    llvm::Expected<uint64_t> rhs_size = rhs_type.GetBitSize(&m_stack_frame);
    if (!rhs_size)
      return rhs_size.takeError();

    if (*rhs_size == *lhs_size) {
      llvm::Expected<lldb::TypeSystemSP> type_system =
          GetTypeSystemFromCU(m_stack_frame);
      if (!type_system)
        return type_system.takeError();
      CompilerType r_type_unsigned = GetBasicType(
          *type_system,
          BasicTypeToUnsigned(
              rhs_type.GetCanonicalType().GetBasicTypeEnumeration()));
      return r_type_unsigned;
    }
  }
  return rhs_type;
}

llvm::Expected<CompilerType>
Interpreter::ArithmeticConversion(lldb::ValueObjectSP &lhs,
                                  lldb::ValueObjectSP &rhs, uint32_t location) {
  // Apply unary conversion for both operands.
  auto lhs_or_err = UnaryConversion(lhs, location);
  if (!lhs_or_err)
    return lhs_or_err.takeError();
  lhs = *lhs_or_err;
  auto rhs_or_err = UnaryConversion(rhs, location);
  if (!rhs_or_err)
    return rhs_or_err.takeError();
  rhs = *rhs_or_err;

  CompilerType lhs_type = lhs->GetCompilerType();
  CompilerType rhs_type = rhs->GetCompilerType();

  // If types already match, no need for further conversions.
  if (lhs_type.CompareTypes(rhs_type))
    return lhs_type;

  // If either of the operands is not arithmetic (e.g. pointer), we're done.
  if (!lhs_type.IsScalarType() || !rhs_type.IsScalarType())
    return CompilerType();

  size_t l_rank = ConversionRank(lhs_type);
  size_t r_rank = ConversionRank(rhs_type);
  if (l_rank == 0 || r_rank == 0)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "unexpected basic type in arithmetic operation", location);

  // If both operands are integer, check if we need to promote
  // the higher ranked signed type.
  if (lhs_type.IsInteger() && rhs_type.IsInteger()) {
    using Rank = std::tuple<size_t, bool>;
    Rank int_l_rank = {l_rank, !lhs_type.IsSigned()};
    Rank int_r_rank = {r_rank, !rhs_type.IsSigned()};
    if (int_l_rank < int_r_rank) {
      auto type_or_err = PromoteSignedInteger(lhs_type, rhs_type);
      if (!type_or_err)
        return type_or_err.takeError();
      return *type_or_err;
    }
    if (int_l_rank > int_r_rank) {
      auto type_or_err = PromoteSignedInteger(rhs_type, lhs_type);
      if (!type_or_err)
        return type_or_err.takeError();
      return *type_or_err;
    }
    return lhs_type;
  }

  // Handle other combinations of integer and floating point operands.
  if (l_rank < r_rank)
    return rhs_type;
  return lhs_type;
}

static lldb::VariableSP DILFindVariable(ConstString name,
                                        VariableList &variable_list) {
  lldb::VariableSP exact_match;
  std::vector<lldb::VariableSP> possible_matches;

  for (lldb::VariableSP var_sp : variable_list) {
    llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();

    str_ref_name.consume_front("::");
    // Check for the exact same match
    if (str_ref_name == name.GetStringRef())
      return var_sp;

    // Check for possible matches by base name
    if (var_sp->NameMatches(name))
      possible_matches.push_back(var_sp);
  }

  // If there's a non-exact match, take it.
  if (possible_matches.size() > 0)
    return possible_matches[0];

  return nullptr;
}

lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
                                           StackFrame &stack_frame,
                                           lldb::TargetSP target_sp,
                                           lldb::DynamicValueType use_dynamic) {
  // Get a global variables list without the locals from the current frame
  SymbolContext symbol_context =
      stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit);
  lldb::VariableListSP variable_list;
  if (symbol_context.comp_unit)
    variable_list = symbol_context.comp_unit->GetVariableList(true);

  name_ref.consume_front("::");
  lldb::ValueObjectSP value_sp;
  if (variable_list) {
    lldb::VariableSP var_sp =
        DILFindVariable(ConstString(name_ref), *variable_list);
    if (var_sp)
      value_sp =
          stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
  }

  if (value_sp)
    return value_sp;

  // Check for match in modules global variables.
  VariableList modules_var_list;
  target_sp->GetImages().FindGlobalVariables(
      ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
      modules_var_list);

  if (!modules_var_list.Empty()) {
    lldb::VariableSP var_sp =
        DILFindVariable(ConstString(name_ref), modules_var_list);
    if (var_sp)
      value_sp = ValueObjectVariable::Create(&stack_frame, var_sp);

    if (value_sp)
      return value_sp;
  }
  return nullptr;
}

lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref,
                                               StackFrame &stack_frame,
                                               lldb::TargetSP target_sp,
                                               lldb::LanguageType language) {
  if (name_ref.starts_with("$")) {
    if (auto *state =
            target_sp->GetPersistentExpressionStateForLanguage(language))
      if (auto var_sp = state->GetVariable(name_ref))
        if (auto valobj_sp = var_sp->GetValueObject())
          return valobj_sp;
  }
  return nullptr;
}

lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
                                     StackFrame &stack_frame,
                                     lldb::DynamicValueType use_dynamic) {
  // Support $rax as a special syntax for accessing registers.
  // Will return an invalid value in case the requested register doesn't exist.
  if (name_ref.consume_front("$")) {
    lldb::RegisterContextSP reg_ctx(stack_frame.GetRegisterContext());
    if (!reg_ctx)
      return nullptr;

    if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
      return ValueObjectRegister::Create(&stack_frame, reg_ctx, reg_info);

    return nullptr;
  }

  if (!name_ref.contains("::")) {
    // Lookup in the current frame.
    // Try looking for a local variable in current scope.
    lldb::VariableListSP variable_list(
        stack_frame.GetInScopeVariableList(false));

    lldb::ValueObjectSP value_sp;
    if (variable_list) {
      lldb::VariableSP var_sp =
          variable_list->FindVariable(ConstString(name_ref));
      if (var_sp)
        value_sp =
            stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
    }

    if (value_sp)
      return value_sp;

    // Try looking for an instance variable (class member).
    SymbolContext sc = stack_frame.GetSymbolContext(
        lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
    llvm::StringRef instance_name = sc.GetInstanceName();
    value_sp = stack_frame.FindVariable(ConstString(instance_name));
    if (value_sp)
      value_sp = value_sp->GetChildMemberWithName(name_ref);

    if (value_sp)
      return value_sp;
  }
  return nullptr;
}

lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
                                    ExecutionContextScope &ctx_scope) {
  if (name_ref.contains("::")) {
    llvm::StringRef enum_typename, enumerator_name;
    // FIXME: Change this to a structured binding for lambda capturing
    // once we have C++20.
    std::tie(enum_typename, enumerator_name) = name_ref.rsplit("::");
    CompilerType enum_type = ResolveTypeByName(enum_typename.str(), ctx_scope);
    lldb::ValueObjectSP result;
    enum_type.ForEachEnumerator([&](const CompilerType &integer_type,
                                    ConstString name,
                                    const llvm::APSInt &value) -> bool {
      if (name == enumerator_name) {
        Scalar scalar(value);
        result = ValueObject::CreateValueObjectFromScalar(ctx_scope, scalar,
                                                          enum_type, "result");
        return false; // Stop iterating
      }
      return true;
    });
    return result;
  }
  return nullptr;
}

Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
                         StackFrame &stack_frame,
                         lldb::DynamicValueType use_dynamic, uint32_t options)
    : m_target(std::move(target)), m_expr(expr), m_stack_frame(stack_frame),
      m_use_dynamic(use_dynamic) {

  const bool check_ptr_vs_member =
      (options & StackFrame::eExpressionPathOptionCheckPtrVsMember) != 0;
  const bool no_synth_child =
      (options & StackFrame::eExpressionPathOptionsNoSyntheticChildren) != 0;
  const bool allow_var_updates =
      (options & StackFrame::eExpressionPathOptionsAllowVarUpdates) != 0;
  const bool disallow_globals =
      (options & StackFrame::eExpressionPathOptionsDisallowGlobals) != 0;

  m_use_synthetic = !no_synth_child;
  m_check_ptr_vs_member = check_ptr_vs_member;
  m_allow_var_updates = allow_var_updates;
  m_allow_globals = !disallow_globals;
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateTree(const ASTNodeUP &tree) {
  assert(tree && "ASTNodeUP must not contain a nullptr");

  auto value_or_error = Interpreter::Evaluate(*tree);
  if (!value_or_error) {
    auto error = value_or_error.takeError();
    LLDB_LOG(GetLog(LLDBLog::Expressions),
             "[Interpreter::Evaluate] DIL interpreter failed:\n{0}",
             llvm::toStringWithoutConsuming(error));
    return error;
  }

  return value_or_error;
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode &node) {
  // Evaluate an AST.
  auto value_or_error = node.Accept(this);
  // Convert SP with a nullptr to an error.
  if (value_or_error && !*value_or_error)
    return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
                                                node.GetLocation());
  // Return the computed value-or-error. The caller is responsible for
  // checking if an error occurred during the evaluation.
  return value_or_error;
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateAndDereference(const ASTNode &node) {
  auto valobj_or_err = Evaluate(node);
  if (!valobj_or_err)
    return valobj_or_err;
  lldb::ValueObjectSP valobj = *valobj_or_err;

  Status error;
  if (valobj->GetCompilerType().IsReferenceType()) {
    valobj = valobj->Dereference(error);
    if (error.Fail())
      return error.ToError();
  }
  return valobj;
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const IdentifierNode &node) {
  lldb::DynamicValueType use_dynamic = m_use_dynamic;

  lldb::ValueObjectSP identifier =
      LookupIdentifier(node.GetName(), m_stack_frame, use_dynamic);

  if (!identifier && m_allow_globals)
    identifier = LookupGlobalIdentifier(node.GetName(), m_stack_frame, m_target,
                                        use_dynamic);

  if (!identifier)
    identifier = LookupEnumValue(node.GetName(), m_stack_frame);

  if (!identifier && node.GetName()[0] == '$') {
    auto language = GetSourceLanguageFromCU(m_stack_frame);
    if (!language)
      return language.takeError();
    identifier = LookupPersistentIdentifier(node.GetName(), m_stack_frame,
                                            m_target, language.get());
  }

  if (!identifier && node.GetName() == "nullptr") {
    // If we got a "nullptr" identifier, and there is no defined variable with
    // this name, resolve it as a null pointer.
    llvm::Expected<lldb::TypeSystemSP> type_system =
        GetTypeSystemFromCU(m_stack_frame);
    if (!type_system)
      return type_system.takeError();
    type_system.get()->GetPointerByteSize();
    llvm::APInt value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
    Scalar scalar(value);
    CompilerType type = GetBasicType(*type_system, lldb::eBasicTypeNullPtr);
    return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
                                                    "result");
  }

  if (!identifier) {
    std::string errMsg =
        llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
    return llvm::make_error<DILDiagnosticError>(
        m_expr, errMsg, node.GetLocation(), node.GetName().size());
  }

  return identifier;
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const UnaryOpNode &node) {
  Status error;
  auto op_or_err = Evaluate(node.GetOperand());
  if (!op_or_err)
    return op_or_err;

  lldb::ValueObjectSP operand = *op_or_err;

  switch (node.GetKind()) {
  case UnaryOpKind::Deref: {
    lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
    if (dynamic_op)
      operand = dynamic_op;

    lldb::ValueObjectSP child_sp = operand->Dereference(error);
    if (!child_sp && m_use_synthetic) {
      if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
        error.Clear();
        child_sp = synth_obj_sp->Dereference(error);
      }
    }
    if (error.Fail())
      return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
                                                  node.GetLocation());

    return child_sp;
  }
  case UnaryOpKind::AddrOf: {
    Status error;
    lldb::ValueObjectSP value = operand->AddressOf(error);
    if (error.Fail())
      return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
                                                  node.GetLocation());

    return value;
  }
  case UnaryOpKind::Minus: {
    if (operand->GetCompilerType().IsReferenceType()) {
      operand = operand->Dereference(error);
      if (error.Fail())
        return error.ToError();
    }
    llvm::Expected<lldb::ValueObjectSP> conv_op =
        UnaryConversion(operand, node.GetOperand().GetLocation());
    if (!conv_op)
      return conv_op;
    operand = *conv_op;
    CompilerType operand_type = operand->GetCompilerType();
    if (!operand_type.IsScalarType()) {
      std::string errMsg =
          llvm::formatv("invalid argument type '{0}' to unary expression",
                        operand_type.GetTypeName());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                  node.GetLocation());
    }
    Scalar scalar;
    bool resolved = operand->ResolveValue(scalar);
    if (!resolved)
      break;

    bool negated = scalar.UnaryNegate();
    if (negated)
      return ValueObject::CreateValueObjectFromScalar(
          m_stack_frame, scalar, operand->GetCompilerType(), "result");
    break;
  }
  case UnaryOpKind::Plus: {
    if (operand->GetCompilerType().IsReferenceType()) {
      operand = operand->Dereference(error);
      if (error.Fail())
        return error.ToError();
    }
    llvm::Expected<lldb::ValueObjectSP> conv_op =
        UnaryConversion(operand, node.GetOperand().GetLocation());
    if (!conv_op)
      return conv_op;
    operand = *conv_op;
    CompilerType operand_type = operand->GetCompilerType();
    if (!operand_type.IsScalarType() &&
        // Unary plus is allowed for pointers.
        !operand_type.IsPointerType()) {
      std::string errMsg =
          llvm::formatv("invalid argument type '{0}' to unary expression",
                        operand_type.GetTypeName());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                  node.GetLocation());
    }
    return operand;
  }
  case UnaryOpKind::Not: {
    if (operand->GetCompilerType().IsReferenceType()) {
      operand = operand->Dereference(error);
      if (error.Fail())
        return error.ToError();
    }
    llvm::Expected<lldb::ValueObjectSP> conv_op =
        UnaryConversion(operand, node.GetLocation());
    if (!conv_op)
      return conv_op;
    operand = *conv_op;
    CompilerType operand_type = operand->GetCompilerType();
    if (!operand_type.IsInteger()) {
      std::string errMsg =
          llvm::formatv("invalid argument type '{0}' to unary expression",
                        operand_type.GetTypeName());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                  node.GetLocation());
    }
    Scalar scalar;
    bool resolved = operand->ResolveValue(scalar);
    if (!resolved) {
      std::string errMsg = llvm::formatv("invalid operand value: {0}",
                                         operand->GetError().AsCString());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                  node.GetLocation());
    }

    bool flipped = scalar.OnesComplement();
    if (flipped)
      return ValueObject::CreateValueObjectFromScalar(
          m_stack_frame, scalar, operand->GetCompilerType(), "result");
    break;
  }
  case UnaryOpKind::LNot: {
    if (operand->GetCompilerType().IsReferenceType()) {
      operand = operand->Dereference(error);
      if (error.Fail())
        return error.ToError();
    }
    CompilerType operand_type = operand->GetCompilerType();
    if (!operand_type.IsContextuallyConvertibleToBool()) {
      std::string errMsg =
          llvm::formatv("invalid argument type '{0}' to unary expression",
                        operand_type.GetTypeName());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                  node.GetLocation());
    }
    llvm::Expected<lldb::TypeSystemSP> type_system =
        GetTypeSystemFromCU(m_stack_frame);
    if (!type_system)
      return type_system.takeError();
    auto value_or_err = operand->GetValueAsBool();
    if (!value_or_err)
      return value_or_err.takeError();
    return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
                                                  !(*value_or_err), "result");
  }
  }
  return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
                                              node.GetLocation());
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::PointerOffset(lldb::ValueObjectSP ptr, lldb::ValueObjectSP offset,
                           BinaryOpKind operation, uint32_t location) {
  assert(operation == BinaryOpKind::Add || operation == BinaryOpKind::Sub);
  if (ptr->GetCompilerType().IsPointerToVoid())
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "arithmetic on a pointer to void", location);
  if (ptr->GetValueAsUnsigned(0) == 0 && offset != 0)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "arithmetic on a nullptr is undefined", location);

  bool success;
  int64_t offset_int = offset->GetValueAsSigned(0, &success);
  if (!success) {
    std::string errMsg = llvm::formatv("could not get the offset: {0}",
                                       offset->GetError().AsCString());
    return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                                location);
  }

  llvm::Expected<uint64_t> byte_size =
      ptr->GetCompilerType().GetPointeeType().GetByteSize(&m_stack_frame);
  if (!byte_size)
    return byte_size.takeError();
  uint64_t ptr_addr = ptr->GetValueAsUnsigned(0);
  if (operation == BinaryOpKind::Sub)
    ptr_addr -= offset_int * (*byte_size);
  else
    ptr_addr += offset_int * (*byte_size);

  ExecutionContext exe_ctx(m_target.get(), false);
  Scalar scalar(ptr_addr);
  return ValueObject::CreateValueObjectFromScalar(
      m_stack_frame, scalar, ptr->GetCompilerType(), "result");
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs,
                              lldb::ValueObjectSP rhs, CompilerType result_type,
                              uint32_t location) {
  Scalar l, r;
  bool l_resolved = lhs->ResolveValue(l);
  if (!l_resolved) {
    std::string errMsg =
        llvm::formatv("invalid lhs value: {0}", lhs->GetError().AsCString());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }
  bool r_resolved = rhs->ResolveValue(r);
  if (!r_resolved) {
    std::string errMsg =
        llvm::formatv("invalid rhs value: {0}", rhs->GetError().AsCString());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }

  auto value_object = [this, result_type](Scalar scalar) {
    return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
                                                    result_type, "result");
  };

  switch (kind) {
  case BinaryOpKind::Add:
    return value_object(l + r);
  case BinaryOpKind::Sub:
    return value_object(l - r);
  case BinaryOpKind::Mul:
    return value_object(l * r);
  case BinaryOpKind::Div:
    return value_object(l / r);
  case BinaryOpKind::Rem:
    return value_object(l % r);
  case BinaryOpKind::And:
    return value_object(l & r);
  case BinaryOpKind::Xor:
    return value_object(l ^ r);
  case BinaryOpKind::Or:
    return value_object(l | r);
  case BinaryOpKind::Shl:
    return value_object(l << r);
  case BinaryOpKind::Shr:
    return value_object(l >> r);
  case BinaryOpKind::LT:
    return value_object(l < r);
  case BinaryOpKind::GT:
    return value_object(l > r);
  case BinaryOpKind::LE:
    return value_object(l <= r);
  case BinaryOpKind::GE:
    return value_object(l >= r);
  case BinaryOpKind::EQ:
    return value_object(l == r);
  case BinaryOpKind::NE:
    return value_object(l != r);
  default:
    break;
  }
  return llvm::make_error<DILDiagnosticError>(
      m_expr, "invalid arithmetic operation", location);
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryAddition(
    lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
  // Operation '+' works for:
  //   {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
  //   {integer,unscoped_enum} <-> pointer
  //   pointer <-> {integer,unscoped_enum}
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (result_type.IsScalarType())
    return EvaluateScalarOp(BinaryOpKind::Add, lhs, rhs, result_type, location);

  // Check for pointer arithmetics.
  // One of the operands must be a pointer and the other one an integer.
  lldb::ValueObjectSP ptr, offset;
  if (lhs->GetCompilerType().IsPointerType()) {
    ptr = lhs;
    offset = rhs;
  } else if (rhs->GetCompilerType().IsPointerType()) {
    ptr = rhs;
    offset = lhs;
  }

  if (!ptr || !offset->GetCompilerType().IsInteger()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                                location);
  }

  return PointerOffset(ptr, offset, BinaryOpKind::Add, location);
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
    lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
  // Operation '-' works for:
  //   {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
  //   pointer <-> {integer,unscoped_enum}
  //   pointer <-> pointer (if pointee types are compatible)
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (result_type.IsScalarType())
    return EvaluateScalarOp(BinaryOpKind::Sub, lhs, rhs, result_type, location);

  auto lhs_type = lhs->GetCompilerType();
  auto rhs_type = rhs->GetCompilerType();

  // "pointer - integer" operation.
  if (lhs_type.IsPointerType() && rhs_type.IsInteger())
    return PointerOffset(lhs, rhs, BinaryOpKind::Sub, location);

  // "pointer - pointer" operation.
  if (lhs_type.IsPointerType() && rhs_type.IsPointerType()) {
    if (lhs_type.IsPointerToVoid() && rhs_type.IsPointerToVoid()) {
      return llvm::make_error<DILDiagnosticError>(
          m_expr, "arithmetic on pointers to void", location);
    }
    // Compare canonical unqualified pointer types.
    CompilerType lhs_unqualified_type = lhs_type.GetCanonicalType();
    CompilerType rhs_unqualified_type = rhs_type.GetCanonicalType();
    if (!lhs_unqualified_type.CompareTypes(rhs_unqualified_type)) {
      std::string errMsg = llvm::formatv(
          "'{0}' and '{1}' are not pointers to compatible types",
          orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
      return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
    }

    llvm::Expected<uint64_t> lhs_byte_size =
        lhs_type.GetPointeeType().GetByteSize(&m_stack_frame);
    if (!lhs_byte_size)
      return lhs_byte_size.takeError();
    // Since pointers have compatible types, both have the same pointee size.
    int64_t item_size = *lhs_byte_size;
    int64_t diff = static_cast<int64_t>(lhs->GetValueAsUnsigned(0) -
                                        rhs->GetValueAsUnsigned(0));
    assert(item_size > 0 && "Pointee size cannot be 0");
    if (diff % item_size != 0) {
      // If address difference isn't divisible by pointee size then performing
      // the operation is undefined behaviour.
      return llvm::make_error<DILDiagnosticError>(
          m_expr, "undefined pointer arithmetic", location);
    }
    diff /= item_size;

    llvm::Expected<lldb::TypeSystemSP> type_system =
        GetTypeSystemFromCU(m_stack_frame);
    if (!type_system)
      return type_system.takeError();
    CompilerType ptrdiff_type = type_system.get()->GetPointerDiffType(true);
    if (!ptrdiff_type)
      return llvm::make_error<DILDiagnosticError>(
          m_expr, "unable to determine pointer diff type", location);

    Scalar scalar(diff);
    return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
                                                    ptrdiff_type, "result");
  }

  std::string errMsg =
      llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                    orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
  return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                              location);
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryMultiplication(
    lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
  // Operation '*' works for:
  //  {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (!result_type.IsScalarType()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                                location);
  }

  return EvaluateScalarOp(BinaryOpKind::Mul, lhs, rhs, result_type, location);
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryDivision(
    lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
  // Operation '/' works for:
  //  {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (!result_type.IsScalarType()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                                location);
  }

  // Check for zero only for integer division.
  if (result_type.IsInteger() && rhs->GetValueAsSigned(-1) == 0) {
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "division by zero is undefined", location);
  }

  return EvaluateScalarOp(BinaryOpKind::Div, lhs, rhs, result_type, location);
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryRemainder(
    lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
  // Operation '%' works for:
  //  {integer,unscoped_enum} <-> {integer,unscoped_enum}
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (!result_type.IsInteger()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                                location);
  }

  if (rhs->GetValueAsSigned(-1) == 0) {
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "division by zero is undefined", location);
  }

  return EvaluateScalarOp(BinaryOpKind::Rem, lhs, rhs, result_type, location);
}

static bool HasFloatingRepresentation(CompilerType ct) {
  return ct.GetTypeInfo() & lldb::eTypeIsFloat;
}

static llvm::Expected<bool> VerifyAssignmentTypes(CompilerType lhs_type,
                                                  CompilerType rhs_type) {
  // Make sure lhs is a legal type for DIL assignment.
  if (!lhs_type.IsInteger() && !lhs_type.IsUnscopedEnumerationType() &&
      !HasFloatingRepresentation(lhs_type) && !lhs_type.IsPointerType() &&
      !lhs_type.IsScalarType())
    return llvm::createStringError(
        "Illegal type for lhs of assignment (not scalar numeric type)");

  // Make sure rhs is a legal type for DIL assignment.
  if (!rhs_type.IsInteger() && !rhs_type.IsUnscopedEnumerationType() &&
      !HasFloatingRepresentation(rhs_type) && !rhs_type.IsPointerType())
    return llvm::createStringError(
        "Illegal type for rhs of assignment (not scalar numeric type)");

  // Only allow assigning pointers to pointers.
  if ((lhs_type.IsPointerType() && !rhs_type.IsPointerType()) ||
      (!lhs_type.IsPointerType() && rhs_type.IsPointerType()))
    return llvm::createStringError(
        "Invalid assignment: Can only assign pointers to pointers");

  // For "real numbers", the types must match exactly.
  if ((HasFloatingRepresentation(rhs_type) ||
       HasFloatingRepresentation(lhs_type)) &&
      lhs_type != rhs_type) {
    std::string err_msg =
        llvm::formatv("Incompatible types for assignment: Cannot assign {0} "
                      "to {1}",
                      rhs_type.TypeDescription(), lhs_type.TypeDescription());
    return llvm::createStringError(err_msg);
  }

  return true;
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateAssignment(lldb::ValueObjectSP lhs,
                                lldb::ValueObjectSP rhs, uint32_t location) {

  // Verify that lhs can accept an assignment.
  if (llvm::Error err = lhs->CanSetValue())
    return err;

  auto all_ok =
      VerifyAssignmentTypes(lhs->GetCompilerType(), rhs->GetCompilerType());
  if (!all_ok)
    return all_ok.takeError();

  if (llvm::Error e = lhs->SetValueFromInteger(rhs, m_allow_var_updates))
    return e;

  return lhs;
}

static bool IsLiteralZero(lldb::ValueObjectSP &val, bool is_literal) {
  bool is_zero = val->GetValueAsUnsigned(-1) == 0;
  bool is_boolean = val->GetCompilerType().IsBoolean();
  return is_zero && !is_boolean && is_literal;
}

llvm::Error
Interpreter::ValidateComparison(BinaryOpKind kind, lldb::ValueObjectSP &lhs,
                                lldb::ValueObjectSP &rhs, bool lhs_is_literal,
                                bool rhs_is_literal, uint32_t location) {
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();

  bool is_ordered = (kind == BinaryOpKind::LT || kind == BinaryOpKind::LE ||
                     kind == BinaryOpKind::GT || kind == BinaryOpKind::GE);
  bool lhs_nullptr_or_zero =
      orig_lhs_type.IsNullPtrType() || IsLiteralZero(lhs, lhs_is_literal);
  bool rhs_nullptr_or_zero =
      orig_rhs_type.IsNullPtrType() || IsLiteralZero(rhs, rhs_is_literal);

  if (orig_lhs_type.IsArrayType())
    lhs = ArrayToPointerConversion(*lhs, m_stack_frame, "result");
  if (orig_rhs_type.IsArrayType())
    rhs = ArrayToPointerConversion(*rhs, m_stack_frame, "result");

  CompilerType lhs_type = lhs->GetCompilerType();
  CompilerType rhs_type = rhs->GetCompilerType();

  if (lhs_type == rhs_type)
    return llvm::Error::success();

  lldb::ValueObjectSP lhs_child;
  lldb::ValueObjectSP rhs_child;
  bool is_signed;

  if (!lhs_nullptr_or_zero && !lhs_type.IsPointerType() &&
      !lhs_type.IsIntegerOrEnumerationType(is_signed)) {
    // lhs is not a nullptr, pointer, enum or integer. Check to see if its
    // first child could be a pointer. If so, update lhs_type accordingly.
    lhs_child = lhs->GetChildAtIndex(0);
    if (lhs_child && (lhs_child->IsPointerType() ||
                      lhs_child->GetCompilerType().IsNullPtrType()))
      lhs_type = lhs_child->GetCompilerType();
  }
  if (!rhs_nullptr_or_zero && !rhs_type.IsPointerType() &&
      !rhs_type.IsIntegerOrEnumerationType(is_signed)) {
    // rhs is not a nullptr, pointer, enum or integer. Check to see if its
    // first child could be a pointer. If so, update rhs_type accordingly.
    rhs_child = rhs->GetChildAtIndex(0);
    if (rhs_child && (rhs_child->IsPointerType() ||
                      rhs_child->GetCompilerType().IsNullPtrType()))
      rhs_type = rhs_child->GetCompilerType();
  }

  if ((lhs_type != orig_lhs_type) || (rhs_type != orig_rhs_type)) {
    if (lhs_type.IsNullPtrType() || rhs_type.IsNullPtrType())
      return llvm::Error::success();

    // May be an integer or enum.
    if (!lhs_type.IsPointerType() || !rhs_type.IsPointerType())
      return llvm::Error::success();

    CompilerType lhs_unqualified =
        lhs_type.GetCanonicalType().GetFullyUnqualifiedType();
    CompilerType rhs_unqualified =
        rhs_type.GetCanonicalType().GetFullyUnqualifiedType();

    if (lhs_unqualified.IsPointerToVoid() || rhs_unqualified.IsPointerToVoid())
      return llvm::Error::success();

    // We have two pointers, neither of which is nullptr or void *. Make
    // sure their types are compatible.
    bool comparable = lhs_unqualified.CompareTypes(rhs_unqualified);
    if (comparable)
      return llvm::Error::success();

    std::string errMsg = llvm::formatv(
        "comparison of distinct pointer types ({0} and {1})",
        orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }

  if (!is_ordered && ((orig_lhs_type.IsNullPtrType() && rhs_nullptr_or_zero) ||
                      (lhs_nullptr_or_zero && orig_rhs_type.IsNullPtrType())))
    return llvm::Error::success();

  // If the operands has arithmetic or enumeration type (scoped or unscoped),
  // usual arithmetic conversions are performed on both operands following the
  // rules for arithmetic operators.
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();

  lhs_type = lhs->GetCompilerType();
  rhs_type = rhs->GetCompilerType();
  if (lhs_type.IsScalarOrUnscopedEnumerationType() &&
      rhs_type.IsScalarOrUnscopedEnumerationType())
    return llvm::Error::success();

  // Scoped enums can be compared only to the instances of the same type.
  if (lhs_type.IsScopedEnumerationType() ||
      rhs_type.IsScopedEnumerationType()) {
    if (lhs_type.CompareTypes(rhs_type))
      return llvm::Error::success();
    std::string errMsg = llvm::formatv(
        "invalid operands to binary expression ({0} and {1})",
        orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }

  // Check if the value can be compared to a pointer. We allow all pointers,
  // integers, unscoped enumerations and a `nullptr` literal if it's an
  // equality/inequality comparison, including comparing a pointer with an
  // integer representing an address. This also allows comparing `nullptr` and
  // any integer, not just literal zero, e.g. `nullptr == 1` is false.
  auto comparable_to_pointer = [&](CompilerType t) {
    return t.IsPointerType() || t.IsInteger() ||
           t.IsUnscopedEnumerationType() || (!is_ordered && t.IsNullPtrType());
  };

  if ((lhs_type.IsPointerType() && comparable_to_pointer(rhs_type)) ||
      (comparable_to_pointer(lhs_type) && rhs_type.IsPointerType())) {
    // If both are pointers, check if they have comparable types.
    if ((lhs_type.IsPointerType() && !lhs_type.IsPointerToVoid()) &&
        (rhs_type.IsPointerType() && !rhs_type.IsPointerToVoid())) {
      // Compare canonical unqualified pointer types.
      CompilerType lhs_unqualified_type =
          lhs_type.GetCanonicalType().GetFullyUnqualifiedType();
      CompilerType rhs_unqualified_type =
          rhs_type.GetCanonicalType().GetFullyUnqualifiedType();
      bool comparable = lhs_unqualified_type.CompareTypes(rhs_unqualified_type);

      if (!comparable) {

        std::string errMsg = llvm::formatv(
            "comparison of distinct pointer types ({0} and {1})",
            orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
        return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
      }
    }
    // Comparing pointers to void is always allowed.
    return llvm::Error::success();
  }

  std::string errMsg = llvm::formatv(
      "invalid operands to binary expression ({0} and {1})",
      orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
  return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateComparison(BinaryOpKind kind, lldb::ValueObjectSP lhs,
                                lldb::ValueObjectSP rhs, bool lhs_is_literal,
                                bool rhs_is_literal, uint32_t location) {
  // Comparison works for:
  //  nullptr_t <-> {nullptr_t,integer} (if integer is literal zero)
  //  {nullptr_t,integer} <-> nullptr_t (if integer is literal zero)
  //  {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
  //  scoped_enum <-> scoped_enum (if the same type)
  //  pointer <-> pointer (if pointee types are compatible)
  //  pointer <-> {integer,unscoped_enum,nullptr_t}
  //  {integer,unscoped_enum,nullptr_t} <-> pointer
  if (auto error = ValidateComparison(kind, lhs, rhs, lhs_is_literal,
                                      rhs_is_literal, location))
    return error;

  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();
  CompilerType boolean_type = GetBasicType(*type_system, lldb::eBasicTypeBool);

  return EvaluateScalarOp(kind, lhs, rhs, boolean_type, location);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateBinaryBitwise(BinaryOpKind kind, lldb::ValueObjectSP lhs,
                                   lldb::ValueObjectSP rhs, uint32_t location) {
  // Operations {'&', '|', '^'} work for:
  //  {integer,unscoped_enum} <-> {integer,unscoped_enum}
  auto orig_lhs_type = lhs->GetCompilerType();
  auto orig_rhs_type = rhs->GetCompilerType();
  auto type_or_err = ArithmeticConversion(lhs, rhs, location);
  if (!type_or_err)
    return type_or_err.takeError();
  CompilerType result_type = *type_or_err;

  if (!result_type.IsInteger()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }

  return EvaluateScalarOp(kind, lhs, rhs, result_type, location);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateBinaryShift(BinaryOpKind kind, lldb::ValueObjectSP lhs,
                                 lldb::ValueObjectSP rhs, uint32_t location) {
  // Operations {'>>', '<<'} work for:
  //  {integer,unscoped_enum} <-> {integer,unscoped_enum}
  CompilerType orig_lhs_type = lhs->GetCompilerType();
  CompilerType orig_rhs_type = rhs->GetCompilerType();
  auto lhs_or_err = UnaryConversion(lhs, location);
  if (!lhs_or_err)
    return lhs_or_err.takeError();
  lhs = *lhs_or_err;
  auto rhs_or_err = UnaryConversion(rhs, location);
  if (!rhs_or_err)
    return rhs_or_err.takeError();
  rhs = *rhs_or_err;

  CompilerType lhs_type = lhs->GetCompilerType();
  CompilerType rhs_type = rhs->GetCompilerType();
  if (!lhs_type.IsInteger() || !rhs_type.IsInteger()) {
    std::string errMsg =
        llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
                      orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
  }

  bool success;
  uint64_t amount = rhs->GetValueAsUnsigned(0, &success);
  if (!success)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "could not get the shift amount as an integer", location);
  llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
  if (!lhs_size)
    return lhs_size.takeError();
  if (amount >= *lhs_size)
    return llvm::make_error<DILDiagnosticError>(m_expr, "invalid shift amount",
                                                location);

  return EvaluateScalarOp(kind, lhs, rhs, lhs_type, location);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::EvaluateLogical(const BinaryOpNode &node) {
  // Operations {'&&', '||'} work for:
  //  {IsContextuallyConvertibleToBool} <-> {IsContextuallyConvertibleToBool}
  // Note: These operators will not evaluate or check the type of RHS
  // if the result is determined after evaluating LHS.
  auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
  if (!lhs_or_err)
    return lhs_or_err;
  lldb::ValueObjectSP lhs = *lhs_or_err;
  auto lhs_type = lhs->GetCompilerType();
  if (!lhs_type.IsContextuallyConvertibleToBool()) {
    std::string errMsg = llvm::formatv(
        "value of type {0} is not contextually convertible to 'bool'",
        lhs_type.TypeDescription());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                node.GetLocation());
  }
  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();

  // For "&&", exit early if LHS is "false"
  // For "||", exit early if LHS is "true".
  auto lvalue_or_err = lhs->GetValueAsBool();
  if (!lvalue_or_err)
    return lvalue_or_err.takeError();
  bool lhs_val = *lvalue_or_err;
  bool exit_early = node.GetKind() == BinaryOpKind::LAnd ? !lhs_val : lhs_val;
  if (exit_early)
    return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
                                                  lhs_val, "result");

  // If the result is to be determined, evaluate the RHS.
  auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
  if (!rhs_or_err)
    return rhs_or_err;
  lldb::ValueObjectSP rhs = *rhs_or_err;
  auto rhs_type = rhs->GetCompilerType();
  if (!rhs_type.IsContextuallyConvertibleToBool()) {
    std::string errMsg = llvm::formatv(
        "value of type {0} is not contextually convertible to 'bool'",
        rhs_type.TypeDescription());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                node.GetLocation());
  }

  auto rvalue_or_err = rhs->GetValueAsBool();
  if (!rvalue_or_err)
    return rvalue_or_err.takeError();
  return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
                                                *rvalue_or_err, "result");
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const BinaryOpNode &node) {
  // Handle logical operators separately. They may or may not evaluate RHS.
  if (node.GetKind() == BinaryOpKind::LAnd ||
      node.GetKind() == BinaryOpKind::LOr)
    return EvaluateLogical(node);

  auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
  if (!lhs_or_err)
    return lhs_or_err;
  lldb::ValueObjectSP lhs = *lhs_or_err;
  auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
  if (!rhs_or_err)
    return rhs_or_err;
  lldb::ValueObjectSP rhs = *rhs_or_err;

  bool lhs_is_literal = node.GetLHS().IsConstLiteral();
  bool rhs_is_literal = node.GetRHS().IsConstLiteral();
  lldb::TypeSystemSP lhs_system =
      lhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
  lldb::TypeSystemSP rhs_system =
      rhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
  if (lhs_system->GetPluginName() != rhs_system->GetPluginName()) {
    // TODO: Attempt to convert values to current CU's type system
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "operands have different type systems", node.GetLocation());
  }

  switch (node.GetKind()) {
  case BinaryOpKind::Assign:
    return EvaluateAssignment(lhs, rhs, node.GetLocation());
  case BinaryOpKind::Add:
    return EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
  case BinaryOpKind::Sub:
    return EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
  case BinaryOpKind::Mul:
    return EvaluateBinaryMultiplication(lhs, rhs, node.GetLocation());
  case BinaryOpKind::Div:
    return EvaluateBinaryDivision(lhs, rhs, node.GetLocation());
  case BinaryOpKind::Rem:
    return EvaluateBinaryRemainder(lhs, rhs, node.GetLocation());
  case BinaryOpKind::And:
  case BinaryOpKind::Xor:
  case BinaryOpKind::Or:
    return EvaluateBinaryBitwise(node.GetKind(), lhs, rhs, node.GetLocation());
  case BinaryOpKind::Shl:
  case BinaryOpKind::Shr:
    return EvaluateBinaryShift(node.GetKind(), lhs, rhs, node.GetLocation());
  case BinaryOpKind::AddAssign: {
    auto ret_or_err = EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::SubAssign: {
    auto ret_or_err = EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::MulAssign: {
    auto ret_or_err =
        EvaluateBinaryMultiplication(lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::DivAssign: {
    auto ret_or_err = EvaluateBinaryDivision(lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::RemAssign: {
    auto ret_or_err = EvaluateBinaryRemainder(lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::AndAssign: {
    auto ret_or_err =
        EvaluateBinaryBitwise(BinaryOpKind::And, lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::XorAssign: {
    auto ret_or_err =
        EvaluateBinaryBitwise(BinaryOpKind::Xor, lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::OrAssign: {
    auto ret_or_err =
        EvaluateBinaryBitwise(BinaryOpKind::Or, lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::ShlAssign: {
    auto ret_or_err =
        EvaluateBinaryShift(BinaryOpKind::Shl, lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::ShrAssign: {
    auto ret_or_err =
        EvaluateBinaryShift(BinaryOpKind::Shr, lhs, rhs, node.GetLocation());
    if (!ret_or_err)
      return ret_or_err;
    return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
  }
  case BinaryOpKind::EQ:
  case BinaryOpKind::NE:
  case BinaryOpKind::LT:
  case BinaryOpKind::LE:
  case BinaryOpKind::GT:
  case BinaryOpKind::GE:
    return EvaluateComparison(node.GetKind(), lhs, rhs, lhs_is_literal,
                              rhs_is_literal, node.GetLocation());
  default:
    break;
  }

  return llvm::make_error<DILDiagnosticError>(
      m_expr, "unimplemented binary operation", node.GetLocation());
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const MemberOfNode &node) {
  auto base_or_err = Evaluate(node.GetBase());
  if (!base_or_err)
    return base_or_err;
  bool expr_is_ptr = node.GetIsArrow();
  lldb::ValueObjectSP base = *base_or_err;

  // Perform some basic type & correctness checking.
  if (node.GetIsArrow()) {
    // If we have a non-pointer type with a synthetic value then lets check
    // if we have a synthetic dereference specified.
    if (!base->IsPointerType() && base->HasSyntheticValue()) {
      Status deref_error;
      if (lldb::ValueObjectSP synth_deref_sp =
              base->GetSyntheticValue()->Dereference(deref_error);
          synth_deref_sp && deref_error.Success()) {
        base = std::move(synth_deref_sp);
      }
      if (!base || deref_error.Fail()) {
        std::string errMsg = llvm::formatv(
            "Failed to dereference synthetic value: {0}", deref_error);
        return llvm::make_error<DILDiagnosticError>(
            m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
      }

      // Some synthetic plug-ins fail to set the error in Dereference
      if (!base) {
        std::string errMsg = "Failed to dereference synthetic value";
        return llvm::make_error<DILDiagnosticError>(
            m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
      }
      expr_is_ptr = false;
    }
  }

  if (m_check_ptr_vs_member) {
    bool base_is_ptr = base->IsPointerType();

    if (expr_is_ptr != base_is_ptr) {
      if (base_is_ptr) {
        std::string errMsg =
            llvm::formatv("member reference type {0} is a pointer; "
                          "did you mean to use '->'?",
                          base->GetCompilerType().TypeDescription());
        return llvm::make_error<DILDiagnosticError>(
            m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
      } else {
        std::string errMsg =
            llvm::formatv("member reference type {0} is not a pointer; "
                          "did you mean to use '.'?",
                          base->GetCompilerType().TypeDescription());
        return llvm::make_error<DILDiagnosticError>(
            m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
      }
    }
  }

  lldb::ValueObjectSP field_obj =
      base->GetChildMemberWithName(node.GetFieldName());
  if (!field_obj) {
    if (m_use_synthetic) {
      field_obj = base->GetSyntheticValue();
      if (field_obj)
        field_obj = field_obj->GetChildMemberWithName(node.GetFieldName());
    }

    if (!m_use_synthetic || !field_obj) {
      std::string errMsg = llvm::formatv(
          "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
          base->GetTypeName().AsCString("<invalid type>"), base->GetName());
      return llvm::make_error<DILDiagnosticError>(
          m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
    }
  }

  if (field_obj) {
    if (m_use_dynamic != lldb::eNoDynamicValues) {
      lldb::ValueObjectSP dynamic_val_sp =
          field_obj->GetDynamicValue(m_use_dynamic);
      if (dynamic_val_sp)
        field_obj = dynamic_val_sp;
    }
    return field_obj;
  }

  CompilerType base_type = base->GetCompilerType();
  if (node.GetIsArrow() && base->IsPointerType())
    base_type = base_type.GetPointeeType();
  std::string errMsg = llvm::formatv(
      "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
      base->GetTypeName().AsCString("<invalid type>"), base->GetName());
  return llvm::make_error<DILDiagnosticError>(
      m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const ArraySubscriptNode &node) {
  auto idx_or_err = EvaluateAndDereference(node.GetIndex());
  if (!idx_or_err)
    return idx_or_err;
  lldb::ValueObjectSP idx = *idx_or_err;

  if (!idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "array subscript is not an integer", node.GetLocation());
  }

  StreamString var_expr_path_strm;
  uint64_t child_idx = idx->GetValueAsUnsigned(0);
  lldb::ValueObjectSP child_valobj_sp;

  auto base_or_err = Evaluate(node.GetBase());
  if (!base_or_err)
    return base_or_err;
  lldb::ValueObjectSP base = *base_or_err;

  CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
  base->GetExpressionPath(var_expr_path_strm);
  bool is_incomplete_array = false;
  if (base_type.IsPointerType()) {
    bool is_objc_pointer = true;

    if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
      is_objc_pointer = false;
    else if (!base->GetCompilerType().IsPointerType())
      is_objc_pointer = false;

    if (!m_use_synthetic && is_objc_pointer) {
      std::string err_msg = llvm::formatv(
          "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
          base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation());
    }
    if (is_objc_pointer) {
      lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
      if (!synthetic || synthetic == base) {
        std::string err_msg =
            llvm::formatv("\"({0}) {1}\" is not an array type",
                          base->GetTypeName().AsCString("<invalid type>"),
                          var_expr_path_strm.GetData());
        return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                    node.GetLocation());
      }
      if (static_cast<uint32_t>(child_idx) >=
          synthetic->GetNumChildrenIgnoringErrors()) {
        std::string err_msg = llvm::formatv(
            "array index {0} is not valid for \"({1}) {2}\"", child_idx,
            base->GetTypeName().AsCString("<invalid type>"),
            var_expr_path_strm.GetData());
        return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                    node.GetLocation());
      }
      child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
      if (!child_valobj_sp) {
        std::string err_msg = llvm::formatv(
            "array index {0} is not valid for \"({1}) {2}\"", child_idx,
            base->GetTypeName().AsCString("<invalid type>"),
            var_expr_path_strm.GetData());
        return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                    node.GetLocation());
      }
      if (m_use_dynamic != lldb::eNoDynamicValues) {
        if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
          child_valobj_sp = std::move(dynamic_sp);
      }
      return child_valobj_sp;
    }

    child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
    if (!child_valobj_sp) {
      std::string err_msg = llvm::formatv(
          "failed to use pointer as array for index {0} for "
          "\"({1}) {2}\"",
          child_idx, base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      if (base_type.IsPointerToVoid())
        err_msg = "subscript of pointer to incomplete type 'void'";
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation());
    }
  } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
    child_valobj_sp = base->GetChildAtIndex(child_idx);
    if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
      child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
    if (!child_valobj_sp) {
      std::string err_msg = llvm::formatv(
          "array index {0} is not valid for \"({1}) {2}\"", child_idx,
          base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation());
    }
  } else if (base_type.IsScalarType()) {
    child_valobj_sp =
        base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
    if (!child_valobj_sp) {
      std::string err_msg = llvm::formatv(
          "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", child_idx,
          child_idx, base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation(), 1);
    }
  } else {
    lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
    if (!m_use_synthetic || !synthetic || synthetic == base) {
      std::string err_msg =
          llvm::formatv("\"{0}\" is not an array type",
                        base->GetTypeName().AsCString("<invalid type>"));
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation(), 1);
    }
    if (static_cast<uint32_t>(child_idx) >=
        synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
      std::string err_msg = llvm::formatv(
          "array index {0} is not valid for \"({1}) {2}\"", child_idx,
          base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation(), 1);
    }
    child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
    if (!child_valobj_sp) {
      std::string err_msg = llvm::formatv(
          "array index {0} is not valid for \"({1}) {2}\"", child_idx,
          base->GetTypeName().AsCString("<invalid type>"),
          var_expr_path_strm.GetData());
      return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
                                                  node.GetLocation(), 1);
    }
  }

  if (child_valobj_sp) {
    if (m_use_dynamic != lldb::eNoDynamicValues) {
      if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
        child_valobj_sp = std::move(dynamic_sp);
    }
    return child_valobj_sp;
  }

  bool success;
  int64_t signed_child_idx = idx->GetValueAsSigned(0, &success);
  if (!success)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "could not get the index as an integer",
        node.GetIndex().GetLocation());
  return base->GetSyntheticArrayMember(signed_child_idx, true);
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const BitFieldExtractionNode &node) {
  auto first_idx_or_err = EvaluateAndDereference(node.GetFirstIndex());
  if (!first_idx_or_err)
    return first_idx_or_err;
  lldb::ValueObjectSP first_idx = *first_idx_or_err;
  auto last_idx_or_err = EvaluateAndDereference(node.GetLastIndex());
  if (!last_idx_or_err)
    return last_idx_or_err;
  lldb::ValueObjectSP last_idx = *last_idx_or_err;

  if (!first_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType() ||
      !last_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "bit index is not an integer", node.GetLocation());
  }

  bool success_first, success_last;
  int64_t first_index = first_idx->GetValueAsSigned(0, &success_first);
  int64_t last_index = last_idx->GetValueAsSigned(0, &success_last);
  if (!success_first || !success_last)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "could not get the index as an integer", node.GetLocation());

  // Reject negative indices before the swap below, so the diagnostic reports
  // the range as the user wrote it. A negative index would also wrap to a huge
  // offset in the uint32_t GetSyntheticBitFieldChild call below.
  if (first_index < 0 || last_index < 0) {
    std::string message =
        llvm::formatv("bitfield range {0}:{1} is not valid (negative index)",
                      first_index, last_index);
    return llvm::make_error<DILDiagnosticError>(m_expr, message,
                                                node.GetLocation());
  }

  // if the format given is [high-low], swap range
  if (first_index > last_index)
    std::swap(first_index, last_index);

  // GetMaxU64Bitfield in the data layer only supports up to 64 bits (it asserts
  // bitfield_bit_size <= 64 and otherwise shifts out of bounds), so reject a
  // wider range here.
  if (last_index - first_index >= 64) {
    std::string message =
        llvm::formatv("bitfield range {0}:{1} is not valid (more than 64 bits)",
                      first_index, last_index);
    return llvm::make_error<DILDiagnosticError>(m_expr, message,
                                                node.GetLocation());
  }

  auto base_or_err = EvaluateAndDereference(node.GetBase());
  if (!base_or_err)
    return base_or_err;
  lldb::ValueObjectSP base = *base_or_err;

  // The high index must lie within the base object's storage; a bit index past
  // its bit size shifts out of bounds when the child is later read or formatted
  // (GetMaxU64Bitfield).
  llvm::Expected<uint64_t> base_bit_size =
      base->GetCompilerType().GetBitSize(&m_stack_frame);
  if (!base_bit_size)
    return base_bit_size.takeError();
  if (static_cast<uint64_t>(last_index) >= *base_bit_size) {
    std::string message = llvm::formatv(
        "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
        last_index, base->GetTypeName().AsCString("<invalid type>"),
        base->GetName().GetStringRef());
    return llvm::make_error<DILDiagnosticError>(m_expr, message,
                                                node.GetLocation());
  }

  lldb::ValueObjectSP child_valobj_sp =
      base->GetSyntheticBitFieldChild(first_index, last_index, true);
  if (!child_valobj_sp) {
    std::string message = llvm::formatv(
        "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
        last_index, base->GetTypeName().AsCString("<invalid type>"),
        base->GetName().GetStringRef());
    return llvm::make_error<DILDiagnosticError>(m_expr, message,
                                                node.GetLocation());
  }
  return child_valobj_sp;
}

llvm::Expected<CompilerType>
Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
                             ExecutionContextScope &ctx,
                             const IntegerLiteralNode &literal) {
  // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
  // an unsigned integer.
  bool unsigned_is_allowed = literal.IsUnsigned() || literal.GetRadix() != 10;
  llvm::APInt apint = literal.GetValue();

  llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
  if (literal.GetTypeSuffix() <= IntegerTypeSuffix::None)
    candidates.emplace_back(lldb::eBasicTypeInt,
                            unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
                                                : lldb::eBasicTypeInvalid);
  if (literal.GetTypeSuffix() <= IntegerTypeSuffix::Long)
    candidates.emplace_back(lldb::eBasicTypeLong,
                            unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
                                                : lldb::eBasicTypeInvalid);
  candidates.emplace_back(lldb::eBasicTypeLongLong,
                          lldb::eBasicTypeUnsignedLongLong);
  for (auto [signed_, unsigned_] : candidates) {
    CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
    if (!signed_type)
      continue;
    llvm::Expected<uint64_t> size = signed_type.GetBitSize(&ctx);
    if (!size)
      return size.takeError();
    if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
      return signed_type;
    if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
      return type_system->GetBasicTypeFromAST(unsigned_);
  }

  return llvm::make_error<DILDiagnosticError>(
      m_expr,
      "integer literal is too large to be represented in any integer type",
      literal.GetLocation());
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const IntegerLiteralNode &node) {
  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();

  llvm::Expected<CompilerType> type =
      PickIntegerType(*type_system, m_stack_frame, node);
  if (!type)
    return type.takeError();

  Scalar scalar = node.GetValue();
  // APInt from StringRef::getAsInteger comes with just enough bitwidth to
  // hold the value. This adjusts APInt bitwidth to match the compiler type.
  llvm::Expected<uint64_t> type_bitsize = type->GetBitSize(&m_stack_frame);
  if (!type_bitsize)
    return type_bitsize.takeError();
  // Literal itself cannot be a negative value, so we do an unsigned extension.
  scalar.TruncOrExtendTo(*type_bitsize, false);
  // If the picked compiler type is signed, make the scalar signed as well.
  if (type->IsSigned())
    scalar.MakeSigned();
  return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, *type,
                                                  "result");
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const FloatLiteralNode &node) {
  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();

  bool isFloat =
      &node.GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
  lldb::BasicType basic_type =
      isFloat ? lldb::eBasicTypeFloat : lldb::eBasicTypeDouble;
  CompilerType type = GetBasicType(*type_system, basic_type);

  if (!type)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "unable to create a const literal", node.GetLocation());

  Scalar scalar = node.GetValue();
  return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
                                                  "result");
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const BooleanLiteralNode &node) {
  bool value = node.GetValue();
  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();
  return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
                                                value, "result");
}

llvm::Expected<CastKind>
Interpreter::VerifyArithmeticCast(CompilerType source_type,
                                  CompilerType target_type, int location) {
  if (source_type.IsPointerType() || source_type.IsNullPtrType()) {
    // Cast from pointer to float/double is not allowed.
    if (target_type.GetTypeInfo() & lldb::eTypeIsFloat) {
      std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
                                         source_type.TypeDescription(),
                                         target_type.TypeDescription());
      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          source_type.TypeDescription().length());
    }

    // Casting from pointer to bool is always valid.
    if (target_type.IsBoolean())
      return CastKind::eArithmetic;

    // Otherwise check if the result type is at least as big as the pointer
    // size.
    uint64_t type_byte_size = 0;
    uint64_t rhs_type_byte_size = 0;
    if (auto temp = target_type.GetByteSize(&m_stack_frame)) {
      type_byte_size = *temp;
    } else {
      std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
                                         target_type.TypeDescription());
      LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
                     "GetByteSize failed: {0}");
      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          target_type.TypeDescription().length());
    }

    if (auto temp = source_type.GetByteSize(&m_stack_frame)) {
      rhs_type_byte_size = *temp;
    } else {
      std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
                                         source_type.TypeDescription());
      LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
                     "GetByteSize failed: {0}");
      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          source_type.TypeDescription().length());
    }

    if (type_byte_size < rhs_type_byte_size) {
      std::string errMsg = llvm::formatv(
          "cast from pointer to smaller type {0} loses information",
          target_type.TypeDescription());
      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          source_type.TypeDescription().length());
    }
  } else if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
    // Otherwise accept only arithmetic types and enums.
    std::string errMsg = llvm::formatv("cannot convert {0} to {1}",
                                       source_type.TypeDescription(),
                                       target_type.TypeDescription());

    return llvm::make_error<DILDiagnosticError>(
        m_expr, std::move(errMsg), location,
        source_type.TypeDescription().length());
  }
  return CastKind::eArithmetic;
}

llvm::Expected<CastKind>
Interpreter::VerifyCastType(lldb::ValueObjectSP operand,
                            CompilerType source_type, CompilerType target_type,
                            int location) {

  if (target_type.IsScalarType())
    return VerifyArithmeticCast(source_type, target_type, location);

  if (target_type.IsEnumerationType()) {
    // Cast to enum type.
    if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
      std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
                                         source_type.TypeDescription(),
                                         target_type.TypeDescription());

      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          source_type.TypeDescription().length());
    }
    return CastKind::eEnumeration;
  }

  if (target_type.IsPointerType()) {
    if (!source_type.IsInteger() && !source_type.IsEnumerationType() &&
        !source_type.IsArrayType() && !source_type.IsPointerType() &&
        !source_type.IsNullPtrType()) {
      std::string errMsg = llvm::formatv(
          "cannot cast from type {0} to pointer type {1}",
          source_type.TypeDescription(), target_type.TypeDescription());

      return llvm::make_error<DILDiagnosticError>(
          m_expr, std::move(errMsg), location,
          source_type.TypeDescription().length());
    }
    return CastKind::ePointer;
  }

  // Unsupported cast.
  std::string errMsg = llvm::formatv(
      "casting of {0} to {1} is not implemented yet",
      source_type.TypeDescription(), target_type.TypeDescription());
  return llvm::make_error<DILDiagnosticError>(
      m_expr, std::move(errMsg), location,
      source_type.TypeDescription().length());
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
  auto operand_or_err = Evaluate(node.GetOperand());

  if (!operand_or_err)
    return operand_or_err;

  lldb::ValueObjectSP operand = *operand_or_err;
  CompilerType op_type = operand->GetCompilerType();
  CompilerType target_type = node.GetType();

  if (op_type.IsReferenceType())
    op_type = op_type.GetNonReferenceType();
  if (target_type.IsScalarType() && op_type.IsArrayType()) {
    operand = ArrayToPointerConversion(*operand, m_stack_frame,
                                       operand->GetName().GetStringRef());
    op_type = operand->GetCompilerType();
  }
  auto type_or_err =
      VerifyCastType(operand, op_type, target_type, node.GetLocation());
  if (!type_or_err)
    return type_or_err.takeError();

  CastKind cast_kind = *type_or_err;
  if (operand->GetCompilerType().IsReferenceType()) {
    Status error;
    operand = operand->Dereference(error);
    if (error.Fail())
      return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
                                                  node.GetLocation());
  }

  lldb::ValueObjectSP result;
  switch (cast_kind) {
  case CastKind::eEnumeration: {
    // FIXME: is this correct for float vector types?
    if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
        op_type.IsEnumerationType())
      result = operand->CastToEnumType(target_type);
    break;
  }
  case CastKind::eArithmetic: {
    if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
        op_type.IsScalarType() || op_type.IsEnumerationType())
      result = operand->CastToBasicType(target_type);
    break;
  }
  case CastKind::ePointer: {
    uint64_t addr = op_type.IsArrayType()
                        ? operand->GetLoadAddress()
                        : (op_type.IsSigned() ? operand->GetValueAsSigned(0)
                                              : operand->GetValueAsUnsigned(0));
    result = ValueObject::CreateValueObjectFromAddress(
        "result", addr, m_stack_frame, target_type,
        /* do_deref */ false);
    break;
  }
  case CastKind::eNone: {
    return lldb::ValueObjectSP();
  }
  } // switch

  if (result) {
    // If cast failed, retrieve the error message from the result.
    if (result->GetError().Fail())
      return llvm::make_error<DILDiagnosticError>(
          m_expr, result->GetError().AsCString(), node.GetLocation());
    return result;
  }

  std::string errMsg =
      llvm::formatv("unable to cast from '{0}' to '{1}'",
                    op_type.TypeDescription(), target_type.TypeDescription());
  return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
                                              node.GetLocation());
}

llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const ConditionalNode &node) {
  auto cond_or_err = EvaluateAndDereference(node.GetCondition());
  if (!cond_or_err)
    return cond_or_err;
  lldb::ValueObjectSP condition = *cond_or_err;

  CompilerType cond_type = condition->GetCompilerType();
  if (!cond_type.IsContextuallyConvertibleToBool()) {
    std::string errMsg = llvm::formatv(
        "value of type {0} is not contextually convertible to 'bool'",
        cond_type.TypeDescription());
    return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
                                                node.GetLocation());
  }
  // Note: DIL evaluates only the operand chosen by the condition,
  // and doesn't check the type or evaluate the other operand.
  auto value_or_err = condition->GetValueAsBool();
  if (value_or_err) {
    if (*value_or_err) {
      auto true_or_err = EvaluateAndDereference(node.GetTrueOperand());
      if (!true_or_err)
        return true_or_err;
      return *true_or_err;
    }
    auto false_or_err = EvaluateAndDereference(node.GetFalseOperand());
    if (!false_or_err)
      return false_or_err;
    return *false_or_err;
  }
  return value_or_err.takeError();
}

llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const SizeOfNode &node) {
  CompilerType typearg = node.GetTypeArg();
  Scalar size;
  if (typearg.IsValid()) {
    if (typearg.IsReferenceType())
      typearg = typearg.GetNonReferenceType();
    llvm::Expected<uint64_t> byte_size = typearg.GetByteSize(m_target.get());
    if (!byte_size)
      return byte_size.takeError();
    size = *byte_size;
  } else {
    auto arg_or_err = EvaluateAndDereference(node.GetNodeArg());
    if (!arg_or_err)
      return arg_or_err;
    lldb::ValueObjectSP arg = *arg_or_err;

    if (arg->IsBitfield())
      return llvm::make_error<DILDiagnosticError>(
          m_expr, "invalid application of 'sizeof' to bit-field",
          node.GetLocation());

    llvm::Expected<uint64_t> byte_size = arg->GetByteSize();
    if (!byte_size)
      return byte_size.takeError();
    size = *byte_size;
  }

  llvm::Expected<lldb::TypeSystemSP> type_system =
      GetTypeSystemFromCU(m_stack_frame);
  if (!type_system)
    return type_system.takeError();
  CompilerType size_type = type_system.get()->GetSizeType();
  if (!size_type)
    return llvm::make_error<DILDiagnosticError>(
        m_expr, "unable to determine size type", node.GetLocation());

  return ValueObject::CreateValueObjectFromScalar(m_stack_frame, size,
                                                  size_type, "result");
}

} // namespace lldb_private::dil
