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