/* Definitions for C expressions

   Copyright (C) 2020-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef C_EXP_H
#define C_EXP_H

#include "expop.h"
#include "objc-lang.h"

extern struct value *eval_op_objc_selector (struct type *expect_type,
					    struct expression *exp,
					    enum noside noside,
					    const char *sel);
extern struct value *opencl_value_cast (struct type *type, struct value *arg);
extern struct value *eval_opencl_assign (struct type *expect_type,
					 struct expression *exp,
					 enum noside noside,
					 enum exp_opcode op,
					 struct value *arg1,
					 struct value *arg2);
extern struct value *opencl_relop (struct type *expect_type,
				   struct expression *exp,
				   enum noside noside, enum exp_opcode op,
				   struct value *arg1, struct value *arg2);
extern struct value *opencl_logical_not (struct type *expect_type,
					 struct expression *exp,
					 enum noside noside,
					 enum exp_opcode op,
					 struct value *arg);

namespace expr
{

class c_string_operation
  : public tuple_holding_operation<enum c_string_type_values,
				   std::vector<std::string>>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override;

  enum exp_opcode opcode () const override
  { return OP_STRING; }
};

class objc_nsstring_operation
  : public tuple_holding_operation<std::string>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override
  {
    const std::string &str = std::get<0> (m_storage);
    return value_nsstring (exp->gdbarch, str.c_str (), str.size () + 1);
  }

  enum exp_opcode opcode () const override
  { return OP_OBJC_NSSTRING; }
};

class objc_selector_operation
  : public tuple_holding_operation<std::string>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override
  {
    return eval_op_objc_selector (expect_type, exp, noside,
				  std::get<0> (m_storage).c_str ());
  }

  enum exp_opcode opcode () const override
  { return OP_OBJC_SELECTOR; }
};

/* An Objective C message call.  */
class objc_msgcall_operation
  : public tuple_holding_operation<CORE_ADDR, operation_up,
				   std::vector<operation_up>>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override;

  enum exp_opcode opcode () const override
  { return OP_OBJC_MSGCALL; }
};

using opencl_cast_type_operation = cxx_cast_operation<UNOP_CAST_TYPE,
						      opencl_value_cast>;

/* Binary operations, as needed for OpenCL.  */
template<enum exp_opcode OP, binary_ftype FUNC,
	 typename BASE = maybe_constant_operation<operation_up, operation_up>>
class opencl_binop_operation
  : public BASE
{
public:

  using BASE::BASE;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override
  {
    value *lhs
      = std::get<0> (this->m_storage)->evaluate (nullptr, exp, noside);
    value *rhs
      = std::get<1> (this->m_storage)->evaluate (value_type (lhs), exp,
						 noside);
    return FUNC (expect_type, exp, noside, OP, lhs, rhs);
  }

  enum exp_opcode opcode () const override
  { return OP; }
};

using opencl_assign_operation = opencl_binop_operation<BINOP_ASSIGN,
						       eval_opencl_assign,
						       assign_operation>;
using opencl_equal_operation = opencl_binop_operation<BINOP_EQUAL,
						      opencl_relop>;
using opencl_notequal_operation = opencl_binop_operation<BINOP_NOTEQUAL,
							 opencl_relop>;
using opencl_less_operation = opencl_binop_operation<BINOP_LESS,
						     opencl_relop>;
using opencl_gtr_operation = opencl_binop_operation<BINOP_GTR,
						    opencl_relop>;
using opencl_geq_operation = opencl_binop_operation<BINOP_GEQ,
						    opencl_relop>;
using opencl_leq_operation = opencl_binop_operation<BINOP_LEQ,
						    opencl_relop>;

using opencl_not_operation = unop_operation<UNOP_LOGICAL_NOT,
					    opencl_logical_not>;

/* STRUCTOP_STRUCT implementation for OpenCL.  */
class opencl_structop_operation
  : public structop_base_operation
{
public:

  using structop_base_operation::structop_base_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override;

  enum exp_opcode opcode () const override
  { return STRUCTOP_STRUCT; }
};

/* This handles the "&&" and "||" operations for OpenCL.  */
class opencl_logical_binop_operation
  : public tuple_holding_operation<enum exp_opcode,
				   operation_up, operation_up>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override;

  enum exp_opcode opcode () const override
  { return std::get<0> (m_storage); }
};

/* The ?: ternary operator for OpenCL.  */
class opencl_ternop_cond_operation
  : public tuple_holding_operation<operation_up, operation_up, operation_up>
{
public:

  using tuple_holding_operation::tuple_holding_operation;

  value *evaluate (struct type *expect_type,
		   struct expression *exp,
		   enum noside noside) override;

  enum exp_opcode opcode () const override
  { return TERNOP_COND; }
};

}/* namespace expr */

#endif /* C_EXP_H */
