146283Sdfr/* Support for printing Java types for GDB, the GNU debugger. 298944Sobrien Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 346283Sdfr 498944Sobrien This file is part of GDB. 546283Sdfr 698944Sobrien This program is free software; you can redistribute it and/or modify 798944Sobrien it under the terms of the GNU General Public License as published by 898944Sobrien the Free Software Foundation; either version 2 of the License, or 998944Sobrien (at your option) any later version. 1046283Sdfr 1198944Sobrien This program is distributed in the hope that it will be useful, 1298944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1398944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1498944Sobrien GNU General Public License for more details. 1546283Sdfr 1698944Sobrien You should have received a copy of the GNU General Public License 1798944Sobrien along with this program; if not, write to the Free Software 1898944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 1998944Sobrien Boston, MA 02111-1307, USA. */ 2046283Sdfr 2146283Sdfr 2246283Sdfr#include "defs.h" 2346283Sdfr#include "symtab.h" 2446283Sdfr#include "gdbtypes.h" 2546283Sdfr#include "value.h" 2646283Sdfr#include "demangle.h" 2746283Sdfr#include "jv-lang.h" 2846283Sdfr#include "gdb_string.h" 2946283Sdfr#include "typeprint.h" 3098944Sobrien#include "c-lang.h" 3198944Sobrien#include "cp-abi.h" 3246283Sdfr 3398944Sobrien/* Local functions */ 3498944Sobrien 3598944Sobrienstatic void java_type_print_base (struct type * type, 3698944Sobrien struct ui_file *stream, int show, 3798944Sobrien int level); 3898944Sobrien 3946283Sdfrstatic void 4098944Sobrienjava_type_print_derivation_info (struct ui_file *stream, struct type *type) 4146283Sdfr{ 4246283Sdfr char *name; 4346283Sdfr int i; 4446283Sdfr int n_bases; 4546283Sdfr int prev; 4646283Sdfr 4746283Sdfr n_bases = TYPE_N_BASECLASSES (type); 4846283Sdfr 4946283Sdfr for (i = 0, prev = 0; i < n_bases; i++) 5046283Sdfr { 5146283Sdfr int kind; 5246283Sdfr 5398944Sobrien kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E'; 5446283Sdfr 5546283Sdfr fputs_filtered (kind == prev ? ", " 5646283Sdfr : kind == 'I' ? " implements " 5746283Sdfr : " extends ", 5846283Sdfr stream); 5946283Sdfr prev = kind; 6046283Sdfr name = type_name_no_tag (TYPE_BASECLASS (type, i)); 6146283Sdfr 6246283Sdfr fprintf_filtered (stream, "%s", name ? name : "(null)"); 6346283Sdfr } 6446283Sdfr 6546283Sdfr if (i > 0) 6646283Sdfr fputs_filtered (" ", stream); 6746283Sdfr} 6846283Sdfr 6946283Sdfr/* Print the name of the type (or the ultimate pointer target, 7046283Sdfr function value or array element), or the description of a 7146283Sdfr structure or union. 7246283Sdfr 7346283Sdfr SHOW positive means print details about the type (e.g. enum values), 7446283Sdfr and print structure elements passing SHOW - 1 for show. 7546283Sdfr SHOW negative means just print the type name or struct tag if there is one. 7646283Sdfr If there is no name, print something sensible but concise like 7746283Sdfr "struct {...}". 7846283Sdfr SHOW zero means just print the type name or struct tag if there is one. 7946283Sdfr If there is no name, print something sensible but not as concise like 8046283Sdfr "struct {int x; int y;}". 8146283Sdfr 8246283Sdfr LEVEL is the number of spaces to indent by. 8346283Sdfr We increase it for some recursive calls. */ 8446283Sdfr 8598944Sobrienstatic void 8698944Sobrienjava_type_print_base (struct type *type, struct ui_file *stream, int show, 8798944Sobrien int level) 8846283Sdfr{ 89130803Smarcel int i; 90130803Smarcel int len; 9146283Sdfr char *mangled_name; 9246283Sdfr char *demangled_name; 9346283Sdfr QUIT; 9446283Sdfr 9546283Sdfr wrap_here (" "); 9646283Sdfr 9746283Sdfr if (type == NULL) 9846283Sdfr { 9946283Sdfr fputs_filtered ("<type unknown>", stream); 10046283Sdfr return; 10146283Sdfr } 10246283Sdfr 10346283Sdfr /* When SHOW is zero or less, and there is a valid type name, then always 10446283Sdfr just print the type name directly from the type. */ 10546283Sdfr 10646283Sdfr if (show <= 0 10746283Sdfr && TYPE_NAME (type) != NULL) 10846283Sdfr { 10946283Sdfr fputs_filtered (TYPE_NAME (type), stream); 11046283Sdfr return; 11146283Sdfr } 11246283Sdfr 11346283Sdfr CHECK_TYPEDEF (type); 11446283Sdfr 11546283Sdfr switch (TYPE_CODE (type)) 11646283Sdfr { 11746283Sdfr case TYPE_CODE_PTR: 11846283Sdfr java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); 11946283Sdfr break; 12046283Sdfr 12146283Sdfr case TYPE_CODE_STRUCT: 12246283Sdfr if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') 12346283Sdfr { /* array type */ 12446283Sdfr char *name = java_demangle_type_signature (TYPE_TAG_NAME (type)); 12546283Sdfr fputs_filtered (name, stream); 12698944Sobrien xfree (name); 12746283Sdfr break; 12846283Sdfr } 12946283Sdfr 13046283Sdfr if (show >= 0) 13146283Sdfr fprintf_filtered (stream, "class "); 13246283Sdfr 13346283Sdfr if (TYPE_TAG_NAME (type) != NULL) 13446283Sdfr { 13546283Sdfr fputs_filtered (TYPE_TAG_NAME (type), stream); 13646283Sdfr if (show > 0) 13746283Sdfr fputs_filtered (" ", stream); 13846283Sdfr } 13946283Sdfr 14046283Sdfr wrap_here (" "); 14146283Sdfr 14246283Sdfr if (show < 0) 14346283Sdfr { 14446283Sdfr /* If we just printed a tag name, no need to print anything else. */ 14546283Sdfr if (TYPE_TAG_NAME (type) == NULL) 14646283Sdfr fprintf_filtered (stream, "{...}"); 14746283Sdfr } 14846283Sdfr else if (show > 0 || TYPE_TAG_NAME (type) == NULL) 14946283Sdfr { 15046283Sdfr java_type_print_derivation_info (stream, type); 15198944Sobrien 15246283Sdfr fprintf_filtered (stream, "{\n"); 15346283Sdfr if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) 15498944Sobrien { 15598944Sobrien if (TYPE_STUB (type)) 15698944Sobrien fprintfi_filtered (level + 4, stream, "<incomplete type>\n"); 15798944Sobrien else 15898944Sobrien fprintfi_filtered (level + 4, stream, "<no data fields>\n"); 15998944Sobrien } 16046283Sdfr 16146283Sdfr /* If there is a base class for this type, 16246283Sdfr do not print the field that it occupies. */ 16346283Sdfr 16446283Sdfr len = TYPE_NFIELDS (type); 16546283Sdfr for (i = TYPE_N_BASECLASSES (type); i < len; i++) 16646283Sdfr { 16746283Sdfr QUIT; 16846283Sdfr /* Don't print out virtual function table. */ 169130803Smarcel if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 17046283Sdfr && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) 17146283Sdfr continue; 17246283Sdfr 17346283Sdfr /* Don't print the dummy field "class". */ 174130803Smarcel if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0) 17546283Sdfr continue; 17646283Sdfr 17746283Sdfr print_spaces_filtered (level + 4, stream); 17846283Sdfr 17946283Sdfr if (HAVE_CPLUS_STRUCT (type)) 18098944Sobrien { 18198944Sobrien if (TYPE_FIELD_PROTECTED (type, i)) 18298944Sobrien fprintf_filtered (stream, "protected "); 18398944Sobrien else if (TYPE_FIELD_PRIVATE (type, i)) 18498944Sobrien fprintf_filtered (stream, "private "); 18598944Sobrien else 18698944Sobrien fprintf_filtered (stream, "public "); 18798944Sobrien } 18846283Sdfr 18946283Sdfr if (TYPE_FIELD_STATIC (type, i)) 19046283Sdfr fprintf_filtered (stream, "static "); 19146283Sdfr 19246283Sdfr java_print_type (TYPE_FIELD_TYPE (type, i), 19346283Sdfr TYPE_FIELD_NAME (type, i), 19446283Sdfr stream, show - 1, level + 4); 19546283Sdfr 19646283Sdfr fprintf_filtered (stream, ";\n"); 19746283Sdfr } 19846283Sdfr 19946283Sdfr /* If there are both fields and methods, put a space between. */ 20046283Sdfr len = TYPE_NFN_FIELDS (type); 20146283Sdfr if (len) 20298944Sobrien fprintf_filtered (stream, "\n"); 20346283Sdfr 20446283Sdfr /* Print out the methods */ 20546283Sdfr 20646283Sdfr for (i = 0; i < len; i++) 20746283Sdfr { 20846283Sdfr struct fn_field *f; 20946283Sdfr int j; 21046283Sdfr char *method_name; 21146283Sdfr char *name; 21246283Sdfr int is_constructor; 21346283Sdfr int n_overloads; 21446283Sdfr 21546283Sdfr f = TYPE_FN_FIELDLIST1 (type, i); 21646283Sdfr n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i); 21746283Sdfr method_name = TYPE_FN_FIELDLIST_NAME (type, i); 21846283Sdfr name = type_name_no_tag (type); 219130803Smarcel is_constructor = name && strcmp (method_name, name) == 0; 22046283Sdfr 22146283Sdfr for (j = 0; j < n_overloads; j++) 22246283Sdfr { 22346283Sdfr char *physname; 22446283Sdfr int is_full_physname_constructor; 22546283Sdfr 22646283Sdfr physname = TYPE_FN_FIELD_PHYSNAME (f, j); 22746283Sdfr 22898944Sobrien is_full_physname_constructor 22998944Sobrien = (is_constructor_name (physname) 23098944Sobrien || is_destructor_name (physname)); 23146283Sdfr 23246283Sdfr QUIT; 23346283Sdfr 23446283Sdfr print_spaces_filtered (level + 4, stream); 23546283Sdfr 23646283Sdfr if (TYPE_FN_FIELD_PROTECTED (f, j)) 23746283Sdfr fprintf_filtered (stream, "protected "); 23846283Sdfr else if (TYPE_FN_FIELD_PRIVATE (f, j)) 23946283Sdfr fprintf_filtered (stream, "private "); 24046283Sdfr else if (TYPE_FN_FIELD_PUBLIC (f, j)) 24146283Sdfr fprintf_filtered (stream, "public "); 24246283Sdfr 24346283Sdfr if (TYPE_FN_FIELD_ABSTRACT (f, j)) 24446283Sdfr fprintf_filtered (stream, "abstract "); 24546283Sdfr if (TYPE_FN_FIELD_STATIC (f, j)) 24646283Sdfr fprintf_filtered (stream, "static "); 24746283Sdfr if (TYPE_FN_FIELD_FINAL (f, j)) 24846283Sdfr fprintf_filtered (stream, "final "); 24946283Sdfr if (TYPE_FN_FIELD_SYNCHRONIZED (f, j)) 25046283Sdfr fprintf_filtered (stream, "synchronized "); 25146283Sdfr if (TYPE_FN_FIELD_NATIVE (f, j)) 25246283Sdfr fprintf_filtered (stream, "native "); 25346283Sdfr 25446283Sdfr if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) 25546283Sdfr { 25646283Sdfr /* Keep GDB from crashing here. */ 25746283Sdfr fprintf_filtered (stream, "<undefined type> %s;\n", 25898944Sobrien TYPE_FN_FIELD_PHYSNAME (f, j)); 25946283Sdfr break; 26046283Sdfr } 26146283Sdfr else if (!is_constructor && !is_full_physname_constructor) 26246283Sdfr { 26346283Sdfr type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), 26446283Sdfr "", stream, -1); 26546283Sdfr fputs_filtered (" ", stream); 26646283Sdfr } 26746283Sdfr 26846283Sdfr if (TYPE_FN_FIELD_STUB (f, j)) 26946283Sdfr /* Build something we can demangle. */ 27046283Sdfr mangled_name = gdb_mangle_name (type, i, j); 27146283Sdfr else 27246283Sdfr mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j); 27346283Sdfr 27446283Sdfr demangled_name = 27546283Sdfr cplus_demangle (mangled_name, 27646283Sdfr DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); 27746283Sdfr 27846283Sdfr if (demangled_name == NULL) 27998944Sobrien demangled_name = xstrdup (mangled_name); 28046283Sdfr 28146283Sdfr { 28246283Sdfr char *demangled_no_class; 28346283Sdfr char *ptr; 28446283Sdfr 28546283Sdfr ptr = demangled_no_class = demangled_name; 28646283Sdfr 28746283Sdfr while (1) 28846283Sdfr { 28946283Sdfr char c; 29046283Sdfr 29146283Sdfr c = *ptr++; 29246283Sdfr 29346283Sdfr if (c == 0 || c == '(') 29446283Sdfr break; 29546283Sdfr if (c == '.') 29646283Sdfr demangled_no_class = ptr; 29746283Sdfr } 29846283Sdfr 29946283Sdfr fputs_filtered (demangled_no_class, stream); 30098944Sobrien xfree (demangled_name); 30146283Sdfr } 30246283Sdfr 30346283Sdfr if (TYPE_FN_FIELD_STUB (f, j)) 30498944Sobrien xfree (mangled_name); 30546283Sdfr 30646283Sdfr fprintf_filtered (stream, ";\n"); 30746283Sdfr } 30846283Sdfr } 30946283Sdfr 31046283Sdfr fprintfi_filtered (level, stream, "}"); 31146283Sdfr } 31246283Sdfr break; 31346283Sdfr 31498944Sobrien default: 31598944Sobrien c_type_print_base (type, stream, show, level); 31646283Sdfr } 31746283Sdfr} 31846283Sdfr 31946283Sdfr/* LEVEL is the depth to indent lines by. */ 32046283Sdfr 32198944Sobrienextern void c_type_print_varspec_suffix (struct type *, struct ui_file *, 32298944Sobrien int, int, int); 32398944Sobrien 32446283Sdfrvoid 32598944Sobrienjava_print_type (struct type *type, char *varstring, struct ui_file *stream, 32698944Sobrien int show, int level) 32746283Sdfr{ 32846283Sdfr int demangled_args; 32946283Sdfr 33046283Sdfr java_type_print_base (type, stream, show, level); 33146283Sdfr 33246283Sdfr if (varstring != NULL && *varstring != '\0') 33346283Sdfr { 33446283Sdfr fputs_filtered (" ", stream); 33546283Sdfr fputs_filtered (varstring, stream); 33646283Sdfr } 33746283Sdfr 33846283Sdfr /* For demangled function names, we have the arglist as part of the name, 33946283Sdfr so don't print an additional pair of ()'s */ 34046283Sdfr 34198944Sobrien demangled_args = strchr (varstring, '(') != NULL; 34246283Sdfr c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); 34346283Sdfr} 344