/* Convert types from GDB to GCC

   Copyright (C) 2014-2020 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_VECTOR (type))
	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) == 0)
	count = -1;
      else
	{
	  gdb_assert (low_bound == 0); /* Ensured above.  */
	  count = high_bound + 1;
	}

      if (TYPE_VECTOR (type))
	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_NAME (type, i),
					  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_UNSIGNED (type),
					     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_NAME (type, i), 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_VARARGS (type) || !TYPE_PROTOTYPED (type);

  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_OBJFILE_OWNED (type))
	target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
      else
	target_type = builtin_type (TYPE_OWNER (type).gdbarch)->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 ();
  array.elements = XNEWVEC (gcc_type, type->num_fields ());
  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);
  xfree (array.elements);

  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_NOSIGN (type))
	{
	  gdb_assert (TYPE_LENGTH (type) == 1);
	  return context->plugin ().char_type ();
	}
      return context->plugin ().int_type (TYPE_UNSIGNED (type),
					  TYPE_LENGTH (type),
					  type->name ());
    }
  else
    return context->plugin ().int_type_v0 (TYPE_UNSIGNED (type),
					   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) & (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_OBJFILE_OWNED (type))
	  fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
	else
	  fallback = builtin_type (TYPE_OWNER (type).gdbarch)->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
