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