/* Scheme interface to types.

   Copyright (C) 2008-2016 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/>.  */

/* See README file in this directory for implementation notes, coding
   conventions, et.al.  */

#include "defs.h"
#include "arch-utils.h"
#include "value.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "language.h"
#include "vec.h"
#include "bcache.h"
#include "dwarf2loc.h"
#include "typeprint.h"
#include "guile-internal.h"

/* The <gdb:type> smob.
   The type is chained with all types associated with its objfile, if any.
   This lets us copy the underlying struct type when the objfile is
   deleted.
   The typedef for this struct is in guile-internal.h.  */

struct _type_smob
{
  /* This always appears first.
     eqable_gdb_smob is used so that types are eq?-able.
     Also, a type object can be associated with an objfile.  eqable_gdb_smob
     lets us track the lifetime of all types associated with an objfile.
     When an objfile is deleted we need to invalidate the type object.  */
  eqable_gdb_smob base;

  /* The GDB type structure this smob is wrapping.  */
  struct type *type;
};

/* A field smob.  */

typedef struct
{
  /* This always appears first.  */
  gdb_smob base;

  /* Backlink to the containing <gdb:type> object.  */
  SCM type_scm;

  /* The field number in TYPE_SCM.  */
  int field_num;
} field_smob;

static const char type_smob_name[] = "gdb:type";
static const char field_smob_name[] = "gdb:field";

static const char not_composite_error[] =
  N_("type is not a structure, union, or enum type");

/* The tag Guile knows the type smob by.  */
static scm_t_bits type_smob_tag;

/* The tag Guile knows the field smob by.  */
static scm_t_bits field_smob_tag;

/* The "next" procedure for field iterators.  */
static SCM tyscm_next_field_x_proc;

/* Keywords used in argument passing.  */
static SCM block_keyword;

static const struct objfile_data *tyscm_objfile_data_key;

/* Hash table to uniquify global (non-objfile-owned) types.  */
static htab_t global_types_map;

static struct type *tyscm_get_composite (struct type *type);

/* Return the type field of T_SMOB.
   This exists so that we don't have to export the struct's contents.  */

struct type *
tyscm_type_smob_type (type_smob *t_smob)
{
  return t_smob->type;
}

/* Return the name of TYPE in expanded form.
   Space for the result is malloc'd, caller must free.
   If there's an error computing the name, the result is NULL and the
   exception is stored in *EXCP.  */

static char *
tyscm_type_name (struct type *type, SCM *excp)
{
  char *name = NULL;

  TRY
    {
      struct cleanup *old_chain;
      struct ui_file *stb;

      stb = mem_fileopen ();
      old_chain = make_cleanup_ui_file_delete (stb);

      LA_PRINT_TYPE (type, "", stb, -1, 0, &type_print_raw_options);

      name = ui_file_xstrdup (stb, NULL);
      do_cleanups (old_chain);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      *excp = gdbscm_scm_from_gdb_exception (except);
      return NULL;
    }
  END_CATCH

  return name;
}

/* Administrivia for type smobs.  */

/* Helper function to hash a type_smob.  */

static hashval_t
tyscm_hash_type_smob (const void *p)
{
  const type_smob *t_smob = (const type_smob *) p;

  return htab_hash_pointer (t_smob->type);
}

/* Helper function to compute equality of type_smobs.  */

static int
tyscm_eq_type_smob (const void *ap, const void *bp)
{
  const type_smob *a = (const type_smob *) ap;
  const type_smob *b = (const type_smob *) bp;

  return (a->type == b->type
	  && a->type != NULL);
}

/* Return the struct type pointer -> SCM mapping table.
   If type is owned by an objfile, the mapping table is created if necessary.
   Otherwise, type is not owned by an objfile, and we use
   global_types_map.  */

static htab_t
tyscm_type_map (struct type *type)
{
  struct objfile *objfile = TYPE_OBJFILE (type);
  htab_t htab;

  if (objfile == NULL)
    return global_types_map;

  htab = (htab_t) objfile_data (objfile, tyscm_objfile_data_key);
  if (htab == NULL)
    {
      htab = gdbscm_create_eqable_gsmob_ptr_map (tyscm_hash_type_smob,
						 tyscm_eq_type_smob);
      set_objfile_data (objfile, tyscm_objfile_data_key, htab);
    }

  return htab;
}

/* The smob "free" function for <gdb:type>.  */

static size_t
tyscm_free_type_smob (SCM self)
{
  type_smob *t_smob = (type_smob *) SCM_SMOB_DATA (self);

  if (t_smob->type != NULL)
    {
      htab_t htab = tyscm_type_map (t_smob->type);

      gdbscm_clear_eqable_gsmob_ptr_slot (htab, &t_smob->base);
    }

  /* Not necessary, done to catch bugs.  */
  t_smob->type = NULL;

  return 0;
}

/* The smob "print" function for <gdb:type>.  */

static int
tyscm_print_type_smob (SCM self, SCM port, scm_print_state *pstate)
{
  type_smob *t_smob = (type_smob *) SCM_SMOB_DATA (self);
  SCM exception;
  char *name = tyscm_type_name (t_smob->type, &exception);

  if (name == NULL)
    gdbscm_throw (exception);

  /* pstate->writingp = zero if invoked by display/~A, and nonzero if
     invoked by write/~S.  What to do here may need to evolve.
     IWBN if we could pass an argument to format that would we could use
     instead of writingp.  */
  if (pstate->writingp)
    gdbscm_printf (port, "#<%s ", type_smob_name);

  scm_puts (name, port);

  if (pstate->writingp)
    scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* The smob "equal?" function for <gdb:type>.  */

static SCM
tyscm_equal_p_type_smob (SCM type1_scm, SCM type2_scm)
{
  type_smob *type1_smob, *type2_smob;
  struct type *type1, *type2;
  int result = 0;

  SCM_ASSERT_TYPE (tyscm_is_type (type1_scm), type1_scm, SCM_ARG1, FUNC_NAME,
		   type_smob_name);
  SCM_ASSERT_TYPE (tyscm_is_type (type2_scm), type2_scm, SCM_ARG2, FUNC_NAME,
		   type_smob_name);
  type1_smob = (type_smob *) SCM_SMOB_DATA (type1_scm);
  type2_smob = (type_smob *) SCM_SMOB_DATA (type2_scm);
  type1 = type1_smob->type;
  type2 = type2_smob->type;

  TRY
    {
      result = types_deeply_equal (type1, type2);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return scm_from_bool (result);
}

/* Low level routine to create a <gdb:type> object.  */

static SCM
tyscm_make_type_smob (void)
{
  type_smob *t_smob = (type_smob *)
    scm_gc_malloc (sizeof (type_smob), type_smob_name);
  SCM t_scm;

  /* This must be filled in by the caller.  */
  t_smob->type = NULL;

  t_scm = scm_new_smob (type_smob_tag, (scm_t_bits) t_smob);
  gdbscm_init_eqable_gsmob (&t_smob->base, t_scm);

  return t_scm;
}

/* Return non-zero if SCM is a <gdb:type> object.  */

int
tyscm_is_type (SCM self)
{
  return SCM_SMOB_PREDICATE (type_smob_tag, self);
}

/* (type? object) -> boolean */

static SCM
gdbscm_type_p (SCM self)
{
  return scm_from_bool (tyscm_is_type (self));
}

/* Return the existing object that encapsulates TYPE, or create a new
   <gdb:type> object.  */

SCM
tyscm_scm_from_type (struct type *type)
{
  htab_t htab;
  eqable_gdb_smob **slot;
  type_smob *t_smob, t_smob_for_lookup;
  SCM t_scm;

  /* If we've already created a gsmob for this type, return it.
     This makes types eq?-able.  */
  htab = tyscm_type_map (type);
  t_smob_for_lookup.type = type;
  slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &t_smob_for_lookup.base);
  if (*slot != NULL)
    return (*slot)->containing_scm;

  t_scm = tyscm_make_type_smob ();
  t_smob = (type_smob *) SCM_SMOB_DATA (t_scm);
  t_smob->type = type;
  gdbscm_fill_eqable_gsmob_ptr_slot (slot, &t_smob->base);

  return t_scm;
}

/* Returns the <gdb:type> object in SELF.
   Throws an exception if SELF is not a <gdb:type> object.  */

static SCM
tyscm_get_type_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (tyscm_is_type (self), self, arg_pos, func_name,
		   type_smob_name);

  return self;
}

/* Returns a pointer to the type smob of SELF.
   Throws an exception if SELF is not a <gdb:type> object.  */

type_smob *
tyscm_get_type_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM t_scm = tyscm_get_type_arg_unsafe (self, arg_pos, func_name);
  type_smob *t_smob = (type_smob *) SCM_SMOB_DATA (t_scm);

  return t_smob;
}

/* Helper function for save_objfile_types to make a deep copy of the type.  */

static int
tyscm_copy_type_recursive (void **slot, void *info)
{
  type_smob *t_smob = (type_smob *) *slot;
  htab_t copied_types = (htab_t) info;
  struct objfile *objfile = TYPE_OBJFILE (t_smob->type);
  htab_t htab;
  eqable_gdb_smob **new_slot;
  type_smob t_smob_for_lookup;

  gdb_assert (objfile != NULL);

  htab_empty (copied_types);
  t_smob->type = copy_type_recursive (objfile, t_smob->type, copied_types);

  /* The eq?-hashtab that the type lived in is going away.
     Add the type to its new eq?-hashtab: Otherwise if/when the type is later
     garbage collected we'll assert-fail if the type isn't in the hashtab.
     PR 16612.

     Types now live in "arch space", and things like "char" that came from
     the objfile *could* be considered eq? with the arch "char" type.
     However, they weren't before the objfile got deleted, so making them
     eq? now is debatable.  */
  htab = tyscm_type_map (t_smob->type);
  t_smob_for_lookup.type = t_smob->type;
  new_slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &t_smob_for_lookup.base);
  gdb_assert (*new_slot == NULL);
  gdbscm_fill_eqable_gsmob_ptr_slot (new_slot, &t_smob->base);

  return 1;
}

/* Called when OBJFILE is about to be deleted.
   Make a copy of all types associated with OBJFILE.  */

static void
save_objfile_types (struct objfile *objfile, void *datum)
{
  htab_t htab = (htab_t) datum;
  htab_t copied_types;

  if (!gdb_scheme_initialized)
    return;

  copied_types = create_copied_types_hash (objfile);

  if (htab != NULL)
    {
      htab_traverse_noresize (htab, tyscm_copy_type_recursive, copied_types);
      htab_delete (htab);
    }

  htab_delete (copied_types);
}

/* Administrivia for field smobs.  */

/* The smob "print" function for <gdb:field>.  */

static int
tyscm_print_field_smob (SCM self, SCM port, scm_print_state *pstate)
{
  field_smob *f_smob = (field_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s ", field_smob_name);
  scm_write (f_smob->type_scm, port);
  gdbscm_printf (port, " %d", f_smob->field_num);
  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* Low level routine to create a <gdb:field> object for field FIELD_NUM
   of type TYPE_SCM.  */

static SCM
tyscm_make_field_smob (SCM type_scm, int field_num)
{
  field_smob *f_smob = (field_smob *)
    scm_gc_malloc (sizeof (field_smob), field_smob_name);
  SCM result;

  f_smob->type_scm = type_scm;
  f_smob->field_num = field_num;
  result = scm_new_smob (field_smob_tag, (scm_t_bits) f_smob);
  gdbscm_init_gsmob (&f_smob->base);

  return result;
}

/* Return non-zero if SCM is a <gdb:field> object.  */

static int
tyscm_is_field (SCM self)
{
  return SCM_SMOB_PREDICATE (field_smob_tag, self);
}

/* (field? object) -> boolean */

static SCM
gdbscm_field_p (SCM self)
{
  return scm_from_bool (tyscm_is_field (self));
}

/* Create a new <gdb:field> object that encapsulates field FIELD_NUM
   in type TYPE_SCM.  */

SCM
tyscm_scm_from_field (SCM type_scm, int field_num)
{
  return tyscm_make_field_smob (type_scm, field_num);
}

/* Returns the <gdb:field> object in SELF.
   Throws an exception if SELF is not a <gdb:field> object.  */

static SCM
tyscm_get_field_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (tyscm_is_field (self), self, arg_pos, func_name,
		   field_smob_name);

  return self;
}

/* Returns a pointer to the field smob of SELF.
   Throws an exception if SELF is not a <gdb:field> object.  */

static field_smob *
tyscm_get_field_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM f_scm = tyscm_get_field_arg_unsafe (self, arg_pos, func_name);
  field_smob *f_smob = (field_smob *) SCM_SMOB_DATA (f_scm);

  return f_smob;
}

/* Returns a pointer to the type struct in F_SMOB
   (the type the field is in).  */

static struct type *
tyscm_field_smob_containing_type (field_smob *f_smob)
{
  type_smob *t_smob;

  gdb_assert (tyscm_is_type (f_smob->type_scm));
  t_smob = (type_smob *) SCM_SMOB_DATA (f_smob->type_scm);

  return t_smob->type;
}

/* Returns a pointer to the field struct of F_SMOB.  */

static struct field *
tyscm_field_smob_to_field (field_smob *f_smob)
{
  struct type *type = tyscm_field_smob_containing_type (f_smob);

  /* This should be non-NULL by construction.  */
  gdb_assert (TYPE_FIELDS (type) != NULL);

  return &TYPE_FIELD (type, f_smob->field_num);
}

/* Type smob accessors.  */

/* (type-code <gdb:type>) -> integer
   Return the code for this type.  */

static SCM
gdbscm_type_code (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  return scm_from_int (TYPE_CODE (type));
}

/* (type-fields <gdb:type>) -> list
   Return a list of all fields.  Each element is a <gdb:field> object.
   This also supports arrays, we return a field list of one element,
   the range type.  */

static SCM
gdbscm_type_fields (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  struct type *containing_type;
  SCM containing_type_scm, result;
  int i;

  containing_type = tyscm_get_composite (type);
  if (containing_type == NULL)
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _(not_composite_error));

  /* If SELF is a typedef or reference, we want the underlying type,
     which is what tyscm_get_composite returns.  */
  if (containing_type == type)
    containing_type_scm = self;
  else
    containing_type_scm = tyscm_scm_from_type (containing_type);

  result = SCM_EOL;
  for (i = 0; i < TYPE_NFIELDS (containing_type); ++i)
    result = scm_cons (tyscm_make_field_smob (containing_type_scm, i), result);

  return scm_reverse_x (result, SCM_EOL);
}

/* (type-tag <gdb:type>) -> string
   Return the type's tag, or #f.  */

static SCM
gdbscm_type_tag (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  if (!TYPE_TAG_NAME (type))
    return SCM_BOOL_F;
  return gdbscm_scm_from_c_string (TYPE_TAG_NAME (type));
}

/* (type-name <gdb:type>) -> string
   Return the type's name, or #f.  */

static SCM
gdbscm_type_name (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  if (!TYPE_NAME (type))
    return SCM_BOOL_F;
  return gdbscm_scm_from_c_string (TYPE_NAME (type));
}

/* (type-print-name <gdb:type>) -> string
   Return the print name of type.
   TODO: template support elided for now.  */

static SCM
gdbscm_type_print_name (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  char *thetype;
  SCM exception, result;

  thetype = tyscm_type_name (type, &exception);

  if (thetype == NULL)
    gdbscm_throw (exception);

  result = gdbscm_scm_from_c_string (thetype);
  xfree (thetype);

  return result;
}

/* (type-sizeof <gdb:type>) -> integer
   Return the size of the type represented by SELF, in bytes.  */

static SCM
gdbscm_type_sizeof (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      check_typedef (type);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
    }
  END_CATCH

  /* Ignore exceptions.  */

  return scm_from_long (TYPE_LENGTH (type));
}

/* (type-strip-typedefs <gdb:type>) -> <gdb:type>
   Return the type, stripped of typedefs. */

static SCM
gdbscm_type_strip_typedefs (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = check_typedef (type);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* Strip typedefs and pointers/reference from a type.  Then check that
   it is a struct, union, or enum type.  If not, return NULL.  */

static struct type *
tyscm_get_composite (struct type *type)
{

  for (;;)
    {
      TRY
	{
	  type = check_typedef (type);
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  GDBSCM_HANDLE_GDB_EXCEPTION (except);
	}
      END_CATCH

      if (TYPE_CODE (type) != TYPE_CODE_PTR
	  && TYPE_CODE (type) != TYPE_CODE_REF)
	break;
      type = TYPE_TARGET_TYPE (type);
    }

  /* If this is not a struct, union, or enum type, raise TypeError
     exception.  */
  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
      && TYPE_CODE (type) != TYPE_CODE_UNION
      && TYPE_CODE (type) != TYPE_CODE_ENUM)
    return NULL;

  return type;
}

/* Helper for tyscm_array and tyscm_vector.  */

static SCM
tyscm_array_1 (SCM self, SCM n1_scm, SCM n2_scm, int is_vector,
	       const char *func_name)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, func_name);
  struct type *type = t_smob->type;
  long n1, n2 = 0;
  struct type *array = NULL;

  gdbscm_parse_function_args (func_name, SCM_ARG2, NULL, "l|l",
			      n1_scm, &n1, n2_scm, &n2);

  if (SCM_UNBNDP (n2_scm))
    {
      n2 = n1;
      n1 = 0;
    }

  if (n2 < n1 - 1) /* Note: An empty array has n2 == n1 - 1.  */
    {
      gdbscm_out_of_range_error (func_name, SCM_ARG3,
				 scm_cons (scm_from_long (n1),
					   scm_from_long (n2)),
				 _("Array length must not be negative"));
    }

  TRY
    {
      array = lookup_array_range_type (type, n1, n2);
      if (is_vector)
	make_vector_type (array);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (array);
}

/* (type-array <gdb:type> [low-bound] high-bound) -> <gdb:type>
   The array has indices [low-bound,high-bound].
   If low-bound is not provided zero is used.
   Return an array type.

   IWBN if the one argument version specified a size, not the high bound.
   It's too easy to pass one argument thinking it is the size of the array.
   The current semantics are for compatibility with the Python version.
   Later we can add #:size.  */

static SCM
gdbscm_type_array (SCM self, SCM n1, SCM n2)
{
  return tyscm_array_1 (self, n1, n2, 0, FUNC_NAME);
}

/* (type-vector <gdb:type> [low-bound] high-bound) -> <gdb:type>
   The array has indices [low-bound,high-bound].
   If low-bound is not provided zero is used.
   Return a vector type.

   IWBN if the one argument version specified a size, not the high bound.
   It's too easy to pass one argument thinking it is the size of the array.
   The current semantics are for compatibility with the Python version.
   Later we can add #:size.  */

static SCM
gdbscm_type_vector (SCM self, SCM n1, SCM n2)
{
  return tyscm_array_1 (self, n1, n2, 1, FUNC_NAME);
}

/* (type-pointer <gdb:type>) -> <gdb:type>
   Return a <gdb:type> object which represents a pointer to SELF.  */

static SCM
gdbscm_type_pointer (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = lookup_pointer_type (type);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* (type-range <gdb:type>) -> (low high)
   Return the range of a type represented by SELF.  The return type is
   a list.  The first element is the low bound, and the second element
   is the high bound.  */

static SCM
gdbscm_type_range (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  SCM low_scm, high_scm;
  /* Initialize these to appease GCC warnings.  */
  LONGEST low = 0, high = 0;

  SCM_ASSERT_TYPE (TYPE_CODE (type) == TYPE_CODE_ARRAY
		   || TYPE_CODE (type) == TYPE_CODE_STRING
		   || TYPE_CODE (type) == TYPE_CODE_RANGE,
		   self, SCM_ARG1, FUNC_NAME, _("ranged type"));

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_STRING:
      low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
      high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type));
      break;
    case TYPE_CODE_RANGE:
      low = TYPE_LOW_BOUND (type);
      high = TYPE_HIGH_BOUND (type);
      break;
    }

  low_scm = gdbscm_scm_from_longest (low);
  high_scm = gdbscm_scm_from_longest (high);

  return scm_list_2 (low_scm, high_scm);
}

/* (type-reference <gdb:type>) -> <gdb:type>
   Return a <gdb:type> object which represents a reference to SELF.  */

static SCM
gdbscm_type_reference (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = lookup_reference_type (type);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* (type-target <gdb:type>) -> <gdb:type>
   Return a <gdb:type> object which represents the target type of SELF.  */

static SCM
gdbscm_type_target (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  SCM_ASSERT (TYPE_TARGET_TYPE (type), self, SCM_ARG1, FUNC_NAME);

  return tyscm_scm_from_type (TYPE_TARGET_TYPE (type));
}

/* (type-const <gdb:type>) -> <gdb:type>
   Return a const-qualified type variant.  */

static SCM
gdbscm_type_const (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = make_cv_type (1, 0, type, NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* (type-volatile <gdb:type>) -> <gdb:type>
   Return a volatile-qualified type variant.  */

static SCM
gdbscm_type_volatile (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = make_cv_type (0, 1, type, NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* (type-unqualified <gdb:type>) -> <gdb:type>
   Return an unqualified type variant.  */

static SCM
gdbscm_type_unqualified (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  TRY
    {
      type = make_cv_type (0, 0, type, NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
  END_CATCH

  return tyscm_scm_from_type (type);
}

/* Field related accessors of types.  */

/* (type-num-fields <gdb:type>) -> integer
   Return number of fields.  */

static SCM
gdbscm_type_num_fields (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;

  type = tyscm_get_composite (type);
  if (type == NULL)
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _(not_composite_error));

  return scm_from_long (TYPE_NFIELDS (type));
}

/* (type-field <gdb:type> string) -> <gdb:field>
   Return the <gdb:field> object for the field named by the argument.  */

static SCM
gdbscm_type_field (SCM self, SCM field_scm)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  char *field;
  int i;
  struct cleanup *cleanups;

  SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
		   _("string"));

  /* We want just fields of this type, not of base types, so instead of
     using lookup_struct_elt_type, portions of that function are
     copied here.  */

  type = tyscm_get_composite (type);
  if (type == NULL)
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _(not_composite_error));

  field = gdbscm_scm_to_c_string (field_scm);
  cleanups = make_cleanup (xfree, field);

  for (i = 0; i < TYPE_NFIELDS (type); i++)
    {
      const char *t_field_name = TYPE_FIELD_NAME (type, i);

      if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
	{
	    do_cleanups (cleanups);
	    return tyscm_make_field_smob (self, i);
	}
    }

  do_cleanups (cleanups);

  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, field_scm,
			     _("Unknown field"));
}

/* (type-has-field? <gdb:type> string) -> boolean
   Return boolean indicating if type SELF has FIELD_SCM (a string).  */

static SCM
gdbscm_type_has_field_p (SCM self, SCM field_scm)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  char *field;
  int i;
  struct cleanup *cleanups;

  SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
		   _("string"));

  /* We want just fields of this type, not of base types, so instead of
     using lookup_struct_elt_type, portions of that function are
     copied here.  */

  type = tyscm_get_composite (type);
  if (type == NULL)
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _(not_composite_error));

  field = gdbscm_scm_to_c_string (field_scm);
  cleanups = make_cleanup (xfree, field);

  for (i = 0; i < TYPE_NFIELDS (type); i++)
    {
      const char *t_field_name = TYPE_FIELD_NAME (type, i);

      if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
	{
	    do_cleanups (cleanups);
	    return SCM_BOOL_T;
	}
    }

  do_cleanups (cleanups);

  return SCM_BOOL_F;
}

/* (make-field-iterator <gdb:type>) -> <gdb:iterator>
   Make a field iterator object.  */

static SCM
gdbscm_make_field_iterator (SCM self)
{
  type_smob *t_smob
    = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct type *type = t_smob->type;
  struct type *containing_type;
  SCM containing_type_scm;

  containing_type = tyscm_get_composite (type);
  if (containing_type == NULL)
    gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
			       _(not_composite_error));

  /* If SELF is a typedef or reference, we want the underlying type,
     which is what tyscm_get_composite returns.  */
  if (containing_type == type)
    containing_type_scm = self;
  else
    containing_type_scm = tyscm_scm_from_type (containing_type);

  return gdbscm_make_iterator (containing_type_scm, scm_from_int (0),
			       tyscm_next_field_x_proc);
}

/* (type-next-field! <gdb:iterator>) -> <gdb:field>
   Return the next field in the iteration through the list of fields of the
   type, or (end-of-iteration).
   SELF is a <gdb:iterator> object created by gdbscm_make_field_iterator.
   This is the next! <gdb:iterator> function, not exported to the user.  */

static SCM
gdbscm_type_next_field_x (SCM self)
{
  iterator_smob *i_smob;
  type_smob *t_smob;
  struct type *type;
  SCM it_scm, result, progress, object;
  int field, rc;

  it_scm = itscm_get_iterator_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  i_smob = (iterator_smob *) SCM_SMOB_DATA (it_scm);
  object = itscm_iterator_smob_object (i_smob);
  progress = itscm_iterator_smob_progress (i_smob);

  SCM_ASSERT_TYPE (tyscm_is_type (object), object,
		   SCM_ARG1, FUNC_NAME, type_smob_name);
  t_smob = (type_smob *) SCM_SMOB_DATA (object);
  type = t_smob->type;

  SCM_ASSERT_TYPE (scm_is_signed_integer (progress,
					  0, TYPE_NFIELDS (type)),
		   progress, SCM_ARG1, FUNC_NAME, _("integer"));
  field = scm_to_int (progress);

  if (field < TYPE_NFIELDS (type))
    {
      result = tyscm_make_field_smob (object, field);
      itscm_set_iterator_smob_progress_x (i_smob, scm_from_int (field + 1));
      return result;
    }

  return gdbscm_end_of_iteration ();
}

/* Field smob accessors.  */

/* (field-name <gdb:field>) -> string
   Return the name of this field or #f if there isn't one.  */

static SCM
gdbscm_field_name (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);

  if (FIELD_NAME (*field))
    return gdbscm_scm_from_c_string (FIELD_NAME (*field));
  return SCM_BOOL_F;
}

/* (field-type <gdb:field>) -> <gdb:type>
   Return the <gdb:type> object of the field or #f if there isn't one.  */

static SCM
gdbscm_field_type (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);

  /* A field can have a NULL type in some situations.  */
  if (FIELD_TYPE (*field))
    return tyscm_scm_from_type (FIELD_TYPE (*field));
  return SCM_BOOL_F;
}

/* (field-enumval <gdb:field>) -> integer
   For enum values, return its value as an integer.  */

static SCM
gdbscm_field_enumval (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);
  struct type *type = tyscm_field_smob_containing_type (f_smob);

  SCM_ASSERT_TYPE (TYPE_CODE (type) == TYPE_CODE_ENUM,
		   self, SCM_ARG1, FUNC_NAME, _("enum type"));

  return scm_from_long (FIELD_ENUMVAL (*field));
}

/* (field-bitpos <gdb:field>) -> integer
   For bitfields, return its offset in bits.  */

static SCM
gdbscm_field_bitpos (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);
  struct type *type = tyscm_field_smob_containing_type (f_smob);

  SCM_ASSERT_TYPE (TYPE_CODE (type) != TYPE_CODE_ENUM,
		   self, SCM_ARG1, FUNC_NAME, _("non-enum type"));

  return scm_from_long (FIELD_BITPOS (*field));
}

/* (field-bitsize <gdb:field>) -> integer
   Return the size of the field in bits.  */

static SCM
gdbscm_field_bitsize (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);

  return scm_from_long (FIELD_BITPOS (*field));
}

/* (field-artificial? <gdb:field>) -> boolean
   Return #t if field is artificial.  */

static SCM
gdbscm_field_artificial_p (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);

  return scm_from_bool (FIELD_ARTIFICIAL (*field));
}

/* (field-baseclass? <gdb:field>) -> boolean
   Return #t if field is a baseclass.  */

static SCM
gdbscm_field_baseclass_p (SCM self)
{
  field_smob *f_smob
    = tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct field *field = tyscm_field_smob_to_field (f_smob);
  struct type *type = tyscm_field_smob_containing_type (f_smob);

  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
    return scm_from_bool (f_smob->field_num < TYPE_N_BASECLASSES (type));
  return SCM_BOOL_F;
}

/* Return the type named TYPE_NAME in BLOCK.
   Returns NULL if not found.
   This routine does not throw an error.  */

static struct type *
tyscm_lookup_typename (const char *type_name, const struct block *block)
{
  struct type *type = NULL;

  TRY
    {
      if (startswith (type_name, "struct "))
	type = lookup_struct (type_name + 7, NULL);
      else if (startswith (type_name, "union "))
	type = lookup_union (type_name + 6, NULL);
      else if (startswith (type_name, "enum "))
	type = lookup_enum (type_name + 5, NULL);
      else
	type = lookup_typename (current_language, get_current_arch (),
				type_name, block, 0);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      return NULL;
    }
  END_CATCH

  return type;
}

/* (lookup-type name [#:block <gdb:block>]) -> <gdb:type>
   TODO: legacy template support left out until needed.  */

static SCM
gdbscm_lookup_type (SCM name_scm, SCM rest)
{
  SCM keywords[] = { block_keyword, SCM_BOOL_F };
  char *name;
  SCM block_scm = SCM_BOOL_F;
  int block_arg_pos = -1;
  const struct block *block = NULL;
  struct type *type;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#O",
			      name_scm, &name,
			      rest, &block_arg_pos, &block_scm);

  if (block_arg_pos != -1)
    {
      SCM exception;

      block = bkscm_scm_to_block (block_scm, block_arg_pos, FUNC_NAME,
				  &exception);
      if (block == NULL)
	{
	  xfree (name);
	  gdbscm_throw (exception);
	}
    }
  type = tyscm_lookup_typename (name, block);
  xfree (name);

  if (type != NULL)
    return tyscm_scm_from_type (type);
  return SCM_BOOL_F;
}

/* Initialize the Scheme type code.  */


static const scheme_integer_constant type_integer_constants[] =
{
#define X(SYM) { #SYM, SYM }
  X (TYPE_CODE_BITSTRING),
  X (TYPE_CODE_PTR),
  X (TYPE_CODE_ARRAY),
  X (TYPE_CODE_STRUCT),
  X (TYPE_CODE_UNION),
  X (TYPE_CODE_ENUM),
  X (TYPE_CODE_FLAGS),
  X (TYPE_CODE_FUNC),
  X (TYPE_CODE_INT),
  X (TYPE_CODE_FLT),
  X (TYPE_CODE_VOID),
  X (TYPE_CODE_SET),
  X (TYPE_CODE_RANGE),
  X (TYPE_CODE_STRING),
  X (TYPE_CODE_ERROR),
  X (TYPE_CODE_METHOD),
  X (TYPE_CODE_METHODPTR),
  X (TYPE_CODE_MEMBERPTR),
  X (TYPE_CODE_REF),
  X (TYPE_CODE_CHAR),
  X (TYPE_CODE_BOOL),
  X (TYPE_CODE_COMPLEX),
  X (TYPE_CODE_TYPEDEF),
  X (TYPE_CODE_NAMESPACE),
  X (TYPE_CODE_DECFLOAT),
  X (TYPE_CODE_INTERNAL_FUNCTION),
#undef X

  END_INTEGER_CONSTANTS
};

static const scheme_function type_functions[] =
{
  { "type?", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_p),
    "\
Return #t if the object is a <gdb:type> object." },

  { "lookup-type", 1, 0, 1, as_a_scm_t_subr (gdbscm_lookup_type),
    "\
Return the <gdb:type> object representing string or #f if not found.\n\
If block is given then the type is looked for in that block.\n\
\n\
  Arguments: string [#:block <gdb:block>]" },

  { "type-code", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_code),
    "\
Return the code of the type" },

  { "type-tag", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_tag),
    "\
Return the tag name of the type, or #f if there isn't one." },

  { "type-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_name),
    "\
Return the name of the type as a string, or #f if there isn't one." },

  { "type-print-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_print_name),
    "\
Return the print name of the type as a string." },

  { "type-sizeof", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_sizeof),
    "\
Return the size of the type, in bytes." },

  { "type-strip-typedefs", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_type_strip_typedefs),
    "\
Return a type formed by stripping the type of all typedefs." },

  { "type-array", 2, 1, 0, as_a_scm_t_subr (gdbscm_type_array),
    "\
Return a type representing an array of objects of the type.\n\
\n\
  Arguments: <gdb:type> [low-bound] high-bound\n\
    If low-bound is not provided zero is used.\n\
    N.B. If only the high-bound parameter is specified, it is not\n\
    the array size.\n\
    Valid bounds for array indices are [low-bound,high-bound]." },

  { "type-vector", 2, 1, 0, as_a_scm_t_subr (gdbscm_type_vector),
    "\
Return a type representing a vector of objects of the type.\n\
Vectors differ from arrays in that if the current language has C-style\n\
arrays, vectors don't decay to a pointer to the first element.\n\
They are first class values.\n\
\n\
  Arguments: <gdb:type> [low-bound] high-bound\n\
    If low-bound is not provided zero is used.\n\
    N.B. If only the high-bound parameter is specified, it is not\n\
    the array size.\n\
    Valid bounds for array indices are [low-bound,high-bound]." },

  { "type-pointer", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_pointer),
    "\
Return a type of pointer to the type." },

  { "type-range", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_range),
    "\
Return (low high) representing the range for the type." },

  { "type-reference", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_reference),
    "\
Return a type of reference to the type." },

  { "type-target", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_target),
    "\
Return the target type of the type." },

  { "type-const", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_const),
    "\
Return a const variant of the type." },

  { "type-volatile", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_volatile),
    "\
Return a volatile variant of the type." },

  { "type-unqualified", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_unqualified),
    "\
Return a variant of the type without const or volatile attributes." },

  { "type-num-fields", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_num_fields),
    "\
Return the number of fields of the type." },

  { "type-fields", 1, 0, 0, as_a_scm_t_subr (gdbscm_type_fields),
    "\
Return the list of <gdb:field> objects of fields of the type." },

  { "make-field-iterator", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_make_field_iterator),
    "\
Return a <gdb:iterator> object for iterating over the fields of the type." },

  { "type-field", 2, 0, 0, as_a_scm_t_subr (gdbscm_type_field),
    "\
Return the field named by string of the type.\n\
\n\
  Arguments: <gdb:type> string" },

  { "type-has-field?", 2, 0, 0, as_a_scm_t_subr (gdbscm_type_has_field_p),
    "\
Return #t if the type has field named string.\n\
\n\
  Arguments: <gdb:type> string" },

  { "field?", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_p),
    "\
Return #t if the object is a <gdb:field> object." },

  { "field-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_name),
    "\
Return the name of the field." },

  { "field-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_type),
    "\
Return the type of the field." },

  { "field-enumval", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_enumval),
    "\
Return the enum value represented by the field." },

  { "field-bitpos", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_bitpos),
    "\
Return the offset in bits of the field in its containing type." },

  { "field-bitsize", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_bitsize),
    "\
Return the size of the field in bits." },

  { "field-artificial?", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_artificial_p),
    "\
Return #t if the field is artificial." },

  { "field-baseclass?", 1, 0, 0, as_a_scm_t_subr (gdbscm_field_baseclass_p),
    "\
Return #t if the field is a baseclass." },

  END_FUNCTIONS
};

void
gdbscm_initialize_types (void)
{
  type_smob_tag = gdbscm_make_smob_type (type_smob_name, sizeof (type_smob));
  scm_set_smob_free (type_smob_tag, tyscm_free_type_smob);
  scm_set_smob_print (type_smob_tag, tyscm_print_type_smob);
  scm_set_smob_equalp (type_smob_tag, tyscm_equal_p_type_smob);

  field_smob_tag = gdbscm_make_smob_type (field_smob_name,
					  sizeof (field_smob));
  scm_set_smob_print (field_smob_tag, tyscm_print_field_smob);

  gdbscm_define_integer_constants (type_integer_constants, 1);
  gdbscm_define_functions (type_functions, 1);

  /* This function is "private".  */
  tyscm_next_field_x_proc
    = scm_c_define_gsubr ("%type-next-field!", 1, 0, 0,
			  as_a_scm_t_subr (gdbscm_type_next_field_x));
  scm_set_procedure_property_x (tyscm_next_field_x_proc,
				gdbscm_documentation_symbol,
				gdbscm_scm_from_c_string ("\
Internal function to assist the type fields iterator."));

  block_keyword = scm_from_latin1_keyword ("block");

  /* Register an objfile "free" callback so we can properly copy types
     associated with the objfile when it's about to be deleted.  */
  tyscm_objfile_data_key
    = register_objfile_data_with_cleanup (save_objfile_types, NULL);

  global_types_map = gdbscm_create_eqable_gsmob_ptr_map (tyscm_hash_type_smob,
							 tyscm_eq_type_smob);
}
