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