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