1/* Support for printing Java types for GDB, the GNU debugger.
2   Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3
4   This file is part of GDB.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place - Suite 330,
19   Boston, MA 02111-1307, USA.  */
20
21
22#include "defs.h"
23#include "symtab.h"
24#include "gdbtypes.h"
25#include "value.h"
26#include "demangle.h"
27#include "jv-lang.h"
28#include "gdb_string.h"
29#include "typeprint.h"
30#include "c-lang.h"
31#include "cp-abi.h"
32
33/* Local functions */
34
35static void java_type_print_base (struct type * type,
36				  struct ui_file *stream, int show,
37				  int level);
38
39static void
40java_type_print_derivation_info (struct ui_file *stream, struct type *type)
41{
42  char *name;
43  int i;
44  int n_bases;
45  int prev;
46
47  n_bases = TYPE_N_BASECLASSES (type);
48
49  for (i = 0, prev = 0; i < n_bases; i++)
50    {
51      int kind;
52
53      kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';
54
55      fputs_filtered (kind == prev ? ", "
56		      : kind == 'I' ? " implements "
57		      : " extends ",
58		      stream);
59      prev = kind;
60      name = type_name_no_tag (TYPE_BASECLASS (type, i));
61
62      fprintf_filtered (stream, "%s", name ? name : "(null)");
63    }
64
65  if (i > 0)
66    fputs_filtered (" ", stream);
67}
68
69/* Print the name of the type (or the ultimate pointer target,
70   function value or array element), or the description of a
71   structure or union.
72
73   SHOW positive means print details about the type (e.g. enum values),
74   and print structure elements passing SHOW - 1 for show.
75   SHOW negative means just print the type name or struct tag if there is one.
76   If there is no name, print something sensible but concise like
77   "struct {...}".
78   SHOW zero means just print the type name or struct tag if there is one.
79   If there is no name, print something sensible but not as concise like
80   "struct {int x; int y;}".
81
82   LEVEL is the number of spaces to indent by.
83   We increase it for some recursive calls.  */
84
85static void
86java_type_print_base (struct type *type, struct ui_file *stream, int show,
87		      int level)
88{
89  int i;
90  int len;
91  char *mangled_name;
92  char *demangled_name;
93  QUIT;
94
95  wrap_here ("    ");
96
97  if (type == NULL)
98    {
99      fputs_filtered ("<type unknown>", stream);
100      return;
101    }
102
103  /* When SHOW is zero or less, and there is a valid type name, then always
104     just print the type name directly from the type.  */
105
106  if (show <= 0
107      && TYPE_NAME (type) != NULL)
108    {
109      fputs_filtered (TYPE_NAME (type), stream);
110      return;
111    }
112
113  CHECK_TYPEDEF (type);
114
115  switch (TYPE_CODE (type))
116    {
117    case TYPE_CODE_PTR:
118      java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
119      break;
120
121    case TYPE_CODE_STRUCT:
122      if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
123	{			/* array type */
124	  char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
125	  fputs_filtered (name, stream);
126	  xfree (name);
127	  break;
128	}
129
130      if (show >= 0)
131	fprintf_filtered (stream, "class ");
132
133      if (TYPE_TAG_NAME (type) != NULL)
134	{
135	  fputs_filtered (TYPE_TAG_NAME (type), stream);
136	  if (show > 0)
137	    fputs_filtered (" ", stream);
138	}
139
140      wrap_here ("    ");
141
142      if (show < 0)
143	{
144	  /* If we just printed a tag name, no need to print anything else.  */
145	  if (TYPE_TAG_NAME (type) == NULL)
146	    fprintf_filtered (stream, "{...}");
147	}
148      else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
149	{
150	  java_type_print_derivation_info (stream, type);
151
152	  fprintf_filtered (stream, "{\n");
153	  if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
154	    {
155	      if (TYPE_STUB (type))
156		fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
157	      else
158		fprintfi_filtered (level + 4, stream, "<no data fields>\n");
159	    }
160
161	  /* If there is a base class for this type,
162	     do not print the field that it occupies.  */
163
164	  len = TYPE_NFIELDS (type);
165	  for (i = TYPE_N_BASECLASSES (type); i < len; i++)
166	    {
167	      QUIT;
168	      /* Don't print out virtual function table.  */
169	      if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
170		  && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
171		continue;
172
173	      /* Don't print the dummy field "class". */
174	      if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
175		continue;
176
177	      print_spaces_filtered (level + 4, stream);
178
179	      if (HAVE_CPLUS_STRUCT (type))
180		{
181		  if (TYPE_FIELD_PROTECTED (type, i))
182		    fprintf_filtered (stream, "protected ");
183		  else if (TYPE_FIELD_PRIVATE (type, i))
184		    fprintf_filtered (stream, "private ");
185		  else
186		    fprintf_filtered (stream, "public ");
187		}
188
189	      if (TYPE_FIELD_STATIC (type, i))
190		fprintf_filtered (stream, "static ");
191
192	      java_print_type (TYPE_FIELD_TYPE (type, i),
193			       TYPE_FIELD_NAME (type, i),
194			       stream, show - 1, level + 4);
195
196	      fprintf_filtered (stream, ";\n");
197	    }
198
199	  /* If there are both fields and methods, put a space between. */
200	  len = TYPE_NFN_FIELDS (type);
201	  if (len)
202	    fprintf_filtered (stream, "\n");
203
204	  /* Print out the methods */
205
206	  for (i = 0; i < len; i++)
207	    {
208	      struct fn_field *f;
209	      int j;
210	      char *method_name;
211	      char *name;
212	      int is_constructor;
213	      int n_overloads;
214
215	      f = TYPE_FN_FIELDLIST1 (type, i);
216	      n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
217	      method_name = TYPE_FN_FIELDLIST_NAME (type, i);
218	      name = type_name_no_tag (type);
219	      is_constructor = name && strcmp (method_name, name) == 0;
220
221	      for (j = 0; j < n_overloads; j++)
222		{
223		  char *physname;
224		  int is_full_physname_constructor;
225
226		  physname = TYPE_FN_FIELD_PHYSNAME (f, j);
227
228		  is_full_physname_constructor
229                    = (is_constructor_name (physname)
230                       || is_destructor_name (physname));
231
232		  QUIT;
233
234		  print_spaces_filtered (level + 4, stream);
235
236		  if (TYPE_FN_FIELD_PROTECTED (f, j))
237		    fprintf_filtered (stream, "protected ");
238		  else if (TYPE_FN_FIELD_PRIVATE (f, j))
239		    fprintf_filtered (stream, "private ");
240		  else if (TYPE_FN_FIELD_PUBLIC (f, j))
241		    fprintf_filtered (stream, "public ");
242
243		  if (TYPE_FN_FIELD_ABSTRACT (f, j))
244		    fprintf_filtered (stream, "abstract ");
245		  if (TYPE_FN_FIELD_STATIC (f, j))
246		    fprintf_filtered (stream, "static ");
247		  if (TYPE_FN_FIELD_FINAL (f, j))
248		    fprintf_filtered (stream, "final ");
249		  if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
250		    fprintf_filtered (stream, "synchronized ");
251		  if (TYPE_FN_FIELD_NATIVE (f, j))
252		    fprintf_filtered (stream, "native ");
253
254		  if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
255		    {
256		      /* Keep GDB from crashing here.  */
257		      fprintf_filtered (stream, "<undefined type> %s;\n",
258					TYPE_FN_FIELD_PHYSNAME (f, j));
259		      break;
260		    }
261		  else if (!is_constructor && !is_full_physname_constructor)
262		    {
263		      type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
264				  "", stream, -1);
265		      fputs_filtered (" ", stream);
266		    }
267
268		  if (TYPE_FN_FIELD_STUB (f, j))
269		    /* Build something we can demangle.  */
270		    mangled_name = gdb_mangle_name (type, i, j);
271		  else
272		    mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
273
274		  demangled_name =
275		    cplus_demangle (mangled_name,
276				    DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
277
278		  if (demangled_name == NULL)
279		    demangled_name = xstrdup (mangled_name);
280
281		  {
282		    char *demangled_no_class;
283		    char *ptr;
284
285		    ptr = demangled_no_class = demangled_name;
286
287		    while (1)
288		      {
289			char c;
290
291			c = *ptr++;
292
293			if (c == 0 || c == '(')
294			  break;
295			if (c == '.')
296			  demangled_no_class = ptr;
297		      }
298
299		    fputs_filtered (demangled_no_class, stream);
300		    xfree (demangled_name);
301		  }
302
303		  if (TYPE_FN_FIELD_STUB (f, j))
304		    xfree (mangled_name);
305
306		  fprintf_filtered (stream, ";\n");
307		}
308	    }
309
310	  fprintfi_filtered (level, stream, "}");
311	}
312      break;
313
314    default:
315      c_type_print_base (type, stream, show, level);
316    }
317}
318
319/* LEVEL is the depth to indent lines by.  */
320
321extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
322					 int, int, int);
323
324void
325java_print_type (struct type *type, char *varstring, struct ui_file *stream,
326		 int show, int level)
327{
328  int demangled_args;
329
330  java_type_print_base (type, stream, show, level);
331
332  if (varstring != NULL && *varstring != '\0')
333    {
334      fputs_filtered (" ", stream);
335      fputs_filtered (varstring, stream);
336    }
337
338  /* For demangled function names, we have the arglist as part of the name,
339     so don't print an additional pair of ()'s */
340
341  demangled_args = strchr (varstring, '(') != NULL;
342  c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
343}
344