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 
35 static void java_type_print_base (struct type * type,
36 				  struct ui_file *stream, int show,
37 				  int level);
38 
39 static void
java_type_print_derivation_info(struct ui_file * stream,struct type * type)40 java_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 
85 static void
java_type_print_base(struct type * type,struct ui_file * stream,int show,int level)86 java_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 
321 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
322 					 int, int, int);
323 
324 void
java_print_type(struct type * type,char * varstring,struct ui_file * stream,int show,int level)325 java_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