xref: /dragonfly/contrib/gdb-7/gdb/jv-typeprint.c (revision 52f9f0d9)
1 /* Support for printing Java types for GDB, the GNU debugger.
2    Copyright (C) 1997-2000, 2007-2012 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 "gdb-demangle.h"
26 #include "jv-lang.h"
27 #include "gdb_string.h"
28 #include "typeprint.h"
29 #include "c-lang.h"
30 #include "cp-abi.h"
31 #include "gdb_assert.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
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
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 
94   QUIT;
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 
126 	  fputs_filtered (name, stream);
127 	  xfree (name);
128 	  break;
129 	}
130 
131       if (show >= 0)
132 	fprintf_filtered (stream, "class ");
133 
134       if (TYPE_TAG_NAME (type) != NULL)
135 	{
136 	  fputs_filtered (TYPE_TAG_NAME (type), stream);
137 	  if (show > 0)
138 	    fputs_filtered (" ", stream);
139 	}
140 
141       wrap_here ("    ");
142 
143       if (show < 0)
144 	{
145 	  /* If we just printed a tag name, no need to print anything else.  */
146 	  if (TYPE_TAG_NAME (type) == NULL)
147 	    fprintf_filtered (stream, "{...}");
148 	}
149       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
150 	{
151 	  java_type_print_derivation_info (stream, type);
152 
153 	  fprintf_filtered (stream, "{\n");
154 	  if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
155 	    {
156 	      if (TYPE_STUB (type))
157 		fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
158 	      else
159 		fprintfi_filtered (level + 4, stream, "<no data fields>\n");
160 	    }
161 
162 	  /* If there is a base class for this type,
163 	     do not print the field that it occupies.  */
164 
165 	  len = TYPE_NFIELDS (type);
166 	  for (i = TYPE_N_BASECLASSES (type); i < len; i++)
167 	    {
168 	      QUIT;
169 	      /* Don't print out virtual function table.  */
170 	      if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
171 		  && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
172 		continue;
173 
174 	      /* Don't print the dummy field "class".  */
175 	      if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
176 		continue;
177 
178 	      print_spaces_filtered (level + 4, stream);
179 
180 	      if (HAVE_CPLUS_STRUCT (type))
181 		{
182 		  if (TYPE_FIELD_PROTECTED (type, i))
183 		    fprintf_filtered (stream, "protected ");
184 		  else if (TYPE_FIELD_PRIVATE (type, i))
185 		    fprintf_filtered (stream, "private ");
186 		  else
187 		    fprintf_filtered (stream, "public ");
188 		}
189 
190 	      if (field_is_static (&TYPE_FIELD (type, i)))
191 		fprintf_filtered (stream, "static ");
192 
193 	      java_print_type (TYPE_FIELD_TYPE (type, i),
194 			       TYPE_FIELD_NAME (type, i),
195 			       stream, show - 1, level + 4);
196 
197 	      fprintf_filtered (stream, ";\n");
198 	    }
199 
200 	  /* If there are both fields and methods, put a space between.  */
201 	  len = TYPE_NFN_FIELDS (type);
202 	  if (len)
203 	    fprintf_filtered (stream, "\n");
204 
205 	  /* Print out the methods.  */
206 
207 	  for (i = 0; i < len; i++)
208 	    {
209 	      struct fn_field *f;
210 	      int j;
211 	      char *method_name;
212 	      char *name;
213 	      int is_constructor;
214 	      int n_overloads;
215 
216 	      f = TYPE_FN_FIELDLIST1 (type, i);
217 	      n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
218 	      method_name = TYPE_FN_FIELDLIST_NAME (type, i);
219 	      name = type_name_no_tag (type);
220 	      is_constructor = name && strcmp (method_name, name) == 0;
221 
222 	      for (j = 0; j < n_overloads; j++)
223 		{
224 		  const char *real_physname;
225 		  char *physname, *p;
226 		  int is_full_physname_constructor;
227 
228 		  real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
229 
230 		  /* The physname will contain the return type
231 		     after the final closing parenthesis.  Strip it off.  */
232 		  p = strrchr (real_physname, ')');
233 		  gdb_assert (p != NULL);
234 		  ++p;   /* Keep the trailing ')'.  */
235 		  physname = alloca (p - real_physname + 1);
236 		  memcpy (physname, real_physname, p - real_physname);
237 		  physname[p - real_physname] = '\0';
238 
239 		  is_full_physname_constructor
240                     = (is_constructor_name (physname)
241                        || is_destructor_name (physname));
242 
243 		  QUIT;
244 
245 		  print_spaces_filtered (level + 4, stream);
246 
247 		  if (TYPE_FN_FIELD_PROTECTED (f, j))
248 		    fprintf_filtered (stream, "protected ");
249 		  else if (TYPE_FN_FIELD_PRIVATE (f, j))
250 		    fprintf_filtered (stream, "private ");
251 		  else if (TYPE_FN_FIELD_PUBLIC (f, j))
252 		    fprintf_filtered (stream, "public ");
253 
254 		  if (TYPE_FN_FIELD_ABSTRACT (f, j))
255 		    fprintf_filtered (stream, "abstract ");
256 		  if (TYPE_FN_FIELD_STATIC (f, j))
257 		    fprintf_filtered (stream, "static ");
258 		  if (TYPE_FN_FIELD_FINAL (f, j))
259 		    fprintf_filtered (stream, "final ");
260 		  if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
261 		    fprintf_filtered (stream, "synchronized ");
262 		  if (TYPE_FN_FIELD_NATIVE (f, j))
263 		    fprintf_filtered (stream, "native ");
264 
265 		  if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
266 		    {
267 		      /* Keep GDB from crashing here.  */
268 		      fprintf_filtered (stream, "<undefined type> %s;\n",
269 					TYPE_FN_FIELD_PHYSNAME (f, j));
270 		      break;
271 		    }
272 		  else if (!is_constructor && !is_full_physname_constructor)
273 		    {
274 		      type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
275 				  "", stream, -1);
276 		      fputs_filtered (" ", stream);
277 		    }
278 
279 		  if (TYPE_FN_FIELD_STUB (f, j))
280 		    /* Build something we can demangle.  */
281 		    mangled_name = gdb_mangle_name (type, i, j);
282 		  else
283 		    mangled_name = physname;
284 
285 		  demangled_name =
286 		    cplus_demangle (mangled_name,
287 				    DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
288 
289 		  if (demangled_name == NULL)
290 		    demangled_name = xstrdup (mangled_name);
291 
292 		  {
293 		    char *demangled_no_class;
294 		    char *ptr;
295 
296 		    ptr = demangled_no_class = demangled_name;
297 
298 		    while (1)
299 		      {
300 			char c;
301 
302 			c = *ptr++;
303 
304 			if (c == 0 || c == '(')
305 			  break;
306 			if (c == '.')
307 			  demangled_no_class = ptr;
308 		      }
309 
310 		    fputs_filtered (demangled_no_class, stream);
311 		    xfree (demangled_name);
312 		  }
313 
314 		  if (TYPE_FN_FIELD_STUB (f, j))
315 		    xfree (mangled_name);
316 
317 		  fprintf_filtered (stream, ";\n");
318 		}
319 	    }
320 
321 	  fprintfi_filtered (level, stream, "}");
322 	}
323       break;
324 
325     default:
326       c_type_print_base (type, stream, show, level);
327     }
328 }
329 
330 /* LEVEL is the depth to indent lines by.  */
331 
332 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
333 					 int, int, int);
334 
335 void
336 java_print_type (struct type *type, const char *varstring,
337 		 struct ui_file *stream, int show, int level)
338 {
339   int demangled_args;
340 
341   java_type_print_base (type, stream, show, level);
342 
343   if (varstring != NULL && *varstring != '\0')
344     {
345       fputs_filtered (" ", stream);
346       fputs_filtered (varstring, stream);
347     }
348 
349   /* For demangled function names, we have the arglist as part of the name,
350      so don't print an additional pair of ()'s.  */
351 
352   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
353   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
354 }
355