xref: /dragonfly/contrib/gdb-7/gdb/jv-typeprint.c (revision 2020c8fe)
1 /* Support for printing Java types for GDB, the GNU debugger.
2    Copyright (C) 1997, 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 
21 #include "defs.h"
22 #include "symtab.h"
23 #include "gdbtypes.h"
24 #include "value.h"
25 #include "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 		  char *real_physname, *physname, *p;
225 		  int is_full_physname_constructor;
226 
227 		  real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
228 
229 		  /* The physname will contain the return type
230 		     after the final closing parenthesis.  Strip it off.  */
231 		  p = strrchr (real_physname, ')');
232 		  gdb_assert (p != NULL);
233 		  ++p;   /* Keep the trailing ')'.  */
234 		  physname = alloca (p - real_physname + 1);
235 		  memcpy (physname, real_physname, p - real_physname);
236 		  physname[p - real_physname] = '\0';
237 
238 		  is_full_physname_constructor
239                     = (is_constructor_name (physname)
240                        || is_destructor_name (physname));
241 
242 		  QUIT;
243 
244 		  print_spaces_filtered (level + 4, stream);
245 
246 		  if (TYPE_FN_FIELD_PROTECTED (f, j))
247 		    fprintf_filtered (stream, "protected ");
248 		  else if (TYPE_FN_FIELD_PRIVATE (f, j))
249 		    fprintf_filtered (stream, "private ");
250 		  else if (TYPE_FN_FIELD_PUBLIC (f, j))
251 		    fprintf_filtered (stream, "public ");
252 
253 		  if (TYPE_FN_FIELD_ABSTRACT (f, j))
254 		    fprintf_filtered (stream, "abstract ");
255 		  if (TYPE_FN_FIELD_STATIC (f, j))
256 		    fprintf_filtered (stream, "static ");
257 		  if (TYPE_FN_FIELD_FINAL (f, j))
258 		    fprintf_filtered (stream, "final ");
259 		  if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
260 		    fprintf_filtered (stream, "synchronized ");
261 		  if (TYPE_FN_FIELD_NATIVE (f, j))
262 		    fprintf_filtered (stream, "native ");
263 
264 		  if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
265 		    {
266 		      /* Keep GDB from crashing here.  */
267 		      fprintf_filtered (stream, "<undefined type> %s;\n",
268 					TYPE_FN_FIELD_PHYSNAME (f, j));
269 		      break;
270 		    }
271 		  else if (!is_constructor && !is_full_physname_constructor)
272 		    {
273 		      type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
274 				  "", stream, -1);
275 		      fputs_filtered (" ", stream);
276 		    }
277 
278 		  if (TYPE_FN_FIELD_STUB (f, j))
279 		    /* Build something we can demangle.  */
280 		    mangled_name = gdb_mangle_name (type, i, j);
281 		  else
282 		    mangled_name = physname;
283 
284 		  demangled_name =
285 		    cplus_demangle (mangled_name,
286 				    DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
287 
288 		  if (demangled_name == NULL)
289 		    demangled_name = xstrdup (mangled_name);
290 
291 		  {
292 		    char *demangled_no_class;
293 		    char *ptr;
294 
295 		    ptr = demangled_no_class = demangled_name;
296 
297 		    while (1)
298 		      {
299 			char c;
300 
301 			c = *ptr++;
302 
303 			if (c == 0 || c == '(')
304 			  break;
305 			if (c == '.')
306 			  demangled_no_class = ptr;
307 		      }
308 
309 		    fputs_filtered (demangled_no_class, stream);
310 		    xfree (demangled_name);
311 		  }
312 
313 		  if (TYPE_FN_FIELD_STUB (f, j))
314 		    xfree (mangled_name);
315 
316 		  fprintf_filtered (stream, ";\n");
317 		}
318 	    }
319 
320 	  fprintfi_filtered (level, stream, "}");
321 	}
322       break;
323 
324     default:
325       c_type_print_base (type, stream, show, level);
326     }
327 }
328 
329 /* LEVEL is the depth to indent lines by.  */
330 
331 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
332 					 int, int, int);
333 
334 void
335 java_print_type (struct type *type, const char *varstring,
336 		 struct ui_file *stream, int show, int level)
337 {
338   int demangled_args;
339 
340   java_type_print_base (type, stream, show, level);
341 
342   if (varstring != NULL && *varstring != '\0')
343     {
344       fputs_filtered (" ", stream);
345       fputs_filtered (varstring, stream);
346     }
347 
348   /* For demangled function names, we have the arglist as part of the name,
349      so don't print an additional pair of ()'s.  */
350 
351   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
352   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
353 }
354