/* Support for printing C++ values for GDB, the GNU debugger.

   Copyright (C) 1986-2025 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 "event-top.h"
#include "extract-store-integer.h"
#include "gdbsupport/gdb_obstack.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "demangle.h"
#include "annotate.h"
#include "c-lang.h"
#include "target.h"
#include "cp-abi.h"
#include "valprint.h"
#include "cp-support.h"
#include "language.h"
#include "extension.h"
#include "typeprint.h"
#include "gdbsupport/byte-vector.h"
#include "gdbarch.h"
#include "cli/cli-style.h"
#include "gdbsupport/selftest.h"
#include "selftest-arch.h"

static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;
static struct obstack dont_print_stat_array_obstack;

static void cp_print_static_field (struct type *, struct value *,
				   struct ui_file *, int,
				   const struct value_print_options *);

static void cp_print_value (struct value *, struct ui_file *,
			    int, const struct value_print_options *,
			    struct type **);


/* GCC versions after 2.4.5 use this.  */
const char vtbl_ptr_name[] = "__vtbl_ptr_type";

/* Return truth value for assertion that TYPE is of the type
   "pointer to virtual function".  */

int
cp_is_vtbl_ptr_type (struct type *type)
{
  const char *type_name = type->name ();

  return (type_name != NULL && !strcmp (type_name, vtbl_ptr_name));
}

/* Return truth value for the assertion that TYPE is of the type
   "pointer to virtual function table".  */

int
cp_is_vtbl_member (struct type *type)
{
  /* With older versions of g++, the vtbl field pointed to an array of
     structures.  Nowadays it points directly to the structure.  */
  if (type->code () == TYPE_CODE_PTR)
    {
      type = type->target_type ();
      if (type->code () == TYPE_CODE_ARRAY)
	{
	  type = type->target_type ();
	  if (type->code () == TYPE_CODE_STRUCT    /* if not using thunks */
	      || type->code () == TYPE_CODE_PTR)   /* if using thunks */
	    {
	      /* Virtual functions tables are full of pointers
		 to virtual functions.  */
	      return cp_is_vtbl_ptr_type (type);
	    }
	}
      else if (type->code () == TYPE_CODE_STRUCT)  /* if not using thunks */
	{
	  return cp_is_vtbl_ptr_type (type);
	}
      else if (type->code () == TYPE_CODE_PTR)     /* if using thunks */
	{
	  /* The type name of the thunk pointer is NULL when using
	     dwarf2.  We could test for a pointer to a function, but
	     there is no type info for the virtual table either, so it
	     won't help.  */
	  return cp_is_vtbl_ptr_type (type);
	}
    }
  return 0;
}

/* Mutually recursive subroutines of cp_print_value and c_val_print to
   print out a structure's fields: cp_print_value_fields and
   cp_print_value.

   TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and OPTIONS have the same
   meanings as in cp_print_value and c_val_print.

   2nd argument REAL_TYPE is used to carry over the type of the
   derived class across the recursion to base classes.

   DONT_PRINT is an array of baseclass types that we should not print,
   or zero if called from top level.  */

void
cp_print_value_fields (struct value *val, struct ui_file *stream,
		       int recurse, const struct value_print_options *options,
		       struct type **dont_print_vb,
		       int dont_print_statmem)
{
  int i, len, n_baseclasses;
  int fields_seen = 0;
  static int last_set_recurse = -1;

  struct type *type = check_typedef (val->type ());

  if (recurse == 0)
    {
      /* Any object can be left on obstacks only during an unexpected
	 error.  */

      if (obstack_object_size (&dont_print_statmem_obstack) > 0)
	{
	  obstack_free (&dont_print_statmem_obstack, NULL);
	  obstack_begin (&dont_print_statmem_obstack,
			 32 * sizeof (CORE_ADDR));
	}
      if (obstack_object_size (&dont_print_stat_array_obstack) > 0)
	{
	  obstack_free (&dont_print_stat_array_obstack, NULL);
	  obstack_begin (&dont_print_stat_array_obstack,
			 32 * sizeof (struct type *));
	}
    }

  gdb_printf (stream, "{");
  len = type->num_fields ();
  n_baseclasses = TYPE_N_BASECLASSES (type);

  /* First, print out baseclasses such that we don't print
     duplicates of virtual baseclasses.  */

  if (n_baseclasses > 0)
    cp_print_value (val, stream, recurse + 1, options, dont_print_vb);

  /* Second, print out data fields */

  /* If there are no data fields, skip this part */
  if (len == n_baseclasses || !len)
    fprintf_styled (stream, metadata_style.style (), "<No data fields>");
  else
    {
      size_t statmem_obstack_initial_size = 0;
      size_t stat_array_obstack_initial_size = 0;
      struct type *vptr_basetype = NULL;
      int vptr_fieldno;

      if (dont_print_statmem == 0)
	{
	  statmem_obstack_initial_size =
	    obstack_object_size (&dont_print_statmem_obstack);

	  if (last_set_recurse != recurse)
	    {
	      stat_array_obstack_initial_size =
		obstack_object_size (&dont_print_stat_array_obstack);

	      last_set_recurse = recurse;
	    }
	}

      vptr_fieldno = get_vptr_fieldno (type, &vptr_basetype);
      for (i = n_baseclasses; i < len; i++)
	{
	  const gdb_byte *valaddr = val->contents_for_printing ().data ();

	  /* If requested, skip printing of static fields.  */
	  if (!options->static_field_print
	      && type->field (i).is_static ())
	    continue;

	  if (fields_seen)
	    {
	      gdb_puts (",", stream);
	      if (!options->prettyformat)
		gdb_puts (" ", stream);
	    }
	  else if (n_baseclasses > 0)
	    {
	      if (options->prettyformat)
		{
		  gdb_printf (stream, "\n");
		  print_spaces (2 + 2 * recurse, stream);
		  gdb_puts ("members of ", stream);
		  gdb_puts (type->name (), stream);
		  gdb_puts (":", stream);
		}
	    }
	  fields_seen = 1;

	  if (options->prettyformat)
	    {
	      gdb_printf (stream, "\n");
	      print_spaces (2 + 2 * recurse, stream);
	    }
	  else
	    {
	      stream->wrap_here (2 + 2 * recurse);
	    }

	  annotate_field_begin (type->field (i).type ());

	  if (type->field (i).is_static ())
	    {
	      gdb_puts ("static ", stream);
	      fprintf_symbol (stream,
			      type->field (i).name (),
			      current_language->la_language,
			      DMGL_PARAMS | DMGL_ANSI);
	    }
	  else
	    fputs_styled (type->field (i).name (),
			  variable_name_style.style (), stream);
	  annotate_field_name_end ();

	  /* We tweak various options in a few cases below.  */
	  value_print_options options_copy = *options;
	  value_print_options *opts = &options_copy;

	  /* Do not print leading '=' in case of anonymous
	     unions.  */
	  if (strcmp (type->field (i).name (), ""))
	    gdb_puts (" = ", stream);
	  else
	    {
	      /* If this is an anonymous field then we want to consider it
		 as though it is at its parent's depth when it comes to the
		 max print depth.  */
	      if (opts->max_depth != -1 && opts->max_depth < INT_MAX)
		++opts->max_depth;
	    }
	  annotate_field_value ();

	  if (!type->field (i).is_static ()
	      && type->field (i).is_packed ())
	    {
	      struct value *v;

	      /* Bitfields require special handling, especially due to
		 byte order problems.  */
	      if (type->field (i).is_ignored ())
		{
		  fputs_styled ("<optimized out or zero length>",
				metadata_style.style (), stream);
		}
	      else if (val->bits_synthetic_pointer
		       (type->field (i).loc_bitpos (),
			type->field (i).bitsize ()))
		{
		  fputs_styled (_("<synthetic pointer>"),
				metadata_style.style (), stream);
		}
	      else
		{
		  opts->deref_ref = false;

		  v = value_field_bitfield (type, i, valaddr,
					    val->embedded_offset (), val);

		  common_val_print (v, stream, recurse + 1,
				    opts, current_language);
		}
	    }
	  else
	    {
	      if (type->field (i).is_ignored ())
		{
		  fputs_styled ("<optimized out or zero length>",
				metadata_style.style (), stream);
		}
	      else if (type->field (i).is_static ())
		{
		  try
		    {
		      struct value *v = value_static_field (type, i);

		      cp_print_static_field (type->field (i).type (),
					     v, stream, recurse + 1,
					     opts);
		    }
		  catch (const gdb_exception_error &ex)
		    {
		      fprintf_styled (stream, metadata_style.style (),
				      _("<error reading variable: %s>"),
				      ex.what ());
		    }
		}
	      else if (i == vptr_fieldno && type == vptr_basetype)
		{
		  int i_offset = type->field (i).loc_bitpos () / 8;
		  struct type *i_type = type->field (i).type ();

		  if (valprint_check_validity (stream, i_type, i_offset, val))
		    {
		      CORE_ADDR addr;

		      i_offset += val->embedded_offset ();
		      addr = extract_typed_address (valaddr + i_offset, i_type);
		      print_function_pointer_address (opts,
						      type->arch (),
						      addr, stream);
		    }
		}
	      else
		{
		  struct value *v = val->primitive_field (0, i, type);
		  opts->deref_ref = false;
		  common_val_print (v, stream, recurse + 1, opts,
				    current_language);
		}
	    }
	  annotate_field_end ();
	}

      if (dont_print_statmem == 0)
	{
	  size_t obstack_final_size =
	   obstack_object_size (&dont_print_statmem_obstack);

	  if (obstack_final_size > statmem_obstack_initial_size)
	    {
	      /* In effect, a pop of the printed-statics stack.  */
	      size_t shrink_bytes
		= statmem_obstack_initial_size - obstack_final_size;
	      obstack_blank_fast (&dont_print_statmem_obstack, shrink_bytes);
	    }

	  if (last_set_recurse != recurse)
	    {
	      obstack_final_size =
		obstack_object_size (&dont_print_stat_array_obstack);

	      if (obstack_final_size > stat_array_obstack_initial_size)
		{
		  void *free_to_ptr =
		    (char *) obstack_next_free (&dont_print_stat_array_obstack)
		    - (obstack_final_size
		       - stat_array_obstack_initial_size);

		  obstack_free (&dont_print_stat_array_obstack,
				free_to_ptr);
		}
	      last_set_recurse = -1;
	    }
	}

      if (options->prettyformat)
	{
	  gdb_printf (stream, "\n");
	  print_spaces (2 * recurse, stream);
	}
    }				/* if there are data fields */

  gdb_printf (stream, "}");
}

/* A wrapper for cp_print_value_fields that tries to apply a
   pretty-printer first.  */

static void
cp_print_value_fields_pp (struct value *val,
			  struct ui_file *stream,
			  int recurse,
			  const struct value_print_options *options,
			  struct type **dont_print_vb,
			  int dont_print_statmem)
{
  int result = 0;

  /* Attempt to run an extension language pretty-printer if
     possible.  */
  if (!options->raw)
    result
      = apply_ext_lang_val_pretty_printer (val, stream,
					   recurse, options,
					   current_language);

  if (!result)
    cp_print_value_fields (val, stream, recurse, options, dont_print_vb,
			   dont_print_statmem);
}

/* Special val_print routine to avoid printing multiple copies of
   virtual baseclasses.  */

static void
cp_print_value (struct value *val, struct ui_file *stream,
		int recurse, const struct value_print_options *options,
		struct type **dont_print_vb)
{
  struct type *type = check_typedef (val->type ());
  CORE_ADDR address = val->address ();
  struct type **last_dont_print
    = (struct type **) obstack_next_free (&dont_print_vb_obstack);
  struct obstack tmp_obstack = dont_print_vb_obstack;
  int i, n_baseclasses = TYPE_N_BASECLASSES (type);
  const gdb_byte *valaddr = val->contents_for_printing ().data ();

  if (dont_print_vb == 0)
    {
      /* If we're at top level, carve out a completely fresh chunk of
	 the obstack and use that until this particular invocation
	 returns.  */
      /* Bump up the high-water mark.  Now alpha is omega.  */
      obstack_finish (&dont_print_vb_obstack);
    }

  for (i = 0; i < n_baseclasses; i++)
    {
      LONGEST boffset = 0;
      int skip = 0;
      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
      const char *basename = baseclass->name ();
      struct value *base_val = NULL;

      if (BASETYPE_VIA_VIRTUAL (type, i))
	{
	  struct type **first_dont_print
	    = (struct type **) obstack_base (&dont_print_vb_obstack);

	  int j = (struct type **)
	    obstack_next_free (&dont_print_vb_obstack) - first_dont_print;

	  while (--j >= 0)
	    if (baseclass == first_dont_print[j])
	      goto flush_it;

	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
	}

      try
	{
	  boffset = baseclass_offset (type, i, valaddr,
				      val->embedded_offset (),
				      address, val);
	}
      catch (const gdb_exception_error &ex)
	{
	  if (ex.error == NOT_AVAILABLE_ERROR)
	    skip = -1;
	  else
	    skip = 1;
	}

      if (skip == 0)
	{
	  if (BASETYPE_VIA_VIRTUAL (type, i))
	    {
	      /* The virtual base class pointer might have been
		 clobbered by the user program. Make sure that it
		 still points to a valid memory location.  */

	      if (boffset < 0 || boffset >= type->length ())
		{
		  gdb::byte_vector buf (baseclass->length ());

		  if (target_read_memory (address + boffset, buf.data (),
					  baseclass->length ()) != 0)
		    skip = 1;
		  base_val = value_from_contents_and_address (baseclass,
							      buf.data (),
							      address + boffset);
		  baseclass = base_val->type ();
		  boffset = 0;
		}
	      else
		{
		  base_val = val;
		}
	    }
	  else
	    {
	      base_val = val;
	    }
	}

      /* Now do the printing.  */
      if (options->prettyformat)
	{
	  gdb_printf (stream, "\n");
	  print_spaces (2 * recurse, stream);
	}
      gdb_puts ("<", stream);
      /* Not sure what the best notation is in the case where there is
	 no baseclass name.  */
      gdb_puts (basename ? basename : "", stream);
      gdb_puts ("> = ", stream);

      if (skip < 0)
	val_print_unavailable (stream);
      else if (skip > 0)
	val_print_invalid_address (stream);
      else
	{
	  if (!val_print_check_max_depth (stream, recurse, options,
					  current_language))
	    {
	      struct value *baseclass_val = val->primitive_field (0,
								  i, type);

	      cp_print_value_fields_pp
		(baseclass_val, stream, recurse, options,
		 (struct type **) obstack_base (&dont_print_vb_obstack),
		 0);
	    }
	}
      gdb_puts (", ", stream);

    flush_it:
      ;
    }

  if (dont_print_vb == 0)
    {
      /* Free the space used to deal with the printing
	 of this type from top level.  */
      obstack_free (&dont_print_vb_obstack, last_dont_print);
      /* Reset watermark so that we can continue protecting
	 ourselves from whatever we were protecting ourselves.  */
      dont_print_vb_obstack = tmp_obstack;
    }
}

/* Print value of a static member.  To avoid infinite recursion when
   printing a class that contains a static instance of the class, we
   keep the addresses of all printed static member classes in an
   obstack and refuse to print them more than once.

   VAL contains the value to print, TYPE, STREAM, RECURSE, and OPTIONS
   have the same meanings as in c_val_print.  */

static void
cp_print_static_field (struct type *type,
		       struct value *val,
		       struct ui_file *stream,
		       int recurse,
		       const struct value_print_options *options)
{
  struct value_print_options opts;

  if (val->entirely_optimized_out ())
    {
      val_print_optimized_out (val, stream);
      return;
    }

  struct type *real_type = check_typedef (type);
  if (real_type->code () == TYPE_CODE_STRUCT)
    {
      CORE_ADDR *first_dont_print;
      CORE_ADDR addr = val->address ();
      int i;

      first_dont_print
	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
      i = obstack_object_size (&dont_print_statmem_obstack)
	/ sizeof (CORE_ADDR);

      while (--i >= 0)
	{
	  if (addr == first_dont_print[i])
	    {
	      fputs_styled (_("<same as static member of an already"
			      " seen type>"),
			    metadata_style.style (), stream);
	      return;
	    }
	}

      obstack_grow (&dont_print_statmem_obstack, (char *) &addr,
		    sizeof (CORE_ADDR));
      cp_print_value_fields_pp (val, stream, recurse, options, nullptr, 1);
      return;
    }

  if (real_type->code () == TYPE_CODE_ARRAY)
    {
      struct type **first_dont_print;
      int i;
      struct type *target_type = type->target_type ();

      first_dont_print
	= (struct type **) obstack_base (&dont_print_stat_array_obstack);
      i = obstack_object_size (&dont_print_stat_array_obstack)
	/ sizeof (struct type *);

      while (--i >= 0)
	{
	  if (target_type == first_dont_print[i])
	    {
	      fputs_styled (_("<same as static member of an already"
			      " seen type>"),
			    metadata_style.style (), stream);
	      return;
	    }
	}

      obstack_grow (&dont_print_stat_array_obstack,
		    (char *) &target_type,
		    sizeof (struct type *));
    }

  opts = *options;
  opts.deref_ref = false;
  common_val_print (val, stream, recurse, &opts, current_language);
}

/* Find the field in *SELF, or its non-virtual base classes, with
   bit offset OFFSET.  Set *SELF to the containing type and *FIELDNO
   to the containing field number.  If OFFSET is not exactly at the
   start of some field, set *SELF to NULL.  */

static void
cp_find_class_member (struct type **self_p, int *fieldno,
		      LONGEST offset)
{
  struct type *self;
  unsigned int i;
  unsigned len;

  *self_p = check_typedef (*self_p);
  self = *self_p;
  len = self->num_fields ();

  for (i = TYPE_N_BASECLASSES (self); i < len; i++)
    {
      field &f = self->field (i);
      if (f.is_static ())
	continue;
      LONGEST bitpos = f.loc_bitpos ();

      QUIT;
      if (offset == bitpos)
	{
	  *fieldno = i;
	  return;
	}
    }

  for (i = 0; i < TYPE_N_BASECLASSES (self); i++)
    {
      LONGEST bitpos = self->field (i).loc_bitpos ();
      LONGEST bitsize = 8 * self->field (i).type ()->length ();

      if (offset >= bitpos && offset < bitpos + bitsize)
	{
	  *self_p = self->field (i).type ();
	  cp_find_class_member (self_p, fieldno, offset - bitpos);
	  return;
	}
    }

  *self_p = NULL;
}

void
cp_print_class_member (const gdb_byte *valaddr, struct type *type,
		       struct ui_file *stream, const char *prefix)
{
  enum bfd_endian byte_order = type_byte_order (type);

  /* VAL is a byte offset into the structure type SELF_TYPE.
     Find the name of the field for that offset and
     print it.  */
  struct type *self_type = TYPE_SELF_TYPE (type);
  LONGEST val;
  int fieldno;

  val = extract_signed_integer (valaddr,
				type->length (),
				byte_order);

  /* Pointers to data members are usually byte offsets into an object.
     Because a data member can have offset zero, and a NULL pointer to
     member must be distinct from any valid non-NULL pointer to
     member, either the value is biased or the NULL value has a
     special representation; both are permitted by ISO C++.  HP aCC
     used a bias of 0x20000000; HP cfront used a bias of 1; g++ 3.x
     and other compilers which use the Itanium ABI use -1 as the NULL
     value.  GDB only supports that last form; to add support for
     another form, make this into a cp-abi hook.  */

  if (val == -1)
    {
      gdb_printf (stream, "NULL");
      return;
    }

  cp_find_class_member (&self_type, &fieldno, val << 3);

  if (self_type != NULL)
    {
      const char *name;

      gdb_puts (prefix, stream);
      name = self_type->name ();
      if (name)
	gdb_puts (name, stream);
      else
	c_type_print_base (self_type, stream, 0, 0, &type_print_raw_options);
      gdb_printf (stream, "::");
      fputs_styled (self_type->field (fieldno).name (),
		    variable_name_style.style (), stream);
    }
  else
    gdb_printf (stream, "%ld", (long) val);
}

#if GDB_SELF_TEST

/* Test printing of TYPE_CODE_STRUCT values.  */

static void
test_print_fields (gdbarch *arch)
{
  struct field *f;
  type *uint8_type = builtin_type (arch)->builtin_uint8;
  type *bool_type = builtin_type (arch)->builtin_bool;
  type *the_struct = arch_composite_type (arch, NULL, TYPE_CODE_STRUCT);
  the_struct->set_length (4);

  /* Value:  1110 1001
     Fields: C-BB B-A- */
  if (gdbarch_byte_order (arch) == BFD_ENDIAN_LITTLE)
    {
      f = append_composite_type_field_raw (the_struct, "A", bool_type);
      f->set_loc_bitpos (1);
      f->set_bitsize (1);
      f = append_composite_type_field_raw (the_struct, "B", uint8_type);
      f->set_loc_bitpos (3);
      f->set_bitsize (3);
      f = append_composite_type_field_raw (the_struct, "C", bool_type);
      f->set_loc_bitpos (7);
      f->set_bitsize (1);
    }
  /* According to the logic commented in "make_gdb_type_struct ()" of
   * target-descriptions.c, bit positions are numbered differently for
   * little and big endians.  */
  else
    {
      f = append_composite_type_field_raw (the_struct, "A", bool_type);
      f->set_loc_bitpos (30);
      f->set_bitsize (1);
      f = append_composite_type_field_raw (the_struct, "B", uint8_type);
      f->set_loc_bitpos (26);
      f->set_bitsize (3);
      f = append_composite_type_field_raw (the_struct, "C", bool_type);
      f->set_loc_bitpos (24);
      f->set_bitsize (1);
    }

  value *val = value::allocate (the_struct);
  gdb_byte *contents = val->contents_writeable ().data ();
  store_unsigned_integer (contents, val->enclosing_type ()->length (),
			  gdbarch_byte_order (arch), 0xe9);

  string_file out;
  struct value_print_options opts;
  get_no_prettyformat_print_options (&opts);
  cp_print_value_fields(val, &out, 0, &opts, NULL, 0);
  SELF_CHECK (out.string () == "{A = false, B = 5, C = true}");

  out.clear();
  opts.format = 'x';
  cp_print_value_fields(val, &out, 0, &opts, NULL, 0);
  SELF_CHECK (out.string () == "{A = 0x0, B = 0x5, C = 0x1}");
}

#endif


void _initialize_cp_valprint ();
void
_initialize_cp_valprint ()
{
#if GDB_SELF_TEST
  selftests::register_test_foreach_arch ("print-fields", test_print_fields);
#endif

  obstack_begin (&dont_print_stat_array_obstack,
		 32 * sizeof (struct type *));
  obstack_begin (&dont_print_statmem_obstack,
		 32 * sizeof (CORE_ADDR));
  obstack_begin (&dont_print_vb_obstack,
		 32 * sizeof (struct type *));
}
