xref: /openbsd-src/gnu/usr.bin/binutils/gdb/p-valprint.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Support for printing Pascal values for GDB, the GNU debugger.
2b725ae77Skettenis    Copyright 2000, 2001, 2003
3b725ae77Skettenis    Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20b725ae77Skettenis 
21b725ae77Skettenis /* This file is derived from c-valprint.c */
22b725ae77Skettenis 
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "gdb_obstack.h"
25b725ae77Skettenis #include "symtab.h"
26b725ae77Skettenis #include "gdbtypes.h"
27b725ae77Skettenis #include "expression.h"
28b725ae77Skettenis #include "value.h"
29b725ae77Skettenis #include "command.h"
30b725ae77Skettenis #include "gdbcmd.h"
31b725ae77Skettenis #include "gdbcore.h"
32b725ae77Skettenis #include "demangle.h"
33b725ae77Skettenis #include "valprint.h"
34b725ae77Skettenis #include "typeprint.h"
35b725ae77Skettenis #include "language.h"
36b725ae77Skettenis #include "target.h"
37b725ae77Skettenis #include "annotate.h"
38b725ae77Skettenis #include "p-lang.h"
39b725ae77Skettenis #include "cp-abi.h"
40b725ae77Skettenis 
41b725ae77Skettenis 
42b725ae77Skettenis 
43b725ae77Skettenis 
44b725ae77Skettenis /* Print data of type TYPE located at VALADDR (within GDB), which came from
45b725ae77Skettenis    the inferior at address ADDRESS, onto stdio stream STREAM according to
46b725ae77Skettenis    FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
47b725ae77Skettenis    target byte order.
48b725ae77Skettenis 
49b725ae77Skettenis    If the data are a string pointer, returns the number of string characters
50b725ae77Skettenis    printed.
51b725ae77Skettenis 
52b725ae77Skettenis    If DEREF_REF is nonzero, then dereference references, otherwise just print
53b725ae77Skettenis    them like pointers.
54b725ae77Skettenis 
55b725ae77Skettenis    The PRETTY parameter controls prettyprinting.  */
56b725ae77Skettenis 
57b725ae77Skettenis 
58b725ae77Skettenis int
pascal_val_print(struct type * type,char * valaddr,int embedded_offset,CORE_ADDR address,struct ui_file * stream,int format,int deref_ref,int recurse,enum val_prettyprint pretty)59b725ae77Skettenis pascal_val_print (struct type *type, char *valaddr, int embedded_offset,
60b725ae77Skettenis 		  CORE_ADDR address, struct ui_file *stream, int format,
61b725ae77Skettenis 		  int deref_ref, int recurse, enum val_prettyprint pretty)
62b725ae77Skettenis {
63b725ae77Skettenis   unsigned int i = 0;	/* Number of characters printed */
64b725ae77Skettenis   unsigned len;
65b725ae77Skettenis   struct type *elttype;
66b725ae77Skettenis   unsigned eltlen;
67b725ae77Skettenis   int length_pos, length_size, string_pos;
68b725ae77Skettenis   int char_size;
69b725ae77Skettenis   LONGEST val;
70b725ae77Skettenis   CORE_ADDR addr;
71b725ae77Skettenis 
72b725ae77Skettenis   CHECK_TYPEDEF (type);
73b725ae77Skettenis   switch (TYPE_CODE (type))
74b725ae77Skettenis     {
75b725ae77Skettenis     case TYPE_CODE_ARRAY:
76b725ae77Skettenis       if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
77b725ae77Skettenis 	{
78b725ae77Skettenis 	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
79b725ae77Skettenis 	  eltlen = TYPE_LENGTH (elttype);
80b725ae77Skettenis 	  len = TYPE_LENGTH (type) / eltlen;
81b725ae77Skettenis 	  if (prettyprint_arrays)
82b725ae77Skettenis 	    {
83b725ae77Skettenis 	      print_spaces_filtered (2 + 2 * recurse, stream);
84b725ae77Skettenis 	    }
85b725ae77Skettenis 	  /* For an array of chars, print with string syntax.  */
86b725ae77Skettenis 	  if (eltlen == 1 &&
87b725ae77Skettenis 	      ((TYPE_CODE (elttype) == TYPE_CODE_INT)
88b725ae77Skettenis 	       || ((current_language->la_language == language_m2)
89b725ae77Skettenis 		   && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
90b725ae77Skettenis 	      && (format == 0 || format == 's'))
91b725ae77Skettenis 	    {
92b725ae77Skettenis 	      /* If requested, look for the first null char and only print
93b725ae77Skettenis 	         elements up to it.  */
94b725ae77Skettenis 	      if (stop_print_at_null)
95b725ae77Skettenis 		{
96b725ae77Skettenis 		  unsigned int temp_len;
97b725ae77Skettenis 
98b725ae77Skettenis 		  /* Look for a NULL char. */
99b725ae77Skettenis 		  for (temp_len = 0;
100b725ae77Skettenis 		       (valaddr + embedded_offset)[temp_len]
101b725ae77Skettenis 		       && temp_len < len && temp_len < print_max;
102b725ae77Skettenis 		       temp_len++);
103b725ae77Skettenis 		  len = temp_len;
104b725ae77Skettenis 		}
105b725ae77Skettenis 
106b725ae77Skettenis 	      LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0);
107b725ae77Skettenis 	      i = len;
108b725ae77Skettenis 	    }
109b725ae77Skettenis 	  else
110b725ae77Skettenis 	    {
111b725ae77Skettenis 	      fprintf_filtered (stream, "{");
112b725ae77Skettenis 	      /* If this is a virtual function table, print the 0th
113b725ae77Skettenis 	         entry specially, and the rest of the members normally.  */
114b725ae77Skettenis 	      if (pascal_object_is_vtbl_ptr_type (elttype))
115b725ae77Skettenis 		{
116b725ae77Skettenis 		  i = 1;
117b725ae77Skettenis 		  fprintf_filtered (stream, "%d vtable entries", len - 1);
118b725ae77Skettenis 		}
119b725ae77Skettenis 	      else
120b725ae77Skettenis 		{
121b725ae77Skettenis 		  i = 0;
122b725ae77Skettenis 		}
123b725ae77Skettenis 	      val_print_array_elements (type, valaddr + embedded_offset, address, stream,
124b725ae77Skettenis 				     format, deref_ref, recurse, pretty, i);
125b725ae77Skettenis 	      fprintf_filtered (stream, "}");
126b725ae77Skettenis 	    }
127b725ae77Skettenis 	  break;
128b725ae77Skettenis 	}
129b725ae77Skettenis       /* Array of unspecified length: treat like pointer to first elt.  */
130b725ae77Skettenis       addr = address;
131b725ae77Skettenis       goto print_unpacked_pointer;
132b725ae77Skettenis 
133b725ae77Skettenis     case TYPE_CODE_PTR:
134b725ae77Skettenis       if (format && format != 's')
135b725ae77Skettenis 	{
136b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
137b725ae77Skettenis 	  break;
138b725ae77Skettenis 	}
139b725ae77Skettenis       if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
140b725ae77Skettenis 	{
141b725ae77Skettenis 	  /* Print the unmangled name if desired.  */
142b725ae77Skettenis 	  /* Print vtable entry - we only get here if we ARE using
143b725ae77Skettenis 	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
144b725ae77Skettenis 	  /* Extract the address, assume that it is unsigned.  */
145b725ae77Skettenis 	  print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type)),
146b725ae77Skettenis 				  stream, demangle);
147b725ae77Skettenis 	  break;
148b725ae77Skettenis 	}
149b725ae77Skettenis       elttype = check_typedef (TYPE_TARGET_TYPE (type));
150b725ae77Skettenis       if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
151b725ae77Skettenis 	{
152b725ae77Skettenis 	  pascal_object_print_class_method (valaddr + embedded_offset, type, stream);
153b725ae77Skettenis 	}
154b725ae77Skettenis       else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
155b725ae77Skettenis 	{
156b725ae77Skettenis 	  pascal_object_print_class_member (valaddr + embedded_offset,
157b725ae77Skettenis 				 TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
158b725ae77Skettenis 					    stream, "&");
159b725ae77Skettenis 	}
160b725ae77Skettenis       else
161b725ae77Skettenis 	{
162b725ae77Skettenis 	  addr = unpack_pointer (type, valaddr + embedded_offset);
163b725ae77Skettenis 	print_unpacked_pointer:
164b725ae77Skettenis 	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
165b725ae77Skettenis 
166b725ae77Skettenis 	  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
167b725ae77Skettenis 	    {
168b725ae77Skettenis 	      /* Try to print what function it points to.  */
169b725ae77Skettenis 	      print_address_demangle (addr, stream, demangle);
170b725ae77Skettenis 	      /* Return value is irrelevant except for string pointers.  */
171b725ae77Skettenis 	      return (0);
172b725ae77Skettenis 	    }
173b725ae77Skettenis 
174b725ae77Skettenis 	  if (addressprint && format != 's')
175b725ae77Skettenis 	    {
176b725ae77Skettenis 	      print_address_numeric (addr, 1, stream);
177b725ae77Skettenis 	    }
178b725ae77Skettenis 
179b725ae77Skettenis 	  /* For a pointer to char or unsigned char, also print the string
180b725ae77Skettenis 	     pointed to, unless pointer is null.  */
181b725ae77Skettenis 	  if (TYPE_LENGTH (elttype) == 1
182b725ae77Skettenis 	      && TYPE_CODE (elttype) == TYPE_CODE_INT
183b725ae77Skettenis 	      && (format == 0 || format == 's')
184b725ae77Skettenis 	      && addr != 0)
185b725ae77Skettenis 	    {
186b725ae77Skettenis 	      /* no wide string yet */
187b725ae77Skettenis 	      i = val_print_string (addr, -1, 1, stream);
188b725ae77Skettenis 	    }
189b725ae77Skettenis 	  /* also for pointers to pascal strings */
190b725ae77Skettenis 	  /* Note: this is Free Pascal specific:
191b725ae77Skettenis 	     as GDB does not recognize stabs pascal strings
192b725ae77Skettenis 	     Pascal strings are mapped to records
193b725ae77Skettenis 	     with lowercase names PM  */
194b725ae77Skettenis           if (is_pascal_string_type (elttype, &length_pos, &length_size,
195b725ae77Skettenis                                      &string_pos, &char_size, NULL)
196b725ae77Skettenis 	      && addr != 0)
197b725ae77Skettenis 	    {
198b725ae77Skettenis 	      ULONGEST string_length;
199b725ae77Skettenis               void *buffer;
200b725ae77Skettenis               buffer = xmalloc (length_size);
201b725ae77Skettenis               read_memory (addr + length_pos, buffer, length_size);
202b725ae77Skettenis 	      string_length = extract_unsigned_integer (buffer, length_size);
203b725ae77Skettenis               xfree (buffer);
204b725ae77Skettenis               i = val_print_string (addr + string_pos, string_length, char_size, stream);
205b725ae77Skettenis 	    }
206b725ae77Skettenis 	  else if (pascal_object_is_vtbl_member (type))
207b725ae77Skettenis 	    {
208b725ae77Skettenis 	      /* print vtbl's nicely */
209b725ae77Skettenis 	      CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
210b725ae77Skettenis 
211b725ae77Skettenis 	      struct minimal_symbol *msymbol =
212b725ae77Skettenis 	      lookup_minimal_symbol_by_pc (vt_address);
213b725ae77Skettenis 	      if ((msymbol != NULL)
214b725ae77Skettenis 		  && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
215b725ae77Skettenis 		{
216b725ae77Skettenis 		  fputs_filtered (" <", stream);
217b725ae77Skettenis 		  fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream);
218b725ae77Skettenis 		  fputs_filtered (">", stream);
219b725ae77Skettenis 		}
220b725ae77Skettenis 	      if (vt_address && vtblprint)
221b725ae77Skettenis 		{
222b725ae77Skettenis 		  struct value *vt_val;
223b725ae77Skettenis 		  struct symbol *wsym = (struct symbol *) NULL;
224b725ae77Skettenis 		  struct type *wtype;
225b725ae77Skettenis 		  struct block *block = (struct block *) NULL;
226b725ae77Skettenis 		  int is_this_fld;
227b725ae77Skettenis 
228b725ae77Skettenis 		  if (msymbol != NULL)
229b725ae77Skettenis 		    wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block,
230b725ae77Skettenis 					  VAR_DOMAIN, &is_this_fld, NULL);
231b725ae77Skettenis 
232b725ae77Skettenis 		  if (wsym)
233b725ae77Skettenis 		    {
234b725ae77Skettenis 		      wtype = SYMBOL_TYPE (wsym);
235b725ae77Skettenis 		    }
236b725ae77Skettenis 		  else
237b725ae77Skettenis 		    {
238b725ae77Skettenis 		      wtype = TYPE_TARGET_TYPE (type);
239b725ae77Skettenis 		    }
240b725ae77Skettenis 		  vt_val = value_at (wtype, vt_address, NULL);
241b725ae77Skettenis 		  val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
242b725ae77Skettenis 			     VALUE_ADDRESS (vt_val), stream, format,
243b725ae77Skettenis 			     deref_ref, recurse + 1, pretty);
244b725ae77Skettenis 		  if (pretty)
245b725ae77Skettenis 		    {
246b725ae77Skettenis 		      fprintf_filtered (stream, "\n");
247b725ae77Skettenis 		      print_spaces_filtered (2 + 2 * recurse, stream);
248b725ae77Skettenis 		    }
249b725ae77Skettenis 		}
250b725ae77Skettenis 	    }
251b725ae77Skettenis 
252b725ae77Skettenis 	  /* Return number of characters printed, including the terminating
253b725ae77Skettenis 	     '\0' if we reached the end.  val_print_string takes care including
254b725ae77Skettenis 	     the terminating '\0' if necessary.  */
255b725ae77Skettenis 	  return i;
256b725ae77Skettenis 	}
257b725ae77Skettenis       break;
258b725ae77Skettenis 
259b725ae77Skettenis     case TYPE_CODE_MEMBER:
260b725ae77Skettenis       error ("not implemented: member type in pascal_val_print");
261b725ae77Skettenis       break;
262b725ae77Skettenis 
263b725ae77Skettenis     case TYPE_CODE_REF:
264b725ae77Skettenis       elttype = check_typedef (TYPE_TARGET_TYPE (type));
265b725ae77Skettenis       if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
266b725ae77Skettenis 	{
267b725ae77Skettenis 	  pascal_object_print_class_member (valaddr + embedded_offset,
268b725ae77Skettenis 					    TYPE_DOMAIN_TYPE (elttype),
269b725ae77Skettenis 					    stream, "");
270b725ae77Skettenis 	  break;
271b725ae77Skettenis 	}
272b725ae77Skettenis       if (addressprint)
273b725ae77Skettenis 	{
274b725ae77Skettenis 	  fprintf_filtered (stream, "@");
275b725ae77Skettenis 	  /* Extract the address, assume that it is unsigned.  */
276b725ae77Skettenis 	  print_address_numeric
277b725ae77Skettenis 	    (extract_unsigned_integer (valaddr + embedded_offset,
278b725ae77Skettenis 				       TARGET_PTR_BIT / HOST_CHAR_BIT),
279b725ae77Skettenis 	     1, stream);
280b725ae77Skettenis 	  if (deref_ref)
281b725ae77Skettenis 	    fputs_filtered (": ", stream);
282b725ae77Skettenis 	}
283b725ae77Skettenis       /* De-reference the reference.  */
284b725ae77Skettenis       if (deref_ref)
285b725ae77Skettenis 	{
286b725ae77Skettenis 	  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
287b725ae77Skettenis 	    {
288b725ae77Skettenis 	      struct value *deref_val =
289b725ae77Skettenis 	      value_at
290b725ae77Skettenis 	      (TYPE_TARGET_TYPE (type),
291b725ae77Skettenis 	       unpack_pointer (lookup_pointer_type (builtin_type_void),
292b725ae77Skettenis 			       valaddr + embedded_offset),
293b725ae77Skettenis 	       NULL);
294b725ae77Skettenis 	      val_print (VALUE_TYPE (deref_val),
295b725ae77Skettenis 			 VALUE_CONTENTS (deref_val), 0,
296b725ae77Skettenis 			 VALUE_ADDRESS (deref_val), stream, format,
297b725ae77Skettenis 			 deref_ref, recurse + 1, pretty);
298b725ae77Skettenis 	    }
299b725ae77Skettenis 	  else
300b725ae77Skettenis 	    fputs_filtered ("???", stream);
301b725ae77Skettenis 	}
302b725ae77Skettenis       break;
303b725ae77Skettenis 
304b725ae77Skettenis     case TYPE_CODE_UNION:
305b725ae77Skettenis       if (recurse && !unionprint)
306b725ae77Skettenis 	{
307b725ae77Skettenis 	  fprintf_filtered (stream, "{...}");
308b725ae77Skettenis 	  break;
309b725ae77Skettenis 	}
310b725ae77Skettenis       /* Fall through.  */
311b725ae77Skettenis     case TYPE_CODE_STRUCT:
312b725ae77Skettenis       if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
313b725ae77Skettenis 	{
314b725ae77Skettenis 	  /* Print the unmangled name if desired.  */
315b725ae77Skettenis 	  /* Print vtable entry - we only get here if NOT using
316b725ae77Skettenis 	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.) */
317b725ae77Skettenis 	  /* Extract the address, assume that it is unsigned.  */
318b725ae77Skettenis 	  print_address_demangle
319b725ae77Skettenis 	    (extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
320b725ae77Skettenis 				       TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
321b725ae77Skettenis 	     stream, demangle);
322b725ae77Skettenis 	}
323b725ae77Skettenis       else
324b725ae77Skettenis 	{
325b725ae77Skettenis           if (is_pascal_string_type (type, &length_pos, &length_size,
326b725ae77Skettenis                                      &string_pos, &char_size, NULL))
327b725ae77Skettenis 	    {
328b725ae77Skettenis 	      len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size);
329b725ae77Skettenis 	      LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0);
330b725ae77Skettenis 	    }
331b725ae77Skettenis 	  else
332b725ae77Skettenis 	    pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, format,
333b725ae77Skettenis 					      recurse, pretty, NULL, 0);
334b725ae77Skettenis 	}
335b725ae77Skettenis       break;
336b725ae77Skettenis 
337b725ae77Skettenis     case TYPE_CODE_ENUM:
338b725ae77Skettenis       if (format)
339b725ae77Skettenis 	{
340b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
341b725ae77Skettenis 	  break;
342b725ae77Skettenis 	}
343b725ae77Skettenis       len = TYPE_NFIELDS (type);
344b725ae77Skettenis       val = unpack_long (type, valaddr + embedded_offset);
345b725ae77Skettenis       for (i = 0; i < len; i++)
346b725ae77Skettenis 	{
347b725ae77Skettenis 	  QUIT;
348b725ae77Skettenis 	  if (val == TYPE_FIELD_BITPOS (type, i))
349b725ae77Skettenis 	    {
350b725ae77Skettenis 	      break;
351b725ae77Skettenis 	    }
352b725ae77Skettenis 	}
353b725ae77Skettenis       if (i < len)
354b725ae77Skettenis 	{
355b725ae77Skettenis 	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
356b725ae77Skettenis 	}
357b725ae77Skettenis       else
358b725ae77Skettenis 	{
359b725ae77Skettenis 	  print_longest (stream, 'd', 0, val);
360b725ae77Skettenis 	}
361b725ae77Skettenis       break;
362b725ae77Skettenis 
363b725ae77Skettenis     case TYPE_CODE_FUNC:
364b725ae77Skettenis       if (format)
365b725ae77Skettenis 	{
366b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
367b725ae77Skettenis 	  break;
368b725ae77Skettenis 	}
369b725ae77Skettenis       /* FIXME, we should consider, at least for ANSI C language, eliminating
370b725ae77Skettenis          the distinction made between FUNCs and POINTERs to FUNCs.  */
371b725ae77Skettenis       fprintf_filtered (stream, "{");
372b725ae77Skettenis       type_print (type, "", stream, -1);
373b725ae77Skettenis       fprintf_filtered (stream, "} ");
374b725ae77Skettenis       /* Try to print what function it points to, and its address.  */
375b725ae77Skettenis       print_address_demangle (address, stream, demangle);
376b725ae77Skettenis       break;
377b725ae77Skettenis 
378b725ae77Skettenis     case TYPE_CODE_BOOL:
379b725ae77Skettenis       format = format ? format : output_format;
380b725ae77Skettenis       if (format)
381b725ae77Skettenis 	print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
382b725ae77Skettenis       else
383b725ae77Skettenis 	{
384b725ae77Skettenis 	  val = unpack_long (type, valaddr + embedded_offset);
385b725ae77Skettenis 	  if (val == 0)
386b725ae77Skettenis 	    fputs_filtered ("false", stream);
387b725ae77Skettenis 	  else if (val == 1)
388b725ae77Skettenis 	    fputs_filtered ("true", stream);
389b725ae77Skettenis 	  else
390b725ae77Skettenis 	    {
391b725ae77Skettenis 	      fputs_filtered ("true (", stream);
392b725ae77Skettenis 	      fprintf_filtered (stream, "%ld)", (long int) val);
393b725ae77Skettenis 	    }
394b725ae77Skettenis 	}
395b725ae77Skettenis       break;
396b725ae77Skettenis 
397b725ae77Skettenis     case TYPE_CODE_RANGE:
398b725ae77Skettenis       /* FIXME: create_range_type does not set the unsigned bit in a
399b725ae77Skettenis          range type (I think it probably should copy it from the target
400b725ae77Skettenis          type), so we won't print values which are too large to
401b725ae77Skettenis          fit in a signed integer correctly.  */
402b725ae77Skettenis       /* FIXME: Doesn't handle ranges of enums correctly.  (Can't just
403b725ae77Skettenis          print with the target type, though, because the size of our type
404b725ae77Skettenis          and the target type might differ).  */
405b725ae77Skettenis       /* FALLTHROUGH */
406b725ae77Skettenis 
407b725ae77Skettenis     case TYPE_CODE_INT:
408b725ae77Skettenis       format = format ? format : output_format;
409b725ae77Skettenis       if (format)
410b725ae77Skettenis 	{
411b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
412b725ae77Skettenis 	}
413b725ae77Skettenis       else
414b725ae77Skettenis 	{
415b725ae77Skettenis 	  val_print_type_code_int (type, valaddr + embedded_offset, stream);
416b725ae77Skettenis 	}
417b725ae77Skettenis       break;
418b725ae77Skettenis 
419b725ae77Skettenis     case TYPE_CODE_CHAR:
420b725ae77Skettenis       format = format ? format : output_format;
421b725ae77Skettenis       if (format)
422b725ae77Skettenis 	{
423b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
424b725ae77Skettenis 	}
425b725ae77Skettenis       else
426b725ae77Skettenis 	{
427b725ae77Skettenis 	  val = unpack_long (type, valaddr + embedded_offset);
428b725ae77Skettenis 	  if (TYPE_UNSIGNED (type))
429b725ae77Skettenis 	    fprintf_filtered (stream, "%u", (unsigned int) val);
430b725ae77Skettenis 	  else
431b725ae77Skettenis 	    fprintf_filtered (stream, "%d", (int) val);
432b725ae77Skettenis 	  fputs_filtered (" ", stream);
433b725ae77Skettenis 	  LA_PRINT_CHAR ((unsigned char) val, stream);
434b725ae77Skettenis 	}
435b725ae77Skettenis       break;
436b725ae77Skettenis 
437b725ae77Skettenis     case TYPE_CODE_FLT:
438b725ae77Skettenis       if (format)
439b725ae77Skettenis 	{
440b725ae77Skettenis 	  print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
441b725ae77Skettenis 	}
442b725ae77Skettenis       else
443b725ae77Skettenis 	{
444b725ae77Skettenis 	  print_floating (valaddr + embedded_offset, type, stream);
445b725ae77Skettenis 	}
446b725ae77Skettenis       break;
447b725ae77Skettenis 
448b725ae77Skettenis     case TYPE_CODE_BITSTRING:
449b725ae77Skettenis     case TYPE_CODE_SET:
450b725ae77Skettenis       elttype = TYPE_INDEX_TYPE (type);
451b725ae77Skettenis       CHECK_TYPEDEF (elttype);
452b725ae77Skettenis       if (TYPE_STUB (elttype))
453b725ae77Skettenis 	{
454b725ae77Skettenis 	  fprintf_filtered (stream, "<incomplete type>");
455b725ae77Skettenis 	  gdb_flush (stream);
456b725ae77Skettenis 	  break;
457b725ae77Skettenis 	}
458b725ae77Skettenis       else
459b725ae77Skettenis 	{
460b725ae77Skettenis 	  struct type *range = elttype;
461b725ae77Skettenis 	  LONGEST low_bound, high_bound;
462b725ae77Skettenis 	  int i;
463b725ae77Skettenis 	  int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
464b725ae77Skettenis 	  int need_comma = 0;
465b725ae77Skettenis 
466b725ae77Skettenis 	  if (is_bitstring)
467b725ae77Skettenis 	    fputs_filtered ("B'", stream);
468b725ae77Skettenis 	  else
469b725ae77Skettenis 	    fputs_filtered ("[", stream);
470b725ae77Skettenis 
471b725ae77Skettenis 	  i = get_discrete_bounds (range, &low_bound, &high_bound);
472b725ae77Skettenis 	maybe_bad_bstring:
473b725ae77Skettenis 	  if (i < 0)
474b725ae77Skettenis 	    {
475b725ae77Skettenis 	      fputs_filtered ("<error value>", stream);
476b725ae77Skettenis 	      goto done;
477b725ae77Skettenis 	    }
478b725ae77Skettenis 
479b725ae77Skettenis 	  for (i = low_bound; i <= high_bound; i++)
480b725ae77Skettenis 	    {
481b725ae77Skettenis 	      int element = value_bit_index (type, valaddr + embedded_offset, i);
482b725ae77Skettenis 	      if (element < 0)
483b725ae77Skettenis 		{
484b725ae77Skettenis 		  i = element;
485b725ae77Skettenis 		  goto maybe_bad_bstring;
486b725ae77Skettenis 		}
487b725ae77Skettenis 	      if (is_bitstring)
488b725ae77Skettenis 		fprintf_filtered (stream, "%d", element);
489b725ae77Skettenis 	      else if (element)
490b725ae77Skettenis 		{
491b725ae77Skettenis 		  if (need_comma)
492b725ae77Skettenis 		    fputs_filtered (", ", stream);
493b725ae77Skettenis 		  print_type_scalar (range, i, stream);
494b725ae77Skettenis 		  need_comma = 1;
495b725ae77Skettenis 
496b725ae77Skettenis 		  if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i))
497b725ae77Skettenis 		    {
498b725ae77Skettenis 		      int j = i;
499b725ae77Skettenis 		      fputs_filtered ("..", stream);
500b725ae77Skettenis 		      while (i + 1 <= high_bound
501b725ae77Skettenis 			     && value_bit_index (type, valaddr + embedded_offset, ++i))
502b725ae77Skettenis 			j = i;
503b725ae77Skettenis 		      print_type_scalar (range, j, stream);
504b725ae77Skettenis 		    }
505b725ae77Skettenis 		}
506b725ae77Skettenis 	    }
507b725ae77Skettenis 	done:
508b725ae77Skettenis 	  if (is_bitstring)
509b725ae77Skettenis 	    fputs_filtered ("'", stream);
510b725ae77Skettenis 	  else
511b725ae77Skettenis 	    fputs_filtered ("]", stream);
512b725ae77Skettenis 	}
513b725ae77Skettenis       break;
514b725ae77Skettenis 
515b725ae77Skettenis     case TYPE_CODE_VOID:
516b725ae77Skettenis       fprintf_filtered (stream, "void");
517b725ae77Skettenis       break;
518b725ae77Skettenis 
519b725ae77Skettenis     case TYPE_CODE_ERROR:
520b725ae77Skettenis       fprintf_filtered (stream, "<error type>");
521b725ae77Skettenis       break;
522b725ae77Skettenis 
523b725ae77Skettenis     case TYPE_CODE_UNDEF:
524b725ae77Skettenis       /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
525b725ae77Skettenis          dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
526b725ae77Skettenis          and no complete type for struct foo in that file.  */
527b725ae77Skettenis       fprintf_filtered (stream, "<incomplete type>");
528b725ae77Skettenis       break;
529b725ae77Skettenis 
530b725ae77Skettenis     default:
531b725ae77Skettenis       error ("Invalid pascal type code %d in symbol table.", TYPE_CODE (type));
532b725ae77Skettenis     }
533b725ae77Skettenis   gdb_flush (stream);
534b725ae77Skettenis   return (0);
535b725ae77Skettenis }
536b725ae77Skettenis 
537b725ae77Skettenis int
pascal_value_print(struct value * val,struct ui_file * stream,int format,enum val_prettyprint pretty)538b725ae77Skettenis pascal_value_print (struct value *val, struct ui_file *stream, int format,
539b725ae77Skettenis 		    enum val_prettyprint pretty)
540b725ae77Skettenis {
541b725ae77Skettenis   struct type *type = VALUE_TYPE (val);
542b725ae77Skettenis 
543b725ae77Skettenis   /* If it is a pointer, indicate what it points to.
544b725ae77Skettenis 
545b725ae77Skettenis      Print type also if it is a reference.
546b725ae77Skettenis 
547b725ae77Skettenis      Object pascal: if it is a member pointer, we will take care
548b725ae77Skettenis      of that when we print it.  */
549b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_PTR ||
550b725ae77Skettenis       TYPE_CODE (type) == TYPE_CODE_REF)
551b725ae77Skettenis     {
552b725ae77Skettenis       /* Hack:  remove (char *) for char strings.  Their
553b725ae77Skettenis          type is indicated by the quoted string anyway. */
554b725ae77Skettenis       if (TYPE_CODE (type) == TYPE_CODE_PTR &&
555b725ae77Skettenis 	  TYPE_NAME (type) == NULL &&
556b725ae77Skettenis 	  TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL
557b725ae77Skettenis 	  && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0)
558b725ae77Skettenis 	{
559b725ae77Skettenis 	  /* Print nothing */
560b725ae77Skettenis 	}
561b725ae77Skettenis       else
562b725ae77Skettenis 	{
563b725ae77Skettenis 	  fprintf_filtered (stream, "(");
564b725ae77Skettenis 	  type_print (type, "", stream, -1);
565b725ae77Skettenis 	  fprintf_filtered (stream, ") ");
566b725ae77Skettenis 	}
567b725ae77Skettenis     }
568b725ae77Skettenis   return val_print (type, VALUE_CONTENTS (val), VALUE_EMBEDDED_OFFSET (val),
569b725ae77Skettenis 		    VALUE_ADDRESS (val) + VALUE_OFFSET (val),
570b725ae77Skettenis 		    stream, format, 1, 0, pretty);
571b725ae77Skettenis }
572b725ae77Skettenis 
573b725ae77Skettenis 
574b725ae77Skettenis /******************************************************************************
575b725ae77Skettenis                     Inserted from cp-valprint
576b725ae77Skettenis ******************************************************************************/
577b725ae77Skettenis 
578b725ae77Skettenis extern int vtblprint;		/* Controls printing of vtbl's */
579b725ae77Skettenis extern int objectprint;		/* Controls looking up an object's derived type
580b725ae77Skettenis 				   using what we find in its vtables.  */
581b725ae77Skettenis static int pascal_static_field_print;	/* Controls printing of static fields. */
582b725ae77Skettenis 
583b725ae77Skettenis static struct obstack dont_print_vb_obstack;
584b725ae77Skettenis static struct obstack dont_print_statmem_obstack;
585b725ae77Skettenis 
586b725ae77Skettenis static void pascal_object_print_static_field (struct type *, struct value *,
587b725ae77Skettenis 					      struct ui_file *, int, int,
588b725ae77Skettenis 					      enum val_prettyprint);
589b725ae77Skettenis 
590b725ae77Skettenis static void
591b725ae77Skettenis   pascal_object_print_value (struct type *, char *, CORE_ADDR, struct ui_file *,
592b725ae77Skettenis 			     int, int, enum val_prettyprint, struct type **);
593b725ae77Skettenis 
594b725ae77Skettenis void
pascal_object_print_class_method(char * valaddr,struct type * type,struct ui_file * stream)595b725ae77Skettenis pascal_object_print_class_method (char *valaddr, struct type *type,
596b725ae77Skettenis 				  struct ui_file *stream)
597b725ae77Skettenis {
598b725ae77Skettenis   struct type *domain;
599b725ae77Skettenis   struct fn_field *f = NULL;
600b725ae77Skettenis   int j = 0;
601b725ae77Skettenis   int len2;
602b725ae77Skettenis   int offset;
603b725ae77Skettenis   char *kind = "";
604b725ae77Skettenis   CORE_ADDR addr;
605b725ae77Skettenis   struct symbol *sym;
606b725ae77Skettenis   unsigned len;
607b725ae77Skettenis   unsigned int i;
608b725ae77Skettenis   struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
609b725ae77Skettenis 
610b725ae77Skettenis   domain = TYPE_DOMAIN_TYPE (target_type);
611b725ae77Skettenis   if (domain == (struct type *) NULL)
612b725ae77Skettenis     {
613b725ae77Skettenis       fprintf_filtered (stream, "<unknown>");
614b725ae77Skettenis       return;
615b725ae77Skettenis     }
616b725ae77Skettenis   addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
617b725ae77Skettenis   if (METHOD_PTR_IS_VIRTUAL (addr))
618b725ae77Skettenis     {
619b725ae77Skettenis       offset = METHOD_PTR_TO_VOFFSET (addr);
620b725ae77Skettenis       len = TYPE_NFN_FIELDS (domain);
621b725ae77Skettenis       for (i = 0; i < len; i++)
622b725ae77Skettenis 	{
623b725ae77Skettenis 	  f = TYPE_FN_FIELDLIST1 (domain, i);
624b725ae77Skettenis 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
625b725ae77Skettenis 
626b725ae77Skettenis 	  check_stub_method_group (domain, i);
627b725ae77Skettenis 	  for (j = 0; j < len2; j++)
628b725ae77Skettenis 	    {
629b725ae77Skettenis 	      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
630b725ae77Skettenis 		{
631b725ae77Skettenis 		  kind = "virtual ";
632b725ae77Skettenis 		  goto common;
633b725ae77Skettenis 		}
634b725ae77Skettenis 	    }
635b725ae77Skettenis 	}
636b725ae77Skettenis     }
637b725ae77Skettenis   else
638b725ae77Skettenis     {
639b725ae77Skettenis       sym = find_pc_function (addr);
640b725ae77Skettenis       if (sym == 0)
641b725ae77Skettenis 	{
642b725ae77Skettenis 	  error ("invalid pointer to member function");
643b725ae77Skettenis 	}
644b725ae77Skettenis       len = TYPE_NFN_FIELDS (domain);
645b725ae77Skettenis       for (i = 0; i < len; i++)
646b725ae77Skettenis 	{
647b725ae77Skettenis 	  f = TYPE_FN_FIELDLIST1 (domain, i);
648b725ae77Skettenis 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
649b725ae77Skettenis 
650b725ae77Skettenis 	  check_stub_method_group (domain, i);
651b725ae77Skettenis 	  for (j = 0; j < len2; j++)
652b725ae77Skettenis 	    {
653b725ae77Skettenis 	      if (DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
654b725ae77Skettenis 		goto common;
655b725ae77Skettenis 	    }
656b725ae77Skettenis 	}
657b725ae77Skettenis     }
658b725ae77Skettenis common:
659b725ae77Skettenis   if (i < len)
660b725ae77Skettenis     {
661b725ae77Skettenis       char *demangled_name;
662b725ae77Skettenis 
663b725ae77Skettenis       fprintf_filtered (stream, "&");
664b725ae77Skettenis       fputs_filtered (kind, stream);
665b725ae77Skettenis       demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
666b725ae77Skettenis 				       DMGL_ANSI | DMGL_PARAMS);
667b725ae77Skettenis       if (demangled_name == NULL)
668b725ae77Skettenis 	fprintf_filtered (stream, "<badly mangled name %s>",
669b725ae77Skettenis 			  TYPE_FN_FIELD_PHYSNAME (f, j));
670b725ae77Skettenis       else
671b725ae77Skettenis 	{
672b725ae77Skettenis 	  fputs_filtered (demangled_name, stream);
673b725ae77Skettenis 	  xfree (demangled_name);
674b725ae77Skettenis 	}
675b725ae77Skettenis     }
676b725ae77Skettenis   else
677b725ae77Skettenis     {
678b725ae77Skettenis       fprintf_filtered (stream, "(");
679b725ae77Skettenis       type_print (type, "", stream, -1);
680b725ae77Skettenis       fprintf_filtered (stream, ") %d", (int) addr >> 3);
681b725ae77Skettenis     }
682b725ae77Skettenis }
683b725ae77Skettenis 
684b725ae77Skettenis /* It was changed to this after 2.4.5.  */
685b725ae77Skettenis const char pascal_vtbl_ptr_name[] =
686b725ae77Skettenis {'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};
687b725ae77Skettenis 
688b725ae77Skettenis /* Return truth value for assertion that TYPE is of the type
689b725ae77Skettenis    "pointer to virtual function".  */
690b725ae77Skettenis 
691b725ae77Skettenis int
pascal_object_is_vtbl_ptr_type(struct type * type)692b725ae77Skettenis pascal_object_is_vtbl_ptr_type (struct type *type)
693b725ae77Skettenis {
694b725ae77Skettenis   char *typename = type_name_no_tag (type);
695b725ae77Skettenis 
696b725ae77Skettenis   return (typename != NULL
697b725ae77Skettenis 	  && strcmp (typename, pascal_vtbl_ptr_name) == 0);
698b725ae77Skettenis }
699b725ae77Skettenis 
700b725ae77Skettenis /* Return truth value for the assertion that TYPE is of the type
701b725ae77Skettenis    "pointer to virtual function table".  */
702b725ae77Skettenis 
703b725ae77Skettenis int
pascal_object_is_vtbl_member(struct type * type)704b725ae77Skettenis pascal_object_is_vtbl_member (struct type *type)
705b725ae77Skettenis {
706b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_PTR)
707b725ae77Skettenis     {
708b725ae77Skettenis       type = TYPE_TARGET_TYPE (type);
709b725ae77Skettenis       if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
710b725ae77Skettenis 	{
711b725ae77Skettenis 	  type = TYPE_TARGET_TYPE (type);
712b725ae77Skettenis 	  if (TYPE_CODE (type) == TYPE_CODE_STRUCT	/* if not using thunks */
713b725ae77Skettenis 	      || TYPE_CODE (type) == TYPE_CODE_PTR)	/* if using thunks */
714b725ae77Skettenis 	    {
715b725ae77Skettenis 	      /* Virtual functions tables are full of pointers
716b725ae77Skettenis 	         to virtual functions. */
717b725ae77Skettenis 	      return pascal_object_is_vtbl_ptr_type (type);
718b725ae77Skettenis 	    }
719b725ae77Skettenis 	}
720b725ae77Skettenis     }
721b725ae77Skettenis   return 0;
722b725ae77Skettenis }
723b725ae77Skettenis 
724b725ae77Skettenis /* Mutually recursive subroutines of pascal_object_print_value and c_val_print to
725b725ae77Skettenis    print out a structure's fields: pascal_object_print_value_fields and pascal_object_print_value.
726b725ae77Skettenis 
727b725ae77Skettenis    TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
728b725ae77Skettenis    same meanings as in pascal_object_print_value and c_val_print.
729b725ae77Skettenis 
730b725ae77Skettenis    DONT_PRINT is an array of baseclass types that we
731b725ae77Skettenis    should not print, or zero if called from top level.  */
732b725ae77Skettenis 
733b725ae77Skettenis void
pascal_object_print_value_fields(struct type * type,char * valaddr,CORE_ADDR address,struct ui_file * stream,int format,int recurse,enum val_prettyprint pretty,struct type ** dont_print_vb,int dont_print_statmem)734b725ae77Skettenis pascal_object_print_value_fields (struct type *type, char *valaddr,
735b725ae77Skettenis 				  CORE_ADDR address, struct ui_file *stream,
736b725ae77Skettenis 				  int format, int recurse,
737b725ae77Skettenis 				  enum val_prettyprint pretty,
738b725ae77Skettenis 				  struct type **dont_print_vb,
739b725ae77Skettenis 				  int dont_print_statmem)
740b725ae77Skettenis {
741b725ae77Skettenis   int i, len, n_baseclasses;
742b725ae77Skettenis   struct obstack tmp_obstack;
743b725ae77Skettenis   char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
744b725ae77Skettenis 
745b725ae77Skettenis   CHECK_TYPEDEF (type);
746b725ae77Skettenis 
747b725ae77Skettenis   fprintf_filtered (stream, "{");
748b725ae77Skettenis   len = TYPE_NFIELDS (type);
749b725ae77Skettenis   n_baseclasses = TYPE_N_BASECLASSES (type);
750b725ae77Skettenis 
751b725ae77Skettenis   /* Print out baseclasses such that we don't print
752b725ae77Skettenis      duplicates of virtual baseclasses.  */
753b725ae77Skettenis   if (n_baseclasses > 0)
754b725ae77Skettenis     pascal_object_print_value (type, valaddr, address, stream,
755b725ae77Skettenis 			       format, recurse + 1, pretty, dont_print_vb);
756b725ae77Skettenis 
757b725ae77Skettenis   if (!len && n_baseclasses == 1)
758b725ae77Skettenis     fprintf_filtered (stream, "<No data fields>");
759b725ae77Skettenis   else
760b725ae77Skettenis     {
761b725ae77Skettenis       int fields_seen = 0;
762b725ae77Skettenis 
763b725ae77Skettenis       if (dont_print_statmem == 0)
764b725ae77Skettenis 	{
765b725ae77Skettenis 	  /* If we're at top level, carve out a completely fresh
766b725ae77Skettenis 	     chunk of the obstack and use that until this particular
767b725ae77Skettenis 	     invocation returns.  */
768b725ae77Skettenis 	  tmp_obstack = dont_print_statmem_obstack;
769b725ae77Skettenis 	  obstack_finish (&dont_print_statmem_obstack);
770b725ae77Skettenis 	}
771b725ae77Skettenis 
772b725ae77Skettenis       for (i = n_baseclasses; i < len; i++)
773b725ae77Skettenis 	{
774b725ae77Skettenis 	  /* If requested, skip printing of static fields.  */
775b725ae77Skettenis 	  if (!pascal_static_field_print && TYPE_FIELD_STATIC (type, i))
776b725ae77Skettenis 	    continue;
777b725ae77Skettenis 	  if (fields_seen)
778b725ae77Skettenis 	    fprintf_filtered (stream, ", ");
779b725ae77Skettenis 	  else if (n_baseclasses > 0)
780b725ae77Skettenis 	    {
781b725ae77Skettenis 	      if (pretty)
782b725ae77Skettenis 		{
783b725ae77Skettenis 		  fprintf_filtered (stream, "\n");
784b725ae77Skettenis 		  print_spaces_filtered (2 + 2 * recurse, stream);
785b725ae77Skettenis 		  fputs_filtered ("members of ", stream);
786b725ae77Skettenis 		  fputs_filtered (type_name_no_tag (type), stream);
787b725ae77Skettenis 		  fputs_filtered (": ", stream);
788b725ae77Skettenis 		}
789b725ae77Skettenis 	    }
790b725ae77Skettenis 	  fields_seen = 1;
791b725ae77Skettenis 
792b725ae77Skettenis 	  if (pretty)
793b725ae77Skettenis 	    {
794b725ae77Skettenis 	      fprintf_filtered (stream, "\n");
795b725ae77Skettenis 	      print_spaces_filtered (2 + 2 * recurse, stream);
796b725ae77Skettenis 	    }
797b725ae77Skettenis 	  else
798b725ae77Skettenis 	    {
799b725ae77Skettenis 	      wrap_here (n_spaces (2 + 2 * recurse));
800b725ae77Skettenis 	    }
801b725ae77Skettenis 	  if (inspect_it)
802b725ae77Skettenis 	    {
803b725ae77Skettenis 	      if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
804b725ae77Skettenis 		fputs_filtered ("\"( ptr \"", stream);
805b725ae77Skettenis 	      else
806b725ae77Skettenis 		fputs_filtered ("\"( nodef \"", stream);
807b725ae77Skettenis 	      if (TYPE_FIELD_STATIC (type, i))
808b725ae77Skettenis 		fputs_filtered ("static ", stream);
809b725ae77Skettenis 	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
810b725ae77Skettenis 				       language_cplus,
811b725ae77Skettenis 				       DMGL_PARAMS | DMGL_ANSI);
812b725ae77Skettenis 	      fputs_filtered ("\" \"", stream);
813b725ae77Skettenis 	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
814b725ae77Skettenis 				       language_cplus,
815b725ae77Skettenis 				       DMGL_PARAMS | DMGL_ANSI);
816b725ae77Skettenis 	      fputs_filtered ("\") \"", stream);
817b725ae77Skettenis 	    }
818b725ae77Skettenis 	  else
819b725ae77Skettenis 	    {
820b725ae77Skettenis 	      annotate_field_begin (TYPE_FIELD_TYPE (type, i));
821b725ae77Skettenis 
822b725ae77Skettenis 	      if (TYPE_FIELD_STATIC (type, i))
823b725ae77Skettenis 		fputs_filtered ("static ", stream);
824b725ae77Skettenis 	      fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
825b725ae77Skettenis 				       language_cplus,
826b725ae77Skettenis 				       DMGL_PARAMS | DMGL_ANSI);
827b725ae77Skettenis 	      annotate_field_name_end ();
828b725ae77Skettenis 	      fputs_filtered (" = ", stream);
829b725ae77Skettenis 	      annotate_field_value ();
830b725ae77Skettenis 	    }
831b725ae77Skettenis 
832b725ae77Skettenis 	  if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
833b725ae77Skettenis 	    {
834b725ae77Skettenis 	      struct value *v;
835b725ae77Skettenis 
836b725ae77Skettenis 	      /* Bitfields require special handling, especially due to byte
837b725ae77Skettenis 	         order problems.  */
838b725ae77Skettenis 	      if (TYPE_FIELD_IGNORE (type, i))
839b725ae77Skettenis 		{
840b725ae77Skettenis 		  fputs_filtered ("<optimized out or zero length>", stream);
841b725ae77Skettenis 		}
842b725ae77Skettenis 	      else
843b725ae77Skettenis 		{
844b725ae77Skettenis 		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
845b725ae77Skettenis 				   unpack_field_as_long (type, valaddr, i));
846b725ae77Skettenis 
847b725ae77Skettenis 		  val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
848b725ae77Skettenis 			     stream, format, 0, recurse + 1, pretty);
849b725ae77Skettenis 		}
850b725ae77Skettenis 	    }
851b725ae77Skettenis 	  else
852b725ae77Skettenis 	    {
853b725ae77Skettenis 	      if (TYPE_FIELD_IGNORE (type, i))
854b725ae77Skettenis 		{
855b725ae77Skettenis 		  fputs_filtered ("<optimized out or zero length>", stream);
856b725ae77Skettenis 		}
857b725ae77Skettenis 	      else if (TYPE_FIELD_STATIC (type, i))
858b725ae77Skettenis 		{
859b725ae77Skettenis 		  /* struct value *v = value_static_field (type, i); v4.17 specific */
860b725ae77Skettenis 		  struct value *v;
861b725ae77Skettenis 		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
862b725ae77Skettenis 				   unpack_field_as_long (type, valaddr, i));
863b725ae77Skettenis 
864b725ae77Skettenis 		  if (v == NULL)
865b725ae77Skettenis 		    fputs_filtered ("<optimized out>", stream);
866b725ae77Skettenis 		  else
867b725ae77Skettenis 		    pascal_object_print_static_field (TYPE_FIELD_TYPE (type, i), v,
868b725ae77Skettenis 						stream, format, recurse + 1,
869b725ae77Skettenis 						      pretty);
870b725ae77Skettenis 		}
871b725ae77Skettenis 	      else
872b725ae77Skettenis 		{
873b725ae77Skettenis 		  /* val_print (TYPE_FIELD_TYPE (type, i),
874b725ae77Skettenis 		     valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
875b725ae77Skettenis 		     address + TYPE_FIELD_BITPOS (type, i) / 8, 0,
876b725ae77Skettenis 		     stream, format, 0, recurse + 1, pretty); */
877b725ae77Skettenis 		  val_print (TYPE_FIELD_TYPE (type, i),
878b725ae77Skettenis 			     valaddr, TYPE_FIELD_BITPOS (type, i) / 8,
879b725ae77Skettenis 			     address + TYPE_FIELD_BITPOS (type, i) / 8,
880b725ae77Skettenis 			     stream, format, 0, recurse + 1, pretty);
881b725ae77Skettenis 		}
882b725ae77Skettenis 	    }
883b725ae77Skettenis 	  annotate_field_end ();
884b725ae77Skettenis 	}
885b725ae77Skettenis 
886b725ae77Skettenis       if (dont_print_statmem == 0)
887b725ae77Skettenis 	{
888b725ae77Skettenis 	  /* Free the space used to deal with the printing
889b725ae77Skettenis 	     of the members from top level.  */
890b725ae77Skettenis 	  obstack_free (&dont_print_statmem_obstack, last_dont_print);
891b725ae77Skettenis 	  dont_print_statmem_obstack = tmp_obstack;
892b725ae77Skettenis 	}
893b725ae77Skettenis 
894b725ae77Skettenis       if (pretty)
895b725ae77Skettenis 	{
896b725ae77Skettenis 	  fprintf_filtered (stream, "\n");
897b725ae77Skettenis 	  print_spaces_filtered (2 * recurse, stream);
898b725ae77Skettenis 	}
899b725ae77Skettenis     }
900b725ae77Skettenis   fprintf_filtered (stream, "}");
901b725ae77Skettenis }
902b725ae77Skettenis 
903b725ae77Skettenis /* Special val_print routine to avoid printing multiple copies of virtual
904b725ae77Skettenis    baseclasses.  */
905b725ae77Skettenis 
906b725ae77Skettenis void
pascal_object_print_value(struct type * type,char * valaddr,CORE_ADDR address,struct ui_file * stream,int format,int recurse,enum val_prettyprint pretty,struct type ** dont_print_vb)907b725ae77Skettenis pascal_object_print_value (struct type *type, char *valaddr, CORE_ADDR address,
908b725ae77Skettenis 			   struct ui_file *stream, int format, int recurse,
909b725ae77Skettenis 			   enum val_prettyprint pretty,
910b725ae77Skettenis 			   struct type **dont_print_vb)
911b725ae77Skettenis {
912b725ae77Skettenis   struct obstack tmp_obstack;
913b725ae77Skettenis   struct type **last_dont_print
914b725ae77Skettenis   = (struct type **) obstack_next_free (&dont_print_vb_obstack);
915b725ae77Skettenis   int i, n_baseclasses = TYPE_N_BASECLASSES (type);
916b725ae77Skettenis 
917b725ae77Skettenis   if (dont_print_vb == 0)
918b725ae77Skettenis     {
919b725ae77Skettenis       /* If we're at top level, carve out a completely fresh
920b725ae77Skettenis          chunk of the obstack and use that until this particular
921b725ae77Skettenis          invocation returns.  */
922b725ae77Skettenis       tmp_obstack = dont_print_vb_obstack;
923b725ae77Skettenis       /* Bump up the high-water mark.  Now alpha is omega.  */
924b725ae77Skettenis       obstack_finish (&dont_print_vb_obstack);
925b725ae77Skettenis     }
926b725ae77Skettenis 
927b725ae77Skettenis   for (i = 0; i < n_baseclasses; i++)
928b725ae77Skettenis     {
929b725ae77Skettenis       int boffset;
930b725ae77Skettenis       struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
931b725ae77Skettenis       char *basename = TYPE_NAME (baseclass);
932b725ae77Skettenis       char *base_valaddr;
933b725ae77Skettenis 
934b725ae77Skettenis       if (BASETYPE_VIA_VIRTUAL (type, i))
935b725ae77Skettenis 	{
936b725ae77Skettenis 	  struct type **first_dont_print
937b725ae77Skettenis 	  = (struct type **) obstack_base (&dont_print_vb_obstack);
938b725ae77Skettenis 
939b725ae77Skettenis 	  int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
940b725ae77Skettenis 	  - first_dont_print;
941b725ae77Skettenis 
942b725ae77Skettenis 	  while (--j >= 0)
943b725ae77Skettenis 	    if (baseclass == first_dont_print[j])
944b725ae77Skettenis 	      goto flush_it;
945b725ae77Skettenis 
946b725ae77Skettenis 	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
947b725ae77Skettenis 	}
948b725ae77Skettenis 
949b725ae77Skettenis       boffset = baseclass_offset (type, i, valaddr, address);
950b725ae77Skettenis 
951b725ae77Skettenis       if (pretty)
952b725ae77Skettenis 	{
953b725ae77Skettenis 	  fprintf_filtered (stream, "\n");
954b725ae77Skettenis 	  print_spaces_filtered (2 * recurse, stream);
955b725ae77Skettenis 	}
956b725ae77Skettenis       fputs_filtered ("<", stream);
957b725ae77Skettenis       /* Not sure what the best notation is in the case where there is no
958b725ae77Skettenis          baseclass name.  */
959b725ae77Skettenis 
960b725ae77Skettenis       fputs_filtered (basename ? basename : "", stream);
961b725ae77Skettenis       fputs_filtered ("> = ", stream);
962b725ae77Skettenis 
963b725ae77Skettenis       /* The virtual base class pointer might have been clobbered by the
964b725ae77Skettenis          user program. Make sure that it still points to a valid memory
965b725ae77Skettenis          location.  */
966b725ae77Skettenis 
967b725ae77Skettenis       if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type)))
968b725ae77Skettenis 	{
969b725ae77Skettenis 	  /* FIXME (alloc): not safe is baseclass is really really big. */
970b725ae77Skettenis 	  base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
971b725ae77Skettenis 	  if (target_read_memory (address + boffset, base_valaddr,
972b725ae77Skettenis 				  TYPE_LENGTH (baseclass)) != 0)
973b725ae77Skettenis 	    boffset = -1;
974b725ae77Skettenis 	}
975b725ae77Skettenis       else
976b725ae77Skettenis 	base_valaddr = valaddr + boffset;
977b725ae77Skettenis 
978b725ae77Skettenis       if (boffset == -1)
979b725ae77Skettenis 	fprintf_filtered (stream, "<invalid address>");
980b725ae77Skettenis       else
981b725ae77Skettenis 	pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset,
982b725ae77Skettenis 					  stream, format, recurse, pretty,
983b725ae77Skettenis 		     (struct type **) obstack_base (&dont_print_vb_obstack),
984b725ae77Skettenis 					  0);
985b725ae77Skettenis       fputs_filtered (", ", stream);
986b725ae77Skettenis 
987b725ae77Skettenis     flush_it:
988b725ae77Skettenis       ;
989b725ae77Skettenis     }
990b725ae77Skettenis 
991b725ae77Skettenis   if (dont_print_vb == 0)
992b725ae77Skettenis     {
993b725ae77Skettenis       /* Free the space used to deal with the printing
994b725ae77Skettenis          of this type from top level.  */
995b725ae77Skettenis       obstack_free (&dont_print_vb_obstack, last_dont_print);
996b725ae77Skettenis       /* Reset watermark so that we can continue protecting
997b725ae77Skettenis          ourselves from whatever we were protecting ourselves.  */
998b725ae77Skettenis       dont_print_vb_obstack = tmp_obstack;
999b725ae77Skettenis     }
1000b725ae77Skettenis }
1001b725ae77Skettenis 
1002b725ae77Skettenis /* Print value of a static member.
1003b725ae77Skettenis    To avoid infinite recursion when printing a class that contains
1004b725ae77Skettenis    a static instance of the class, we keep the addresses of all printed
1005b725ae77Skettenis    static member classes in an obstack and refuse to print them more
1006b725ae77Skettenis    than once.
1007b725ae77Skettenis 
1008b725ae77Skettenis    VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
1009b725ae77Skettenis    have the same meanings as in c_val_print.  */
1010b725ae77Skettenis 
1011b725ae77Skettenis static void
pascal_object_print_static_field(struct type * type,struct value * val,struct ui_file * stream,int format,int recurse,enum val_prettyprint pretty)1012b725ae77Skettenis pascal_object_print_static_field (struct type *type, struct value *val,
1013b725ae77Skettenis 				  struct ui_file *stream, int format,
1014b725ae77Skettenis 				  int recurse, enum val_prettyprint pretty)
1015b725ae77Skettenis {
1016b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
1017b725ae77Skettenis     {
1018b725ae77Skettenis       CORE_ADDR *first_dont_print;
1019b725ae77Skettenis       int i;
1020b725ae77Skettenis 
1021b725ae77Skettenis       first_dont_print
1022b725ae77Skettenis 	= (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
1023b725ae77Skettenis       i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
1024b725ae77Skettenis 	- first_dont_print;
1025b725ae77Skettenis 
1026b725ae77Skettenis       while (--i >= 0)
1027b725ae77Skettenis 	{
1028b725ae77Skettenis 	  if (VALUE_ADDRESS (val) == first_dont_print[i])
1029b725ae77Skettenis 	    {
1030b725ae77Skettenis 	      fputs_filtered ("<same as static member of an already seen type>",
1031b725ae77Skettenis 			      stream);
1032b725ae77Skettenis 	      return;
1033b725ae77Skettenis 	    }
1034b725ae77Skettenis 	}
1035b725ae77Skettenis 
1036b725ae77Skettenis       obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
1037b725ae77Skettenis 		    sizeof (CORE_ADDR));
1038b725ae77Skettenis 
1039b725ae77Skettenis       CHECK_TYPEDEF (type);
1040b725ae77Skettenis       pascal_object_print_value_fields (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
1041b725ae77Skettenis 				  stream, format, recurse, pretty, NULL, 1);
1042b725ae77Skettenis       return;
1043b725ae77Skettenis     }
1044b725ae77Skettenis   val_print (type, VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val),
1045b725ae77Skettenis 	     stream, format, 0, recurse, pretty);
1046b725ae77Skettenis }
1047b725ae77Skettenis 
1048b725ae77Skettenis void
pascal_object_print_class_member(char * valaddr,struct type * domain,struct ui_file * stream,char * prefix)1049b725ae77Skettenis pascal_object_print_class_member (char *valaddr, struct type *domain,
1050b725ae77Skettenis 				  struct ui_file *stream, char *prefix)
1051b725ae77Skettenis {
1052b725ae77Skettenis 
1053b725ae77Skettenis   /* VAL is a byte offset into the structure type DOMAIN.
1054b725ae77Skettenis      Find the name of the field for that offset and
1055b725ae77Skettenis      print it.  */
1056b725ae77Skettenis   int extra = 0;
1057b725ae77Skettenis   int bits = 0;
1058b725ae77Skettenis   unsigned int i;
1059b725ae77Skettenis   unsigned len = TYPE_NFIELDS (domain);
1060b725ae77Skettenis   /* @@ Make VAL into bit offset */
1061b725ae77Skettenis   LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
1062b725ae77Skettenis   for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
1063b725ae77Skettenis     {
1064b725ae77Skettenis       int bitpos = TYPE_FIELD_BITPOS (domain, i);
1065b725ae77Skettenis       QUIT;
1066b725ae77Skettenis       if (val == bitpos)
1067b725ae77Skettenis 	break;
1068b725ae77Skettenis       if (val < bitpos && i != 0)
1069b725ae77Skettenis 	{
1070b725ae77Skettenis 	  /* Somehow pointing into a field.  */
1071b725ae77Skettenis 	  i -= 1;
1072b725ae77Skettenis 	  extra = (val - TYPE_FIELD_BITPOS (domain, i));
1073b725ae77Skettenis 	  if (extra & 0x7)
1074b725ae77Skettenis 	    bits = 1;
1075b725ae77Skettenis 	  else
1076b725ae77Skettenis 	    extra >>= 3;
1077b725ae77Skettenis 	  break;
1078b725ae77Skettenis 	}
1079b725ae77Skettenis     }
1080b725ae77Skettenis   if (i < len)
1081b725ae77Skettenis     {
1082b725ae77Skettenis       char *name;
1083b725ae77Skettenis       fputs_filtered (prefix, stream);
1084b725ae77Skettenis       name = type_name_no_tag (domain);
1085b725ae77Skettenis       if (name)
1086b725ae77Skettenis 	fputs_filtered (name, stream);
1087b725ae77Skettenis       else
1088b725ae77Skettenis 	pascal_type_print_base (domain, stream, 0, 0);
1089b725ae77Skettenis       fprintf_filtered (stream, "::");
1090b725ae77Skettenis       fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
1091b725ae77Skettenis       if (extra)
1092b725ae77Skettenis 	fprintf_filtered (stream, " + %d bytes", extra);
1093b725ae77Skettenis       if (bits)
1094b725ae77Skettenis 	fprintf_filtered (stream, " (offset in bits)");
1095b725ae77Skettenis     }
1096b725ae77Skettenis   else
1097b725ae77Skettenis     fprintf_filtered (stream, "%ld", (long int) (val >> 3));
1098b725ae77Skettenis }
1099b725ae77Skettenis 
1100b725ae77Skettenis extern initialize_file_ftype _initialize_pascal_valprint; /* -Wmissing-prototypes */
1101b725ae77Skettenis 
1102b725ae77Skettenis void
_initialize_pascal_valprint(void)1103b725ae77Skettenis _initialize_pascal_valprint (void)
1104b725ae77Skettenis {
1105*11efff7fSkettenis   deprecated_add_show_from_set
1106b725ae77Skettenis     (add_set_cmd ("pascal_static-members", class_support, var_boolean,
1107b725ae77Skettenis 		  (char *) &pascal_static_field_print,
1108b725ae77Skettenis 		  "Set printing of pascal static members.",
1109b725ae77Skettenis 		  &setprintlist),
1110b725ae77Skettenis      &showprintlist);
1111b725ae77Skettenis   /* Turn on printing of static fields.  */
1112b725ae77Skettenis   pascal_static_field_print = 1;
1113b725ae77Skettenis 
1114b725ae77Skettenis }
1115