/* Convert types from GDB to GCC

   Copyright (C) 2014-2015 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 "gdb_assert.h"

/* An object that maps a gdb type to a gcc type.  */

struct type_map_instance
{
  /* The gdb type.  */

  struct type *type;

  /* The corresponding gcc type handle.  */

  gcc_type gcc_type;
};

/* Hash a type_map_instance.  */

static hashval_t
hash_type_map_instance (const void *p)
{
  const struct type_map_instance *inst = p;

  return htab_hash_pointer (inst->type);
}

/* Check two type_map_instance objects for equality.  */

static int
eq_type_map_instance (const void *a, const void *b)
{
  const struct type_map_instance *insta = a;
  const struct type_map_instance *instb = b;

  return insta->type == instb->type;
}



/* Insert an entry into the type map associated with CONTEXT that maps
   from the gdb type TYPE to the gcc type GCC_TYPE.  It is ok for a
   given type to be inserted more than once, provided that the exact
   same association is made each time.  This simplifies how type
   caching works elsewhere in this file -- see how struct type caching
   is handled.  */

static void
insert_type (struct compile_c_instance *context, struct type *type,
	     gcc_type gcc_type)
{
  struct type_map_instance inst, *add;
  void **slot;

  inst.type = type;
  inst.gcc_type = gcc_type;
  slot = htab_find_slot (context->type_map, &inst, INSERT);

  add = *slot;
  /* The type might have already been inserted in order to handle
     recursive types.  */
  gdb_assert (add == NULL || add->gcc_type == gcc_type);

  if (add == NULL)
    {
      add = XNEW (struct type_map_instance);
      *add = inst;
      *slot = add;
    }
}

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

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

  return C_CTX (context)->c_ops->build_pointer_type (C_CTX (context),
						     target);
}

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

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

  element_type = convert_type (context, TYPE_TARGET_TYPE (type));

  if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST)
    return C_CTX (context)->c_ops->error (C_CTX (context),
					  _("array type with non-constant"
					    " lower bound is not supported"));
  if (TYPE_LOW_BOUND (range) != 0)
    return C_CTX (context)->c_ops->error (C_CTX (context),
					  _("cannot convert array type with "
					    "non-zero lower bound to C"));

  if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR
      || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST)
    {
      gcc_type result;
      char *upper_bound;

      if (TYPE_VECTOR (type))
	return C_CTX (context)->c_ops->error (C_CTX (context),
					      _("variably-sized vector type"
						" is not supported"));

      upper_bound = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high);
      result = C_CTX (context)->c_ops->build_vla_array_type (C_CTX (context),
							     element_type,
							     upper_bound);
      xfree (upper_bound);
      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 C_CTX (context)->c_ops->build_vector_type (C_CTX (context),
							  element_type,
							  count);
      return C_CTX (context)->c_ops->build_array_type (C_CTX (context),
						       element_type, count);
    }
}

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

static gcc_type
convert_struct_or_union (struct 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) == TYPE_CODE_STRUCT)
    result = C_CTX (context)->c_ops->build_record_type (C_CTX (context));
  else
    {
      gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
      result = C_CTX (context)->c_ops->build_union_type (C_CTX (context));
    }
  insert_type (context, type, result);

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

      field_type = convert_type (context, TYPE_FIELD_TYPE (type, i));
      if (bitsize == 0)
	bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i));
      C_CTX (context)->c_ops->build_add_field (C_CTX (context), result,
					       TYPE_FIELD_NAME (type, i),
					       field_type,
					       bitsize,
					       TYPE_FIELD_BITPOS (type, i));
    }

  C_CTX (context)->c_ops->finish_record_or_union (C_CTX (context), result,
						  TYPE_LENGTH (type));
  return result;
}

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

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

  int_type = ctx->c_ops->int_type (ctx,
				   TYPE_UNSIGNED (type),
				   TYPE_LENGTH (type));

  result = ctx->c_ops->build_enum_type (ctx, int_type);
  for (i = 0; i < TYPE_NFIELDS (type); ++i)
    {
      ctx->c_ops->build_add_enum_constant (ctx,
					   result,
					   TYPE_FIELD_NAME (type, i),
					   TYPE_FIELD_ENUMVAL (type, i));
    }

  ctx->c_ops->finish_enum_type (ctx, result);

  return result;
}

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

static gcc_type
convert_func (struct 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);

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

  array.n_elements = TYPE_NFIELDS (type);
  array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type));
  for (i = 0; i < TYPE_NFIELDS (type); ++i)
    array.elements[i] = convert_type (context, TYPE_FIELD_TYPE (type, i));

  result = C_CTX (context)->c_ops->build_function_type (C_CTX (context),
							return_type,
							&array, is_varargs);
  xfree (array.elements);

  return result;
}

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

static gcc_type
convert_int (struct compile_c_instance *context, struct type *type)
{
  return C_CTX (context)->c_ops->int_type (C_CTX (context),
					   TYPE_UNSIGNED (type),
					   TYPE_LENGTH (type));
}

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

static gcc_type
convert_float (struct compile_c_instance *context, struct type *type)
{
  return C_CTX (context)->c_ops->float_type (C_CTX (context),
					     TYPE_LENGTH (type));
}

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

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

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

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

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

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

  unqual_converted = convert_type (context, 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 C_CTX (context)->c_ops->build_qualified_type (C_CTX (context),
						       unqual_converted,
						       quals);
}

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

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

  return C_CTX (context)->c_ops->build_complex_type (C_CTX (context), 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 (struct 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 (type))
    {
    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);
    }

  return C_CTX (context)->c_ops->error (C_CTX (context),
					_("cannot convert gdb type "
					  "to gcc type"));
}

/* See compile-internal.h.  */

gcc_type
convert_type (struct compile_c_instance *context, struct type *type)
{
  struct type_map_instance inst, *found;
  gcc_type result;

  /* We don't ever have to deal with typedefs in this code, because
     those are only needed as symbols by the C compiler.  */
  CHECK_TYPEDEF (type);

  inst.type = type;
  found = htab_find (context->type_map, &inst);
  if (found != NULL)
    return found->gcc_type;

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



/* Delete the compiler instance C.  */

static void
delete_instance (struct compile_instance *c)
{
  struct compile_c_instance *context = (struct compile_c_instance *) c;

  context->base.fe->ops->destroy (context->base.fe);
  htab_delete (context->type_map);
  if (context->symbol_err_map != NULL)
    htab_delete (context->symbol_err_map);
  xfree (context);
}

/* See compile-internal.h.  */

struct compile_instance *
new_compile_instance (struct gcc_c_context *fe)
{
  struct compile_c_instance *result = XCNEW (struct compile_c_instance);

  result->base.fe = &fe->base;
  result->base.destroy = delete_instance;
  result->base.gcc_target_options = ("-std=gnu11"
				     /* Otherwise the .o file may need
					"_Unwind_Resume" and
					"__gcc_personality_v0".  */
				     " -fno-exceptions");

  result->type_map = htab_create_alloc (10, hash_type_map_instance,
					eq_type_map_instance,
					xfree, xcalloc, xfree);

  fe->c_ops->set_callbacks (fe, gcc_convert_symbol,
			    gcc_symbol_address, result);

  return &result->base;
}
