198944Sobrien/* Support for printing Pascal values for GDB, the GNU debugger.
2130803Smarcel   Copyright 2000, 2001, 2003
398944Sobrien   Free Software Foundation, Inc.
498944Sobrien
598944Sobrien   This file is part of GDB.
698944Sobrien
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1198944Sobrien
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1698944Sobrien
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2098944Sobrien
2198944Sobrien/* This file is derived from c-valprint.c */
2298944Sobrien
2398944Sobrien#include "defs.h"
24130803Smarcel#include "gdb_obstack.h"
2598944Sobrien#include "symtab.h"
2698944Sobrien#include "gdbtypes.h"
2798944Sobrien#include "expression.h"
2898944Sobrien#include "value.h"
2998944Sobrien#include "command.h"
3098944Sobrien#include "gdbcmd.h"
3198944Sobrien#include "gdbcore.h"
3298944Sobrien#include "demangle.h"
3398944Sobrien#include "valprint.h"
3498944Sobrien#include "typeprint.h"
3598944Sobrien#include "language.h"
3698944Sobrien#include "target.h"
3798944Sobrien#include "annotate.h"
3898944Sobrien#include "p-lang.h"
3998944Sobrien#include "cp-abi.h"
4098944Sobrien
4198944Sobrien
4298944Sobrien
4398944Sobrien
4498944Sobrien/* Print data of type TYPE located at VALADDR (within GDB), which came from
4598944Sobrien   the inferior at address ADDRESS, onto stdio stream STREAM according to
4698944Sobrien   FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
4798944Sobrien   target byte order.
4898944Sobrien
4998944Sobrien   If the data are a string pointer, returns the number of string characters
5098944Sobrien   printed.
5198944Sobrien
5298944Sobrien   If DEREF_REF is nonzero, then dereference references, otherwise just print
5398944Sobrien   them like pointers.
5498944Sobrien
5598944Sobrien   The PRETTY parameter controls prettyprinting.  */
5698944Sobrien
5798944Sobrien
5898944Sobrienint
5998944Sobrienpascal_val_print (struct type *type, char *valaddr, int embedded_offset,
6098944Sobrien		  CORE_ADDR address, struct ui_file *stream, int format,
6198944Sobrien		  int deref_ref, int recurse, enum val_prettyprint pretty)
6298944Sobrien{
63130803Smarcel  unsigned int i = 0;	/* Number of characters printed */
6498944Sobrien  unsigned len;
6598944Sobrien  struct type *elttype;
6698944Sobrien  unsigned eltlen;
6798944Sobrien  int length_pos, length_size, string_pos;
6898944Sobrien  int char_size;
6998944Sobrien  LONGEST val;
7098944Sobrien  CORE_ADDR addr;
7198944Sobrien
7298944Sobrien  CHECK_TYPEDEF (type);
7398944Sobrien  switch (TYPE_CODE (type))
7498944Sobrien    {
7598944Sobrien    case TYPE_CODE_ARRAY:
7698944Sobrien      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
7798944Sobrien	{
7898944Sobrien	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
7998944Sobrien	  eltlen = TYPE_LENGTH (elttype);
8098944Sobrien	  len = TYPE_LENGTH (type) / eltlen;
8198944Sobrien	  if (prettyprint_arrays)
8298944Sobrien	    {
8398944Sobrien	      print_spaces_filtered (2 + 2 * recurse, stream);
8498944Sobrien	    }
8598944Sobrien	  /* For an array of chars, print with string syntax.  */
8698944Sobrien	  if (eltlen == 1 &&
8798944Sobrien	      ((TYPE_CODE (elttype) == TYPE_CODE_INT)
8898944Sobrien	       || ((current_language->la_language == language_m2)
8998944Sobrien		   && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
9098944Sobrien	      && (format == 0 || format == 's'))
9198944Sobrien	    {
9298944Sobrien	      /* If requested, look for the first null char and only print
9398944Sobrien	         elements up to it.  */
9498944Sobrien	      if (stop_print_at_null)
9598944Sobrien		{
9698944Sobrien		  unsigned int temp_len;
9798944Sobrien
9898944Sobrien		  /* Look for a NULL char. */
9998944Sobrien		  for (temp_len = 0;
10098944Sobrien		       (valaddr + embedded_offset)[temp_len]
10198944Sobrien		       && temp_len < len && temp_len < print_max;
10298944Sobrien		       temp_len++);
10398944Sobrien		  len = temp_len;
10498944Sobrien		}
10598944Sobrien
10698944Sobrien	      LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0);
10798944Sobrien	      i = len;
10898944Sobrien	    }
10998944Sobrien	  else
11098944Sobrien	    {
11198944Sobrien	      fprintf_filtered (stream, "{");
11298944Sobrien	      /* If this is a virtual function table, print the 0th
11398944Sobrien	         entry specially, and the rest of the members normally.  */
11498944Sobrien	      if (pascal_object_is_vtbl_ptr_type (elttype))
11598944Sobrien		{
11698944Sobrien		  i = 1;
11798944Sobrien		  fprintf_filtered (stream, "%d vtable entries", len - 1);
11898944Sobrien		}
11998944Sobrien	      else
12098944Sobrien		{
12198944Sobrien		  i = 0;
12298944Sobrien		}
12398944Sobrien	      val_print_array_elements (type, valaddr + embedded_offset, address, stream,
12498944Sobrien				     format, deref_ref, recurse, pretty, i);
12598944Sobrien	      fprintf_filtered (stream, "}");
12698944Sobrien	    }
12798944Sobrien	  break;
12898944Sobrien	}
12998944Sobrien      /* Array of unspecified length: treat like pointer to first elt.  */
13098944Sobrien      addr = address;
13198944Sobrien      goto print_unpacked_pointer;
13298944Sobrien
13398944Sobrien    case TYPE_CODE_PTR:
13498944Sobrien      if (format && format != 's')
13598944Sobrien	{
13698944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
13798944Sobrien	  break;
13898944Sobrien	}
13998944Sobrien      if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
14098944Sobrien	{
14198944Sobrien	  /* Print the unmangled name if desired.  */
14298944Sobrien	  /* Print vtable entry - we only get here if we ARE using
14398944Sobrien	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
144130803Smarcel	  /* Extract the address, assume that it is unsigned.  */
145130803Smarcel	  print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type)),
14698944Sobrien				  stream, demangle);
14798944Sobrien	  break;
14898944Sobrien	}
14998944Sobrien      elttype = check_typedef (TYPE_TARGET_TYPE (type));
15098944Sobrien      if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
15198944Sobrien	{
15298944Sobrien	  pascal_object_print_class_method (valaddr + embedded_offset, type, stream);
15398944Sobrien	}
15498944Sobrien      else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
15598944Sobrien	{
15698944Sobrien	  pascal_object_print_class_member (valaddr + embedded_offset,
15798944Sobrien				 TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
15898944Sobrien					    stream, "&");
15998944Sobrien	}
16098944Sobrien      else
16198944Sobrien	{
16298944Sobrien	  addr = unpack_pointer (type, valaddr + embedded_offset);
16398944Sobrien	print_unpacked_pointer:
16498944Sobrien	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
16598944Sobrien
16698944Sobrien	  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
16798944Sobrien	    {
16898944Sobrien	      /* Try to print what function it points to.  */
16998944Sobrien	      print_address_demangle (addr, stream, demangle);
17098944Sobrien	      /* Return value is irrelevant except for string pointers.  */
17198944Sobrien	      return (0);
17298944Sobrien	    }
17398944Sobrien
17498944Sobrien	  if (addressprint && format != 's')
17598944Sobrien	    {
17698944Sobrien	      print_address_numeric (addr, 1, stream);
17798944Sobrien	    }
17898944Sobrien
17998944Sobrien	  /* For a pointer to char or unsigned char, also print the string
18098944Sobrien	     pointed to, unless pointer is null.  */
18198944Sobrien	  if (TYPE_LENGTH (elttype) == 1
18298944Sobrien	      && TYPE_CODE (elttype) == TYPE_CODE_INT
18398944Sobrien	      && (format == 0 || format == 's')
18498944Sobrien	      && addr != 0)
18598944Sobrien	    {
18698944Sobrien	      /* no wide string yet */
18798944Sobrien	      i = val_print_string (addr, -1, 1, stream);
18898944Sobrien	    }
18998944Sobrien	  /* also for pointers to pascal strings */
19098944Sobrien	  /* Note: this is Free Pascal specific:
19198944Sobrien	     as GDB does not recognize stabs pascal strings
19298944Sobrien	     Pascal strings are mapped to records
19398944Sobrien	     with lowercase names PM  */
194130803Smarcel          if (is_pascal_string_type (elttype, &length_pos, &length_size,
195130803Smarcel                                     &string_pos, &char_size, NULL)
19698944Sobrien	      && addr != 0)
19798944Sobrien	    {
19898944Sobrien	      ULONGEST string_length;
19998944Sobrien              void *buffer;
20098944Sobrien              buffer = xmalloc (length_size);
20198944Sobrien              read_memory (addr + length_pos, buffer, length_size);
20298944Sobrien	      string_length = extract_unsigned_integer (buffer, length_size);
20398944Sobrien              xfree (buffer);
20498944Sobrien              i = val_print_string (addr + string_pos, string_length, char_size, stream);
20598944Sobrien	    }
20698944Sobrien	  else if (pascal_object_is_vtbl_member (type))
20798944Sobrien	    {
20898944Sobrien	      /* print vtbl's nicely */
20998944Sobrien	      CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
21098944Sobrien
21198944Sobrien	      struct minimal_symbol *msymbol =
21298944Sobrien	      lookup_minimal_symbol_by_pc (vt_address);
21398944Sobrien	      if ((msymbol != NULL)
21498944Sobrien		  && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
21598944Sobrien		{
21698944Sobrien		  fputs_filtered (" <", stream);
217130803Smarcel		  fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream);
21898944Sobrien		  fputs_filtered (">", stream);
21998944Sobrien		}
22098944Sobrien	      if (vt_address && vtblprint)
22198944Sobrien		{
22298944Sobrien		  struct value *vt_val;
22398944Sobrien		  struct symbol *wsym = (struct symbol *) NULL;
22498944Sobrien		  struct type *wtype;
22598944Sobrien		  struct block *block = (struct block *) NULL;
22698944Sobrien		  int is_this_fld;
22798944Sobrien
22898944Sobrien		  if (msymbol != NULL)
229130803Smarcel		    wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block,
230130803Smarcel					  VAR_DOMAIN, &is_this_fld, NULL);
23198944Sobrien
23298944Sobrien		  if (wsym)
23398944Sobrien		    {
23498944Sobrien		      wtype = SYMBOL_TYPE (wsym);
23598944Sobrien		    }
23698944Sobrien		  else
23798944Sobrien		    {
23898944Sobrien		      wtype = TYPE_TARGET_TYPE (type);
23998944Sobrien		    }
24098944Sobrien		  vt_val = value_at (wtype, vt_address, NULL);
241242936Semaste		  common_val_print (vt_val, stream, format, deref_ref,
242242936Semaste				    recurse + 1, pretty);
24398944Sobrien		  if (pretty)
24498944Sobrien		    {
24598944Sobrien		      fprintf_filtered (stream, "\n");
24698944Sobrien		      print_spaces_filtered (2 + 2 * recurse, stream);
24798944Sobrien		    }
24898944Sobrien		}
24998944Sobrien	    }
25098944Sobrien
25198944Sobrien	  /* Return number of characters printed, including the terminating
25298944Sobrien	     '\0' if we reached the end.  val_print_string takes care including
25398944Sobrien	     the terminating '\0' if necessary.  */
25498944Sobrien	  return i;
25598944Sobrien	}
25698944Sobrien      break;
25798944Sobrien
25898944Sobrien    case TYPE_CODE_MEMBER:
25998944Sobrien      error ("not implemented: member type in pascal_val_print");
26098944Sobrien      break;
26198944Sobrien
26298944Sobrien    case TYPE_CODE_REF:
26398944Sobrien      elttype = check_typedef (TYPE_TARGET_TYPE (type));
26498944Sobrien      if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
26598944Sobrien	{
26698944Sobrien	  pascal_object_print_class_member (valaddr + embedded_offset,
26798944Sobrien					    TYPE_DOMAIN_TYPE (elttype),
26898944Sobrien					    stream, "");
26998944Sobrien	  break;
27098944Sobrien	}
27198944Sobrien      if (addressprint)
27298944Sobrien	{
27398944Sobrien	  fprintf_filtered (stream, "@");
274130803Smarcel	  /* Extract the address, assume that it is unsigned.  */
27598944Sobrien	  print_address_numeric
276130803Smarcel	    (extract_unsigned_integer (valaddr + embedded_offset,
277130803Smarcel				       TARGET_PTR_BIT / HOST_CHAR_BIT),
278130803Smarcel	     1, stream);
27998944Sobrien	  if (deref_ref)
28098944Sobrien	    fputs_filtered (": ", stream);
28198944Sobrien	}
28298944Sobrien      /* De-reference the reference.  */
28398944Sobrien      if (deref_ref)
28498944Sobrien	{
28598944Sobrien	  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
28698944Sobrien	    {
28798944Sobrien	      struct value *deref_val =
28898944Sobrien	      value_at
28998944Sobrien	      (TYPE_TARGET_TYPE (type),
29098944Sobrien	       unpack_pointer (lookup_pointer_type (builtin_type_void),
29198944Sobrien			       valaddr + embedded_offset),
29298944Sobrien	       NULL);
293242936Semaste	      common_val_print (deref_val, stream, format, deref_ref,
294242936Semaste				recurse + 1, pretty);
29598944Sobrien	    }
29698944Sobrien	  else
29798944Sobrien	    fputs_filtered ("???", stream);
29898944Sobrien	}
29998944Sobrien      break;
30098944Sobrien
30198944Sobrien    case TYPE_CODE_UNION:
30298944Sobrien      if (recurse && !unionprint)
30398944Sobrien	{
30498944Sobrien	  fprintf_filtered (stream, "{...}");
30598944Sobrien	  break;
30698944Sobrien	}
30798944Sobrien      /* Fall through.  */
30898944Sobrien    case TYPE_CODE_STRUCT:
30998944Sobrien      if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
31098944Sobrien	{
31198944Sobrien	  /* Print the unmangled name if desired.  */
31298944Sobrien	  /* Print vtable entry - we only get here if NOT using
31398944Sobrien	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.) */
314130803Smarcel	  /* Extract the address, assume that it is unsigned.  */
315130803Smarcel	  print_address_demangle
316130803Smarcel	    (extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
317130803Smarcel				       TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
318130803Smarcel	     stream, demangle);
31998944Sobrien	}
32098944Sobrien      else
32198944Sobrien	{
32298944Sobrien          if (is_pascal_string_type (type, &length_pos, &length_size,
323130803Smarcel                                     &string_pos, &char_size, NULL))
32498944Sobrien	    {
32598944Sobrien	      len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size);
32698944Sobrien	      LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0);
32798944Sobrien	    }
32898944Sobrien	  else
32998944Sobrien	    pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, format,
33098944Sobrien					      recurse, pretty, NULL, 0);
33198944Sobrien	}
33298944Sobrien      break;
33398944Sobrien
33498944Sobrien    case TYPE_CODE_ENUM:
33598944Sobrien      if (format)
33698944Sobrien	{
33798944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
33898944Sobrien	  break;
33998944Sobrien	}
34098944Sobrien      len = TYPE_NFIELDS (type);
34198944Sobrien      val = unpack_long (type, valaddr + embedded_offset);
34298944Sobrien      for (i = 0; i < len; i++)
34398944Sobrien	{
34498944Sobrien	  QUIT;
34598944Sobrien	  if (val == TYPE_FIELD_BITPOS (type, i))
34698944Sobrien	    {
34798944Sobrien	      break;
34898944Sobrien	    }
34998944Sobrien	}
35098944Sobrien      if (i < len)
35198944Sobrien	{
35298944Sobrien	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
35398944Sobrien	}
35498944Sobrien      else
35598944Sobrien	{
35698944Sobrien	  print_longest (stream, 'd', 0, val);
35798944Sobrien	}
35898944Sobrien      break;
35998944Sobrien
36098944Sobrien    case TYPE_CODE_FUNC:
36198944Sobrien      if (format)
36298944Sobrien	{
36398944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
36498944Sobrien	  break;
36598944Sobrien	}
36698944Sobrien      /* FIXME, we should consider, at least for ANSI C language, eliminating
36798944Sobrien         the distinction made between FUNCs and POINTERs to FUNCs.  */
36898944Sobrien      fprintf_filtered (stream, "{");
36998944Sobrien      type_print (type, "", stream, -1);
37098944Sobrien      fprintf_filtered (stream, "} ");
37198944Sobrien      /* Try to print what function it points to, and its address.  */
37298944Sobrien      print_address_demangle (address, stream, demangle);
37398944Sobrien      break;
37498944Sobrien
37598944Sobrien    case TYPE_CODE_BOOL:
37698944Sobrien      format = format ? format : output_format;
37798944Sobrien      if (format)
37898944Sobrien	print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
37998944Sobrien      else
38098944Sobrien	{
38198944Sobrien	  val = unpack_long (type, valaddr + embedded_offset);
38298944Sobrien	  if (val == 0)
38398944Sobrien	    fputs_filtered ("false", stream);
38498944Sobrien	  else if (val == 1)
38598944Sobrien	    fputs_filtered ("true", stream);
38698944Sobrien	  else
38798944Sobrien	    {
38898944Sobrien	      fputs_filtered ("true (", stream);
38998944Sobrien	      fprintf_filtered (stream, "%ld)", (long int) val);
39098944Sobrien	    }
39198944Sobrien	}
39298944Sobrien      break;
39398944Sobrien
39498944Sobrien    case TYPE_CODE_RANGE:
39598944Sobrien      /* FIXME: create_range_type does not set the unsigned bit in a
39698944Sobrien         range type (I think it probably should copy it from the target
39798944Sobrien         type), so we won't print values which are too large to
39898944Sobrien         fit in a signed integer correctly.  */
39998944Sobrien      /* FIXME: Doesn't handle ranges of enums correctly.  (Can't just
40098944Sobrien         print with the target type, though, because the size of our type
40198944Sobrien         and the target type might differ).  */
40298944Sobrien      /* FALLTHROUGH */
40398944Sobrien
40498944Sobrien    case TYPE_CODE_INT:
40598944Sobrien      format = format ? format : output_format;
40698944Sobrien      if (format)
40798944Sobrien	{
40898944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
40998944Sobrien	}
41098944Sobrien      else
41198944Sobrien	{
41298944Sobrien	  val_print_type_code_int (type, valaddr + embedded_offset, stream);
41398944Sobrien	}
41498944Sobrien      break;
41598944Sobrien
41698944Sobrien    case TYPE_CODE_CHAR:
41798944Sobrien      format = format ? format : output_format;
41898944Sobrien      if (format)
41998944Sobrien	{
42098944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
42198944Sobrien	}
42298944Sobrien      else
42398944Sobrien	{
42498944Sobrien	  val = unpack_long (type, valaddr + embedded_offset);
42598944Sobrien	  if (TYPE_UNSIGNED (type))
42698944Sobrien	    fprintf_filtered (stream, "%u", (unsigned int) val);
42798944Sobrien	  else
42898944Sobrien	    fprintf_filtered (stream, "%d", (int) val);
42998944Sobrien	  fputs_filtered (" ", stream);
43098944Sobrien	  LA_PRINT_CHAR ((unsigned char) val, stream);
43198944Sobrien	}
43298944Sobrien      break;
43398944Sobrien
43498944Sobrien    case TYPE_CODE_FLT:
43598944Sobrien      if (format)
43698944Sobrien	{
43798944Sobrien	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
43898944Sobrien	}
43998944Sobrien      else
44098944Sobrien	{
44198944Sobrien	  print_floating (valaddr + embedded_offset, type, stream);
44298944Sobrien	}
44398944Sobrien      break;
44498944Sobrien
44598944Sobrien    case TYPE_CODE_BITSTRING:
44698944Sobrien    case TYPE_CODE_SET:
44798944Sobrien      elttype = TYPE_INDEX_TYPE (type);
44898944Sobrien      CHECK_TYPEDEF (elttype);
44998944Sobrien      if (TYPE_STUB (elttype))
45098944Sobrien	{
45198944Sobrien	  fprintf_filtered (stream, "<incomplete type>");
45298944Sobrien	  gdb_flush (stream);
45398944Sobrien	  break;
45498944Sobrien	}
45598944Sobrien      else
45698944Sobrien	{
45798944Sobrien	  struct type *range = elttype;
45898944Sobrien	  LONGEST low_bound, high_bound;
45998944Sobrien	  int i;
46098944Sobrien	  int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
46198944Sobrien	  int need_comma = 0;
46298944Sobrien
46398944Sobrien	  if (is_bitstring)
46498944Sobrien	    fputs_filtered ("B'", stream);
46598944Sobrien	  else
46698944Sobrien	    fputs_filtered ("[", stream);
46798944Sobrien
46898944Sobrien	  i = get_discrete_bounds (range, &low_bound, &high_bound);
46998944Sobrien	maybe_bad_bstring:
47098944Sobrien	  if (i < 0)
47198944Sobrien	    {
47298944Sobrien	      fputs_filtered ("<error value>", stream);
47398944Sobrien	      goto done;
47498944Sobrien	    }
47598944Sobrien
47698944Sobrien	  for (i = low_bound; i <= high_bound; i++)
47798944Sobrien	    {
47898944Sobrien	      int element = value_bit_index (type, valaddr + embedded_offset, i);
47998944Sobrien	      if (element < 0)
48098944Sobrien		{
48198944Sobrien		  i = element;
48298944Sobrien		  goto maybe_bad_bstring;
48398944Sobrien		}
48498944Sobrien	      if (is_bitstring)
48598944Sobrien		fprintf_filtered (stream, "%d", element);
48698944Sobrien	      else if (element)
48798944Sobrien		{
48898944Sobrien		  if (need_comma)
48998944Sobrien		    fputs_filtered (", ", stream);
49098944Sobrien		  print_type_scalar (range, i, stream);
49198944Sobrien		  need_comma = 1;
49298944Sobrien
49398944Sobrien		  if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i))
49498944Sobrien		    {
49598944Sobrien		      int j = i;
49698944Sobrien		      fputs_filtered ("..", stream);
49798944Sobrien		      while (i + 1 <= high_bound
49898944Sobrien			     && value_bit_index (type, valaddr + embedded_offset, ++i))
49998944Sobrien			j = i;
50098944Sobrien		      print_type_scalar (range, j, stream);
50198944Sobrien		    }
50298944Sobrien		}
50398944Sobrien	    }
50498944Sobrien	done:
50598944Sobrien	  if (is_bitstring)
50698944Sobrien	    fputs_filtered ("'", stream);
50798944Sobrien	  else
50898944Sobrien	    fputs_filtered ("]", stream);
50998944Sobrien	}
51098944Sobrien      break;
51198944Sobrien
51298944Sobrien    case TYPE_CODE_VOID:
51398944Sobrien      fprintf_filtered (stream, "void");
51498944Sobrien      break;
51598944Sobrien
51698944Sobrien    case TYPE_CODE_ERROR:
51798944Sobrien      fprintf_filtered (stream, "<error type>");
51898944Sobrien      break;
51998944Sobrien
52098944Sobrien    case TYPE_CODE_UNDEF:
52198944Sobrien      /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
52298944Sobrien         dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
52398944Sobrien         and no complete type for struct foo in that file.  */
52498944Sobrien      fprintf_filtered (stream, "<incomplete type>");
52598944Sobrien      break;
52698944Sobrien
52798944Sobrien    default:
52898944Sobrien      error ("Invalid pascal type code %d in symbol table.", TYPE_CODE (type));
52998944Sobrien    }
53098944Sobrien  gdb_flush (stream);
53198944Sobrien  return (0);
53298944Sobrien}
53398944Sobrien
53498944Sobrienint
53598944Sobrienpascal_value_print (struct value *val, struct ui_file *stream, int format,
53698944Sobrien		    enum val_prettyprint pretty)
53798944Sobrien{
53898944Sobrien  struct type *type = VALUE_TYPE (val);
53998944Sobrien
54098944Sobrien  /* If it is a pointer, indicate what it points to.
54198944Sobrien
54298944Sobrien     Print type also if it is a reference.
54398944Sobrien
54498944Sobrien     Object pascal: if it is a member pointer, we will take care
54598944Sobrien     of that when we print it.  */
54698944Sobrien  if (TYPE_CODE (type) == TYPE_CODE_PTR ||
54798944Sobrien      TYPE_CODE (type) == TYPE_CODE_REF)
54898944Sobrien    {
54998944Sobrien      /* Hack:  remove (char *) for char strings.  Their
55098944Sobrien         type is indicated by the quoted string anyway. */
55198944Sobrien      if (TYPE_CODE (type) == TYPE_CODE_PTR &&
55298944Sobrien	  TYPE_NAME (type) == NULL &&
553130803Smarcel	  TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL
554130803Smarcel	  && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0)
55598944Sobrien	{
55698944Sobrien	  /* Print nothing */
55798944Sobrien	}
55898944Sobrien      else
55998944Sobrien	{
56098944Sobrien	  fprintf_filtered (stream, "(");
56198944Sobrien	  type_print (type, "", stream, -1);
56298944Sobrien	  fprintf_filtered (stream, ") ");
56398944Sobrien	}
56498944Sobrien    }
565242936Semaste  return common_val_print (val, stream, format, 1, 0, pretty);
56698944Sobrien}
56798944Sobrien
56898944Sobrien
56998944Sobrien/******************************************************************************
57098944Sobrien                    Inserted from cp-valprint
57198944Sobrien******************************************************************************/
57298944Sobrien
57398944Sobrienextern int vtblprint;		/* Controls printing of vtbl's */
57498944Sobrienextern int objectprint;		/* Controls looking up an object's derived type
57598944Sobrien				   using what we find in its vtables.  */
57698944Sobrienstatic int pascal_static_field_print;	/* Controls printing of static fields. */
57798944Sobrien
57898944Sobrienstatic struct obstack dont_print_vb_obstack;
57998944Sobrienstatic struct obstack dont_print_statmem_obstack;
58098944Sobrien
581242936Semastestatic void pascal_object_print_static_field (struct value *,
58298944Sobrien					      struct ui_file *, int, int,
58398944Sobrien					      enum val_prettyprint);
58498944Sobrien
58598944Sobrienstatic void
58698944Sobrien  pascal_object_print_value (struct type *, char *, CORE_ADDR, struct ui_file *,
58798944Sobrien			     int, int, enum val_prettyprint, struct type **);
58898944Sobrien
58998944Sobrienvoid
59098944Sobrienpascal_object_print_class_method (char *valaddr, struct type *type,
59198944Sobrien				  struct ui_file *stream)
59298944Sobrien{
59398944Sobrien  struct type *domain;
59498944Sobrien  struct fn_field *f = NULL;
59598944Sobrien  int j = 0;
59698944Sobrien  int len2;
59798944Sobrien  int offset;
59898944Sobrien  char *kind = "";
59998944Sobrien  CORE_ADDR addr;
60098944Sobrien  struct symbol *sym;
60198944Sobrien  unsigned len;
60298944Sobrien  unsigned int i;
60398944Sobrien  struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
60498944Sobrien
60598944Sobrien  domain = TYPE_DOMAIN_TYPE (target_type);
60698944Sobrien  if (domain == (struct type *) NULL)
60798944Sobrien    {
60898944Sobrien      fprintf_filtered (stream, "<unknown>");
60998944Sobrien      return;
61098944Sobrien    }
61198944Sobrien  addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
61298944Sobrien  if (METHOD_PTR_IS_VIRTUAL (addr))
61398944Sobrien    {
61498944Sobrien      offset = METHOD_PTR_TO_VOFFSET (addr);
61598944Sobrien      len = TYPE_NFN_FIELDS (domain);
61698944Sobrien      for (i = 0; i < len; i++)
61798944Sobrien	{
61898944Sobrien	  f = TYPE_FN_FIELDLIST1 (domain, i);
61998944Sobrien	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
62098944Sobrien
621130803Smarcel	  check_stub_method_group (domain, i);
62298944Sobrien	  for (j = 0; j < len2; j++)
62398944Sobrien	    {
62498944Sobrien	      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
62598944Sobrien		{
62698944Sobrien		  kind = "virtual ";
62798944Sobrien		  goto common;
62898944Sobrien		}
62998944Sobrien	    }
63098944Sobrien	}
63198944Sobrien    }
63298944Sobrien  else
63398944Sobrien    {
63498944Sobrien      sym = find_pc_function (addr);
63598944Sobrien      if (sym == 0)
63698944Sobrien	{
63798944Sobrien	  error ("invalid pointer to member function");
63898944Sobrien	}
63998944Sobrien      len = TYPE_NFN_FIELDS (domain);
64098944Sobrien      for (i = 0; i < len; i++)
64198944Sobrien	{
64298944Sobrien	  f = TYPE_FN_FIELDLIST1 (domain, i);
64398944Sobrien	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
64498944Sobrien
645130803Smarcel	  check_stub_method_group (domain, i);
64698944Sobrien	  for (j = 0; j < len2; j++)
64798944Sobrien	    {
648130803Smarcel	      if (DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
649130803Smarcel		goto common;
65098944Sobrien	    }
65198944Sobrien	}
65298944Sobrien    }
65398944Sobriencommon:
65498944Sobrien  if (i < len)
65598944Sobrien    {
65698944Sobrien      char *demangled_name;
65798944Sobrien
65898944Sobrien      fprintf_filtered (stream, "&");
659130803Smarcel      fputs_filtered (kind, stream);
66098944Sobrien      demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
66198944Sobrien				       DMGL_ANSI | DMGL_PARAMS);
66298944Sobrien      if (demangled_name == NULL)
66398944Sobrien	fprintf_filtered (stream, "<badly mangled name %s>",
66498944Sobrien			  TYPE_FN_FIELD_PHYSNAME (f, j));
66598944Sobrien      else
66698944Sobrien	{
66798944Sobrien	  fputs_filtered (demangled_name, stream);
66898944Sobrien	  xfree (demangled_name);
66998944Sobrien	}
67098944Sobrien    }
67198944Sobrien  else
67298944Sobrien    {
67398944Sobrien      fprintf_filtered (stream, "(");
67498944Sobrien      type_print (type, "", stream, -1);
67598944Sobrien      fprintf_filtered (stream, ") %d", (int) addr >> 3);
67698944Sobrien    }
67798944Sobrien}
67898944Sobrien
67998944Sobrien/* It was changed to this after 2.4.5.  */
68098944Sobrienconst char pascal_vtbl_ptr_name[] =
68198944Sobrien{'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};
68298944Sobrien
68398944Sobrien/* Return truth value for assertion that TYPE is of the type
68498944Sobrien   "pointer to virtual function".  */
68598944Sobrien
68698944Sobrienint
68798944Sobrienpascal_object_is_vtbl_ptr_type (struct type *type)
68898944Sobrien{
68998944Sobrien  char *typename = type_name_no_tag (type);
69098944Sobrien
69198944Sobrien  return (typename != NULL
692130803Smarcel	  && strcmp (typename, pascal_vtbl_ptr_name) == 0);
69398944Sobrien}
69498944Sobrien
69598944Sobrien/* Return truth value for the assertion that TYPE is of the type
69698944Sobrien   "pointer to virtual function table".  */
69798944Sobrien
69898944Sobrienint
69998944Sobrienpascal_object_is_vtbl_member (struct type *type)
70098944Sobrien{
70198944Sobrien  if (TYPE_CODE (type) == TYPE_CODE_PTR)
70298944Sobrien    {
70398944Sobrien      type = TYPE_TARGET_TYPE (type);
70498944Sobrien      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
70598944Sobrien	{
70698944Sobrien	  type = TYPE_TARGET_TYPE (type);
70798944Sobrien	  if (TYPE_CODE (type) == TYPE_CODE_STRUCT	/* if not using thunks */
70898944Sobrien	      || TYPE_CODE (type) == TYPE_CODE_PTR)	/* if using thunks */
70998944Sobrien	    {
71098944Sobrien	      /* Virtual functions tables are full of pointers
71198944Sobrien	         to virtual functions. */
71298944Sobrien	      return pascal_object_is_vtbl_ptr_type (type);
71398944Sobrien	    }
71498944Sobrien	}
71598944Sobrien    }
71698944Sobrien  return 0;
71798944Sobrien}
71898944Sobrien
71998944Sobrien/* Mutually recursive subroutines of pascal_object_print_value and c_val_print to
72098944Sobrien   print out a structure's fields: pascal_object_print_value_fields and pascal_object_print_value.
72198944Sobrien
72298944Sobrien   TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
72398944Sobrien   same meanings as in pascal_object_print_value and c_val_print.
72498944Sobrien
72598944Sobrien   DONT_PRINT is an array of baseclass types that we
72698944Sobrien   should not print, or zero if called from top level.  */
72798944Sobrien
72898944Sobrienvoid
72998944Sobrienpascal_object_print_value_fields (struct type *type, char *valaddr,
73098944Sobrien				  CORE_ADDR address, struct ui_file *stream,
73198944Sobrien				  int format, int recurse,
73298944Sobrien				  enum val_prettyprint pretty,
73398944Sobrien				  struct type **dont_print_vb,
73498944Sobrien				  int dont_print_statmem)
73598944Sobrien{
73698944Sobrien  int i, len, n_baseclasses;
73798944Sobrien  struct obstack tmp_obstack;
73898944Sobrien  char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
73998944Sobrien
74098944Sobrien  CHECK_TYPEDEF (type);
74198944Sobrien
74298944Sobrien  fprintf_filtered (stream, "{");
74398944Sobrien  len = TYPE_NFIELDS (type);
74498944Sobrien  n_baseclasses = TYPE_N_BASECLASSES (type);
74598944Sobrien
74698944Sobrien  /* Print out baseclasses such that we don't print
74798944Sobrien     duplicates of virtual baseclasses.  */
74898944Sobrien  if (n_baseclasses > 0)
74998944Sobrien    pascal_object_print_value (type, valaddr, address, stream,
75098944Sobrien			       format, recurse + 1, pretty, dont_print_vb);
75198944Sobrien
75298944Sobrien  if (!len && n_baseclasses == 1)
75398944Sobrien    fprintf_filtered (stream, "<No data fields>");
75498944Sobrien  else
75598944Sobrien    {
75698944Sobrien      int fields_seen = 0;
75798944Sobrien
75898944Sobrien      if (dont_print_statmem == 0)
75998944Sobrien	{
76098944Sobrien	  /* If we're at top level, carve out a completely fresh
76198944Sobrien	     chunk of the obstack and use that until this particular
76298944Sobrien	     invocation returns.  */
76398944Sobrien	  tmp_obstack = dont_print_statmem_obstack;
76498944Sobrien	  obstack_finish (&dont_print_statmem_obstack);
76598944Sobrien	}
76698944Sobrien
76798944Sobrien      for (i = n_baseclasses; i < len; i++)
76898944Sobrien	{
76998944Sobrien	  /* If requested, skip printing of static fields.  */
77098944Sobrien	  if (!pascal_static_field_print && TYPE_FIELD_STATIC (type, i))
77198944Sobrien	    continue;
77298944Sobrien	  if (fields_seen)
77398944Sobrien	    fprintf_filtered (stream, ", ");
77498944Sobrien	  else if (n_baseclasses > 0)
77598944Sobrien	    {
77698944Sobrien	      if (pretty)
77798944Sobrien		{
77898944Sobrien		  fprintf_filtered (stream, "\n");
77998944Sobrien		  print_spaces_filtered (2 + 2 * recurse, stream);
78098944Sobrien		  fputs_filtered ("members of ", stream);
78198944Sobrien		  fputs_filtered (type_name_no_tag (type), stream);
78298944Sobrien		  fputs_filtered (": ", stream);
78398944Sobrien		}
78498944Sobrien	    }
78598944Sobrien	  fields_seen = 1;
78698944Sobrien
78798944Sobrien	  if (pretty)
78898944Sobrien	    {
78998944Sobrien	      fprintf_filtered (stream, "\n");
79098944Sobrien	      print_spaces_filtered (2 + 2 * recurse, stream);
79198944Sobrien	    }
79298944Sobrien	  else
79398944Sobrien	    {
79498944Sobrien	      wrap_here (n_spaces (2 + 2 * recurse));
79598944Sobrien	    }
79698944Sobrien	  if (inspect_it)
79798944Sobrien	    {
79898944Sobrien	      if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
79998944Sobrien		fputs_filtered ("\"( ptr \"", stream);
80098944Sobrien	      else
80198944Sobrien		fputs_filtered ("\"( nodef \"", stream);
80298944Sobrien	      if (TYPE_FIELD_STATIC (type, i))
80398944Sobrien		fputs_filtered ("static ", stream);
80498944Sobrien	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
80598944Sobrien				       language_cplus,
80698944Sobrien				       DMGL_PARAMS | DMGL_ANSI);
80798944Sobrien	      fputs_filtered ("\" \"", stream);
80898944Sobrien	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
80998944Sobrien				       language_cplus,
81098944Sobrien				       DMGL_PARAMS | DMGL_ANSI);
81198944Sobrien	      fputs_filtered ("\") \"", stream);
81298944Sobrien	    }
81398944Sobrien	  else
81498944Sobrien	    {
81598944Sobrien	      annotate_field_begin (TYPE_FIELD_TYPE (type, i));
81698944Sobrien
81798944Sobrien	      if (TYPE_FIELD_STATIC (type, i))
81898944Sobrien		fputs_filtered ("static ", stream);
81998944Sobrien	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
82098944Sobrien				       language_cplus,
82198944Sobrien				       DMGL_PARAMS | DMGL_ANSI);
82298944Sobrien	      annotate_field_name_end ();
82398944Sobrien	      fputs_filtered (" = ", stream);
82498944Sobrien	      annotate_field_value ();
82598944Sobrien	    }
82698944Sobrien
82798944Sobrien	  if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
82898944Sobrien	    {
82998944Sobrien	      struct value *v;
83098944Sobrien
83198944Sobrien	      /* Bitfields require special handling, especially due to byte
83298944Sobrien	         order problems.  */
83398944Sobrien	      if (TYPE_FIELD_IGNORE (type, i))
83498944Sobrien		{
83598944Sobrien		  fputs_filtered ("<optimized out or zero length>", stream);
83698944Sobrien		}
83798944Sobrien	      else
83898944Sobrien		{
83998944Sobrien		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
84098944Sobrien				   unpack_field_as_long (type, valaddr, i));
84198944Sobrien
842242936Semaste		  common_val_print (v, stream, format, 0, recurse + 1, pretty);
84398944Sobrien		}
84498944Sobrien	    }
84598944Sobrien	  else
84698944Sobrien	    {
84798944Sobrien	      if (TYPE_FIELD_IGNORE (type, i))
84898944Sobrien		{
84998944Sobrien		  fputs_filtered ("<optimized out or zero length>", stream);
85098944Sobrien		}
85198944Sobrien	      else if (TYPE_FIELD_STATIC (type, i))
85298944Sobrien		{
85398944Sobrien		  /* struct value *v = value_static_field (type, i); v4.17 specific */
85498944Sobrien		  struct value *v;
85598944Sobrien		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
85698944Sobrien				   unpack_field_as_long (type, valaddr, i));
85798944Sobrien
85898944Sobrien		  if (v == NULL)
85998944Sobrien		    fputs_filtered ("<optimized out>", stream);
86098944Sobrien		  else
861242936Semaste		    pascal_object_print_static_field (v, stream, format,
862242936Semaste						      recurse + 1, pretty);
86398944Sobrien		}
86498944Sobrien	      else
86598944Sobrien		{
86698944Sobrien		  /* val_print (TYPE_FIELD_TYPE (type, i),
86798944Sobrien		     valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
86898944Sobrien		     address + TYPE_FIELD_BITPOS (type, i) / 8, 0,
86998944Sobrien		     stream, format, 0, recurse + 1, pretty); */
87098944Sobrien		  val_print (TYPE_FIELD_TYPE (type, i),
87198944Sobrien			     valaddr, TYPE_FIELD_BITPOS (type, i) / 8,
87298944Sobrien			     address + TYPE_FIELD_BITPOS (type, i) / 8,
87398944Sobrien			     stream, format, 0, recurse + 1, pretty);
87498944Sobrien		}
87598944Sobrien	    }
87698944Sobrien	  annotate_field_end ();
87798944Sobrien	}
87898944Sobrien
87998944Sobrien      if (dont_print_statmem == 0)
88098944Sobrien	{
88198944Sobrien	  /* Free the space used to deal with the printing
88298944Sobrien	     of the members from top level.  */
88398944Sobrien	  obstack_free (&dont_print_statmem_obstack, last_dont_print);
88498944Sobrien	  dont_print_statmem_obstack = tmp_obstack;
88598944Sobrien	}
88698944Sobrien
88798944Sobrien      if (pretty)
88898944Sobrien	{
88998944Sobrien	  fprintf_filtered (stream, "\n");
89098944Sobrien	  print_spaces_filtered (2 * recurse, stream);
89198944Sobrien	}
89298944Sobrien    }
89398944Sobrien  fprintf_filtered (stream, "}");
89498944Sobrien}
89598944Sobrien
89698944Sobrien/* Special val_print routine to avoid printing multiple copies of virtual
89798944Sobrien   baseclasses.  */
89898944Sobrien
89998944Sobrienvoid
90098944Sobrienpascal_object_print_value (struct type *type, char *valaddr, CORE_ADDR address,
90198944Sobrien			   struct ui_file *stream, int format, int recurse,
90298944Sobrien			   enum val_prettyprint pretty,
90398944Sobrien			   struct type **dont_print_vb)
90498944Sobrien{
90598944Sobrien  struct obstack tmp_obstack;
90698944Sobrien  struct type **last_dont_print
90798944Sobrien  = (struct type **) obstack_next_free (&dont_print_vb_obstack);
90898944Sobrien  int i, n_baseclasses = TYPE_N_BASECLASSES (type);
90998944Sobrien
91098944Sobrien  if (dont_print_vb == 0)
91198944Sobrien    {
91298944Sobrien      /* If we're at top level, carve out a completely fresh
91398944Sobrien         chunk of the obstack and use that until this particular
91498944Sobrien         invocation returns.  */
91598944Sobrien      tmp_obstack = dont_print_vb_obstack;
91698944Sobrien      /* Bump up the high-water mark.  Now alpha is omega.  */
91798944Sobrien      obstack_finish (&dont_print_vb_obstack);
91898944Sobrien    }
91998944Sobrien
92098944Sobrien  for (i = 0; i < n_baseclasses; i++)
92198944Sobrien    {
92298944Sobrien      int boffset;
92398944Sobrien      struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
92498944Sobrien      char *basename = TYPE_NAME (baseclass);
92598944Sobrien      char *base_valaddr;
92698944Sobrien
92798944Sobrien      if (BASETYPE_VIA_VIRTUAL (type, i))
92898944Sobrien	{
92998944Sobrien	  struct type **first_dont_print
93098944Sobrien	  = (struct type **) obstack_base (&dont_print_vb_obstack);
93198944Sobrien
93298944Sobrien	  int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
93398944Sobrien	  - first_dont_print;
93498944Sobrien
93598944Sobrien	  while (--j >= 0)
93698944Sobrien	    if (baseclass == first_dont_print[j])
93798944Sobrien	      goto flush_it;
93898944Sobrien
93998944Sobrien	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
94098944Sobrien	}
94198944Sobrien
94298944Sobrien      boffset = baseclass_offset (type, i, valaddr, address);
94398944Sobrien
94498944Sobrien      if (pretty)
94598944Sobrien	{
94698944Sobrien	  fprintf_filtered (stream, "\n");
94798944Sobrien	  print_spaces_filtered (2 * recurse, stream);
94898944Sobrien	}
94998944Sobrien      fputs_filtered ("<", stream);
95098944Sobrien      /* Not sure what the best notation is in the case where there is no
95198944Sobrien         baseclass name.  */
95298944Sobrien
95398944Sobrien      fputs_filtered (basename ? basename : "", stream);
95498944Sobrien      fputs_filtered ("> = ", stream);
95598944Sobrien
95698944Sobrien      /* The virtual base class pointer might have been clobbered by the
95798944Sobrien         user program. Make sure that it still points to a valid memory
95898944Sobrien         location.  */
95998944Sobrien
96098944Sobrien      if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type)))
96198944Sobrien	{
96298944Sobrien	  /* FIXME (alloc): not safe is baseclass is really really big. */
96398944Sobrien	  base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
96498944Sobrien	  if (target_read_memory (address + boffset, base_valaddr,
96598944Sobrien				  TYPE_LENGTH (baseclass)) != 0)
96698944Sobrien	    boffset = -1;
96798944Sobrien	}
96898944Sobrien      else
96998944Sobrien	base_valaddr = valaddr + boffset;
97098944Sobrien
97198944Sobrien      if (boffset == -1)
97298944Sobrien	fprintf_filtered (stream, "<invalid address>");
97398944Sobrien      else
97498944Sobrien	pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset,
97598944Sobrien					  stream, format, recurse, pretty,
97698944Sobrien		     (struct type **) obstack_base (&dont_print_vb_obstack),
97798944Sobrien					  0);
97898944Sobrien      fputs_filtered (", ", stream);
97998944Sobrien
98098944Sobrien    flush_it:
98198944Sobrien      ;
98298944Sobrien    }
98398944Sobrien
98498944Sobrien  if (dont_print_vb == 0)
98598944Sobrien    {
98698944Sobrien      /* Free the space used to deal with the printing
98798944Sobrien         of this type from top level.  */
98898944Sobrien      obstack_free (&dont_print_vb_obstack, last_dont_print);
98998944Sobrien      /* Reset watermark so that we can continue protecting
99098944Sobrien         ourselves from whatever we were protecting ourselves.  */
99198944Sobrien      dont_print_vb_obstack = tmp_obstack;
99298944Sobrien    }
99398944Sobrien}
99498944Sobrien
99598944Sobrien/* Print value of a static member.
99698944Sobrien   To avoid infinite recursion when printing a class that contains
99798944Sobrien   a static instance of the class, we keep the addresses of all printed
99898944Sobrien   static member classes in an obstack and refuse to print them more
99998944Sobrien   than once.
100098944Sobrien
1001242936Semaste   VAL contains the value to print, STREAM, RECURSE, and PRETTY
100298944Sobrien   have the same meanings as in c_val_print.  */
100398944Sobrien
100498944Sobrienstatic void
1005242936Semastepascal_object_print_static_field (struct value *val,
100698944Sobrien				  struct ui_file *stream, int format,
100798944Sobrien				  int recurse, enum val_prettyprint pretty)
100898944Sobrien{
1009242936Semaste  struct type *type = VALUE_TYPE (val);
1010242936Semaste
101198944Sobrien  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
101298944Sobrien    {
101398944Sobrien      CORE_ADDR *first_dont_print;
101498944Sobrien      int i;
101598944Sobrien
101698944Sobrien      first_dont_print
101798944Sobrien	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
101898944Sobrien      i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
101998944Sobrien	- first_dont_print;
102098944Sobrien
102198944Sobrien      while (--i >= 0)
102298944Sobrien	{
102398944Sobrien	  if (VALUE_ADDRESS (val) == first_dont_print[i])
102498944Sobrien	    {
102598944Sobrien	      fputs_filtered ("<same as static member of an already seen type>",
102698944Sobrien			      stream);
102798944Sobrien	      return;
102898944Sobrien	    }
102998944Sobrien	}
103098944Sobrien
103198944Sobrien      obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
103298944Sobrien		    sizeof (CORE_ADDR));
103398944Sobrien
103498944Sobrien      CHECK_TYPEDEF (type);
103598944Sobrien      pascal_object_print_value_fields (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
103698944Sobrien				  stream, format, recurse, pretty, NULL, 1);
103798944Sobrien      return;
103898944Sobrien    }
1039242936Semaste  common_val_print (val, stream, format, 0, recurse, pretty);
104098944Sobrien}
104198944Sobrien
104298944Sobrienvoid
104398944Sobrienpascal_object_print_class_member (char *valaddr, struct type *domain,
104498944Sobrien				  struct ui_file *stream, char *prefix)
104598944Sobrien{
104698944Sobrien
104798944Sobrien  /* VAL is a byte offset into the structure type DOMAIN.
104898944Sobrien     Find the name of the field for that offset and
104998944Sobrien     print it.  */
105098944Sobrien  int extra = 0;
105198944Sobrien  int bits = 0;
1052130803Smarcel  unsigned int i;
105398944Sobrien  unsigned len = TYPE_NFIELDS (domain);
105498944Sobrien  /* @@ Make VAL into bit offset */
105598944Sobrien  LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
105698944Sobrien  for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
105798944Sobrien    {
105898944Sobrien      int bitpos = TYPE_FIELD_BITPOS (domain, i);
105998944Sobrien      QUIT;
106098944Sobrien      if (val == bitpos)
106198944Sobrien	break;
106298944Sobrien      if (val < bitpos && i != 0)
106398944Sobrien	{
106498944Sobrien	  /* Somehow pointing into a field.  */
106598944Sobrien	  i -= 1;
106698944Sobrien	  extra = (val - TYPE_FIELD_BITPOS (domain, i));
106798944Sobrien	  if (extra & 0x7)
106898944Sobrien	    bits = 1;
106998944Sobrien	  else
107098944Sobrien	    extra >>= 3;
107198944Sobrien	  break;
107298944Sobrien	}
107398944Sobrien    }
107498944Sobrien  if (i < len)
107598944Sobrien    {
107698944Sobrien      char *name;
1077130803Smarcel      fputs_filtered (prefix, stream);
107898944Sobrien      name = type_name_no_tag (domain);
107998944Sobrien      if (name)
108098944Sobrien	fputs_filtered (name, stream);
108198944Sobrien      else
108298944Sobrien	pascal_type_print_base (domain, stream, 0, 0);
108398944Sobrien      fprintf_filtered (stream, "::");
108498944Sobrien      fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
108598944Sobrien      if (extra)
108698944Sobrien	fprintf_filtered (stream, " + %d bytes", extra);
108798944Sobrien      if (bits)
108898944Sobrien	fprintf_filtered (stream, " (offset in bits)");
108998944Sobrien    }
109098944Sobrien  else
109198944Sobrien    fprintf_filtered (stream, "%ld", (long int) (val >> 3));
109298944Sobrien}
109398944Sobrien
1094130803Smarcelextern initialize_file_ftype _initialize_pascal_valprint; /* -Wmissing-prototypes */
109598944Sobrien
109698944Sobrienvoid
109798944Sobrien_initialize_pascal_valprint (void)
109898944Sobrien{
109998944Sobrien  add_show_from_set
110098944Sobrien    (add_set_cmd ("pascal_static-members", class_support, var_boolean,
110198944Sobrien		  (char *) &pascal_static_field_print,
110298944Sobrien		  "Set printing of pascal static members.",
110398944Sobrien		  &setprintlist),
110498944Sobrien     &showprintlist);
110598944Sobrien  /* Turn on printing of static fields.  */
110698944Sobrien  pascal_static_field_print = 1;
110798944Sobrien
110898944Sobrien}
1109