/* Convert types from GDB to GCC

   Copyright (C) 2014-2021 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/>.  */


#include "defs.h"
#include "gdbtypes.h"
#include "compile-internal.h"
#include "compile-c.h"
#include "objfiles.h"

/* Convert a pointer type to its gcc representation.  */

static gcc_type
convert_pointer (compile_c_instance *context, struct type *type)
{
  gcc_type target = context->convert_type (TYPE_TARGET_TYPE (type));

  return context->plugin ().build_pointer_type (target);
}

/* Convert an array type to its gcc representation.  */

static gcc_type
convert_array (compile_c_instance *context, struct type *type)
{
  gcc_type element_type;
  struct type *range = type->index_type ();

  element_type = context->convert_type (TYPE_TARGET_TYPE (type));

  if (range->bounds ()->low.kind () != PROP_CONST)
    return context->plugin ().error (_("array type with non-constant"
				       " lower bound is not supported"));
  if (range->bounds ()->low.const_val () != 0)
    return context->plugin ().error (_("cannot convert array type with "
				       "non-zero lower bound to C"));

  if (range->bounds ()->high.kind () == PROP_LOCEXPR
      || range->bounds ()->high.kind () == PROP_LOCLIST)
    {
      gcc_type result;

      if (type->is_vector ())
	return context->plugin ().error (_("variably-sized vector type"
					   " is not supported"));

      std::string upper_bound
	= c_get_range_decl_name (&range->bounds ()->high);
      result = context->plugin ().build_vla_array_type (element_type,
							upper_bound.c_str ());
      return result;
    }
  else
    {
      LONGEST low_bound, high_bound, count;

      if (!get_array_bounds (type, &low_bound, &high_bound))
	count = -1;
      else
	{
	  gdb_assert (low_bound == 0); /* Ensured above.  */
	  count = high_bound + 1;
	}

      if (type->is_vector ())
	return context->plugin ().build_vector_type (element_type, count);
      return context->plugin ().build_array_type (element_type, count);
    }
}

/* Convert a struct or union type to its gcc representation.  */

static gcc_type
convert_struct_or_union (compile_c_instance *context, struct type *type)
{
  int i;
  gcc_type result;

  /* First we create the resulting type and enter it into our hash
     table.  This lets recursive types work.  */
  if (type->code () == TYPE_CODE_STRUCT)
    result = context->plugin ().build_record_type ();
  else
    {
      gdb_assert (type->code () == TYPE_CODE_UNION);
      result = context->plugin ().build_union_type ();
    }
  context->insert_type (type, result);

  for (i = 0; i < type->num_fields (); ++i)
    {
      gcc_type field_type;
      unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i);

      field_type = context->convert_type (type->field (i).type ());
      if (bitsize == 0)
	bitsize = 8 * TYPE_LENGTH (type->field (i).type ());
      context->plugin ().build_add_field (result,
					  type->field (i).name (),
					  field_type,
					  bitsize,
					  TYPE_FIELD_BITPOS (type, i));
    }

  context->plugin ().finish_record_or_union (result, TYPE_LENGTH (type));
  return result;
}

/* Convert an enum type to its gcc representation.  */

static gcc_type
convert_enum (compile_c_instance *context, struct type *type)
{
  gcc_type int_type, result;
  int i;

  int_type = context->plugin ().int_type_v0 (type->is_unsigned (),
					     TYPE_LENGTH (type));

  result = context->plugin ().build_enum_type (int_type);
  for (i = 0; i < type->num_fields (); ++i)
    {
      context->plugin ().build_add_enum_constant
	(result, type->field (i).name (), TYPE_FIELD_ENUMVAL (type, i));
    }

  context->plugin ().finish_enum_type (result);

  return result;
}

/* Convert a function type to its gcc representation.  */

static gcc_type
convert_func (compile_c_instance *context, struct type *type)
{
  int i;
  gcc_type result, return_type;
  struct gcc_type_array array;
  int is_varargs = type->has_varargs () || !type->is_prototyped ();

  struct type *target_type = TYPE_TARGET_TYPE (type);

  /* Functions with no debug info have no return type.  Ideally we'd
     want to fallback to the type of the cast just before the
     function, like GDB's built-in expression parser, but we don't
     have access to that type here.  For now, fallback to int, like
     GDB's parser used to do.  */
  if (target_type == NULL)
    {
      if (type->is_objfile_owned ())
	target_type = objfile_type (type->objfile_owner ())->builtin_int;
      else
	target_type = builtin_type (type->arch_owner ())->builtin_int;
      warning (_("function has unknown return type; assuming int"));
    }

  /* This approach means we can't make self-referential function
     types.  Those are impossible in C, though.  */
  return_type = context->convert_type (target_type);

  array.n_elements = type->num_fields ();
  std::vector<gcc_type> elements (array.n_elements);
  array.elements = elements.data ();
  for (i = 0; i < type->num_fields (); ++i)
    array.elements[i] = context->convert_type (type->field (i).type ());

  result = context->plugin ().build_function_type (return_type,
						   &array, is_varargs);

  return result;
}

/* Convert an integer type to its gcc representation.  */

static gcc_type
convert_int (compile_c_instance *context, struct type *type)
{
  if (context->plugin ().version () >= GCC_C_FE_VERSION_1)
    {
      if (type->has_no_signedness ())
	{
	  gdb_assert (TYPE_LENGTH (type) == 1);
	  return context->plugin ().char_type ();
	}
      return context->plugin ().int_type (type->is_unsigned (),
					  TYPE_LENGTH (type),
					  type->name ());
    }
  else
    return context->plugin ().int_type_v0 (type->is_unsigned (),
					   TYPE_LENGTH (type));
}

/* Convert a floating-point type to its gcc representation.  */

static gcc_type
convert_float (compile_c_instance *context, struct type *type)
{
  if (context->plugin ().version () >= GCC_C_FE_VERSION_1)
    return context->plugin ().float_type (TYPE_LENGTH (type),
					  type->name ());
  else
    return context->plugin ().float_type_v0 (TYPE_LENGTH (type));
}

/* Convert the 'void' type to its gcc representation.  */

static gcc_type
convert_void (compile_c_instance *context, struct type *type)
{
  return context->plugin ().void_type ();
}

/* Convert a boolean type to its gcc representation.  */

static gcc_type
convert_bool (compile_c_instance *context, struct type *type)
{
  return context->plugin ().bool_type ();
}

/* Convert a qualified type to its gcc representation.  */

static gcc_type
convert_qualified (compile_c_instance *context, struct type *type)
{
  struct type *unqual = make_unqualified_type (type);
  gcc_type unqual_converted;
  gcc_qualifiers_flags quals = 0;

  unqual_converted = context->convert_type (unqual);

  if (TYPE_CONST (type))
    quals |= GCC_QUALIFIER_CONST;
  if (TYPE_VOLATILE (type))
    quals |= GCC_QUALIFIER_VOLATILE;
  if (TYPE_RESTRICT (type))
    quals |= GCC_QUALIFIER_RESTRICT;

  return context->plugin ().build_qualified_type (unqual_converted,
						  quals.raw ());
}

/* Convert a complex type to its gcc representation.  */

static gcc_type
convert_complex (compile_c_instance *context, struct type *type)
{
  gcc_type base = context->convert_type (TYPE_TARGET_TYPE (type));

  return context->plugin ().build_complex_type (base);
}

/* A helper function which knows how to convert most types from their
   gdb representation to the corresponding gcc form.  This examines
   the TYPE and dispatches to the appropriate conversion function.  It
   returns the gcc type.  */

static gcc_type
convert_type_basic (compile_c_instance *context, struct type *type)
{
  /* If we are converting a qualified type, first convert the
     unqualified type and then apply the qualifiers.  */
  if ((type->instance_flags () & (TYPE_INSTANCE_FLAG_CONST
				  | TYPE_INSTANCE_FLAG_VOLATILE
				  | TYPE_INSTANCE_FLAG_RESTRICT)) != 0)
    return convert_qualified (context, type);

  switch (type->code ())
    {
    case TYPE_CODE_PTR:
      return convert_pointer (context, type);

    case TYPE_CODE_ARRAY:
      return convert_array (context, type);

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      return convert_struct_or_union (context, type);

    case TYPE_CODE_ENUM:
      return convert_enum (context, type);

    case TYPE_CODE_FUNC:
      return convert_func (context, type);

    case TYPE_CODE_INT:
      return convert_int (context, type);

    case TYPE_CODE_FLT:
      return convert_float (context, type);

    case TYPE_CODE_VOID:
      return convert_void (context, type);

    case TYPE_CODE_BOOL:
      return convert_bool (context, type);

    case TYPE_CODE_COMPLEX:
      return convert_complex (context, type);

    case TYPE_CODE_ERROR:
      {
	/* Ideally, if we get here due to a cast expression, we'd use
	   the cast-to type as the variable's type, like GDB's
	   built-in parser does.  For now, assume "int" like GDB's
	   built-in parser used to do, but at least warn.  */
	struct type *fallback;
	if (type->is_objfile_owned ())
	  fallback = objfile_type (type->objfile_owner ())->builtin_int;
	else
	  fallback = builtin_type (type->arch_owner ())->builtin_int;
	warning (_("variable has unknown type; assuming int"));
	return convert_int (context, fallback);
      }
    }

  return context->plugin ().error (_("cannot convert gdb type to gcc type"));
}

/* Default compile flags for C.  */

const char *compile_c_instance::m_default_cflags = "-std=gnu11"
  /* Otherwise the .o file may need
     "_Unwind_Resume" and
     "__gcc_personality_v0".  */
  " -fno-exceptions"
  " -Wno-implicit-function-declaration";

/* See compile-c.h.  */

gcc_type
compile_c_instance::convert_type (struct type *type)
{
  /* We don't ever have to deal with typedefs in this code, because
     those are only needed as symbols by the C compiler.  */
  type = check_typedef (type);

  gcc_type result;
  if (get_cached_type (type, &result))
    return result;

  result = convert_type_basic (this, type);
  insert_type (type, result);
  return result;
}



/* C plug-in wrapper.  */

#define FORWARD(OP,...) m_context->c_ops->OP(m_context, ##__VA_ARGS__)
#define GCC_METHOD0(R, N) \
  R gcc_c_plugin::N () const \
  { return FORWARD (N); }
#define GCC_METHOD1(R, N, A) \
  R gcc_c_plugin::N (A a) const \
  { return FORWARD (N, a); }
#define GCC_METHOD2(R, N, A, B) \
  R gcc_c_plugin::N (A a, B b) const \
  { return FORWARD (N, a, b); }
#define GCC_METHOD3(R, N, A, B, C) \
  R gcc_c_plugin::N (A a, B b, C c)  const \
  { return FORWARD (N, a, b, c); }
#define GCC_METHOD4(R, N, A, B, C, D) \
  R gcc_c_plugin::N (A a, B b, C c, D d) const \
  { return FORWARD (N, a, b, c, d); }
#define GCC_METHOD5(R, N, A, B, C, D, E) \
  R gcc_c_plugin::N (A a, B b, C c, D d, E e) const \
  { return FORWARD (N, a, b, c, d, e); }
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
  R gcc_c_plugin::N (A a, B b, C c, D d, E e, F f, G g) const \
  { return FORWARD (N, a, b, c, d, e, f, g); }

#include "gcc-c-fe.def"

#undef GCC_METHOD0
#undef GCC_METHOD1
#undef GCC_METHOD2
#undef GCC_METHOD3
#undef GCC_METHOD4
#undef GCC_METHOD5
#undef GCC_METHOD7
#undef FORWARD
