GDB (API)
|
00001 /* Support for printing Java types for GDB, the GNU debugger. 00002 Copyright (C) 1997-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 00020 #include "defs.h" 00021 #include "symtab.h" 00022 #include "gdbtypes.h" 00023 #include "value.h" 00024 #include "demangle.h" 00025 #include "gdb-demangle.h" 00026 #include "jv-lang.h" 00027 #include "gdb_string.h" 00028 #include "typeprint.h" 00029 #include "c-lang.h" 00030 #include "cp-abi.h" 00031 #include "cp-support.h" 00032 #include "gdb_assert.h" 00033 00034 /* Local functions */ 00035 00036 static void java_type_print_base (struct type * type, 00037 struct ui_file *stream, int show, 00038 int level, 00039 const struct type_print_options *flags); 00040 00041 static void 00042 java_type_print_derivation_info (struct ui_file *stream, struct type *type) 00043 { 00044 const char *name; 00045 int i; 00046 int n_bases; 00047 int prev; 00048 00049 n_bases = TYPE_N_BASECLASSES (type); 00050 00051 for (i = 0, prev = 0; i < n_bases; i++) 00052 { 00053 int kind; 00054 00055 kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E'; 00056 00057 fputs_filtered (kind == prev ? ", " 00058 : kind == 'I' ? " implements " 00059 : " extends ", 00060 stream); 00061 prev = kind; 00062 name = type_name_no_tag (TYPE_BASECLASS (type, i)); 00063 00064 fprintf_filtered (stream, "%s", name ? name : "(null)"); 00065 } 00066 00067 if (i > 0) 00068 fputs_filtered (" ", stream); 00069 } 00070 00071 /* Print the name of the type (or the ultimate pointer target, 00072 function value or array element), or the description of a 00073 structure or union. 00074 00075 SHOW positive means print details about the type (e.g. enum values), 00076 and print structure elements passing SHOW - 1 for show. 00077 SHOW negative means just print the type name or struct tag if there is one. 00078 If there is no name, print something sensible but concise like 00079 "struct {...}". 00080 SHOW zero means just print the type name or struct tag if there is one. 00081 If there is no name, print something sensible but not as concise like 00082 "struct {int x; int y;}". 00083 00084 LEVEL is the number of spaces to indent by. 00085 We increase it for some recursive calls. */ 00086 00087 static void 00088 java_type_print_base (struct type *type, struct ui_file *stream, int show, 00089 int level, const struct type_print_options *flags) 00090 { 00091 int i; 00092 int len; 00093 char *mangled_name; 00094 char *demangled_name; 00095 00096 QUIT; 00097 wrap_here (" "); 00098 00099 if (type == NULL) 00100 { 00101 fputs_filtered ("<type unknown>", stream); 00102 return; 00103 } 00104 00105 /* When SHOW is zero or less, and there is a valid type name, then always 00106 just print the type name directly from the type. */ 00107 00108 if (show <= 0 00109 && TYPE_NAME (type) != NULL) 00110 { 00111 fputs_filtered (TYPE_NAME (type), stream); 00112 return; 00113 } 00114 00115 CHECK_TYPEDEF (type); 00116 00117 switch (TYPE_CODE (type)) 00118 { 00119 case TYPE_CODE_PTR: 00120 java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level, 00121 flags); 00122 break; 00123 00124 case TYPE_CODE_STRUCT: 00125 if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') 00126 { /* array type */ 00127 char *name = java_demangle_type_signature (TYPE_TAG_NAME (type)); 00128 00129 fputs_filtered (name, stream); 00130 xfree (name); 00131 break; 00132 } 00133 00134 if (show >= 0) 00135 fprintf_filtered (stream, "class "); 00136 00137 if (TYPE_TAG_NAME (type) != NULL) 00138 { 00139 fputs_filtered (TYPE_TAG_NAME (type), stream); 00140 if (show > 0) 00141 fputs_filtered (" ", stream); 00142 } 00143 00144 wrap_here (" "); 00145 00146 if (show < 0) 00147 { 00148 /* If we just printed a tag name, no need to print anything else. */ 00149 if (TYPE_TAG_NAME (type) == NULL) 00150 fprintf_filtered (stream, "{...}"); 00151 } 00152 else if (show > 0 || TYPE_TAG_NAME (type) == NULL) 00153 { 00154 java_type_print_derivation_info (stream, type); 00155 00156 fprintf_filtered (stream, "{\n"); 00157 if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) 00158 { 00159 if (TYPE_STUB (type)) 00160 fprintfi_filtered (level + 4, stream, "<incomplete type>\n"); 00161 else 00162 fprintfi_filtered (level + 4, stream, "<no data fields>\n"); 00163 } 00164 00165 /* If there is a base class for this type, 00166 do not print the field that it occupies. */ 00167 00168 len = TYPE_NFIELDS (type); 00169 for (i = TYPE_N_BASECLASSES (type); i < len; i++) 00170 { 00171 QUIT; 00172 /* Don't print out virtual function table. */ 00173 if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 00174 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) 00175 continue; 00176 00177 /* Don't print the dummy field "class". */ 00178 if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0) 00179 continue; 00180 00181 print_spaces_filtered (level + 4, stream); 00182 00183 if (HAVE_CPLUS_STRUCT (type)) 00184 { 00185 if (TYPE_FIELD_PROTECTED (type, i)) 00186 fprintf_filtered (stream, "protected "); 00187 else if (TYPE_FIELD_PRIVATE (type, i)) 00188 fprintf_filtered (stream, "private "); 00189 else 00190 fprintf_filtered (stream, "public "); 00191 } 00192 00193 if (field_is_static (&TYPE_FIELD (type, i))) 00194 fprintf_filtered (stream, "static "); 00195 00196 java_print_type (TYPE_FIELD_TYPE (type, i), 00197 TYPE_FIELD_NAME (type, i), 00198 stream, show - 1, level + 4, flags); 00199 00200 fprintf_filtered (stream, ";\n"); 00201 } 00202 00203 /* If there are both fields and methods, put a space between. */ 00204 len = TYPE_NFN_FIELDS (type); 00205 if (len) 00206 fprintf_filtered (stream, "\n"); 00207 00208 /* Print out the methods. */ 00209 00210 for (i = 0; i < len; i++) 00211 { 00212 struct fn_field *f; 00213 int j; 00214 const char *method_name; 00215 const char *name; 00216 int is_constructor; 00217 int n_overloads; 00218 00219 f = TYPE_FN_FIELDLIST1 (type, i); 00220 n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i); 00221 method_name = TYPE_FN_FIELDLIST_NAME (type, i); 00222 name = type_name_no_tag (type); 00223 is_constructor = name && strcmp (method_name, name) == 0; 00224 00225 for (j = 0; j < n_overloads; j++) 00226 { 00227 const char *real_physname; 00228 char *physname, *p; 00229 int is_full_physname_constructor; 00230 00231 real_physname = TYPE_FN_FIELD_PHYSNAME (f, j); 00232 00233 /* The physname will contain the return type 00234 after the final closing parenthesis. Strip it off. */ 00235 p = strrchr (real_physname, ')'); 00236 gdb_assert (p != NULL); 00237 ++p; /* Keep the trailing ')'. */ 00238 physname = alloca (p - real_physname + 1); 00239 memcpy (physname, real_physname, p - real_physname); 00240 physname[p - real_physname] = '\0'; 00241 00242 is_full_physname_constructor 00243 = (TYPE_FN_FIELD_CONSTRUCTOR (f, j) 00244 || is_constructor_name (physname) 00245 || is_destructor_name (physname)); 00246 00247 QUIT; 00248 00249 print_spaces_filtered (level + 4, stream); 00250 00251 if (TYPE_FN_FIELD_PROTECTED (f, j)) 00252 fprintf_filtered (stream, "protected "); 00253 else if (TYPE_FN_FIELD_PRIVATE (f, j)) 00254 fprintf_filtered (stream, "private "); 00255 else if (TYPE_FN_FIELD_PUBLIC (f, j)) 00256 fprintf_filtered (stream, "public "); 00257 00258 if (TYPE_FN_FIELD_ABSTRACT (f, j)) 00259 fprintf_filtered (stream, "abstract "); 00260 if (TYPE_FN_FIELD_STATIC (f, j)) 00261 fprintf_filtered (stream, "static "); 00262 if (TYPE_FN_FIELD_FINAL (f, j)) 00263 fprintf_filtered (stream, "final "); 00264 if (TYPE_FN_FIELD_SYNCHRONIZED (f, j)) 00265 fprintf_filtered (stream, "synchronized "); 00266 if (TYPE_FN_FIELD_NATIVE (f, j)) 00267 fprintf_filtered (stream, "native "); 00268 00269 if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) 00270 { 00271 /* Keep GDB from crashing here. */ 00272 fprintf_filtered (stream, "<undefined type> %s;\n", 00273 TYPE_FN_FIELD_PHYSNAME (f, j)); 00274 break; 00275 } 00276 else if (!is_constructor && !is_full_physname_constructor) 00277 { 00278 type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), 00279 "", stream, -1); 00280 fputs_filtered (" ", stream); 00281 } 00282 00283 if (TYPE_FN_FIELD_STUB (f, j)) 00284 /* Build something we can demangle. */ 00285 mangled_name = gdb_mangle_name (type, i, j); 00286 else 00287 mangled_name = physname; 00288 00289 demangled_name = 00290 gdb_demangle (mangled_name, 00291 DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); 00292 00293 if (demangled_name == NULL) 00294 demangled_name = xstrdup (mangled_name); 00295 00296 { 00297 char *demangled_no_class; 00298 char *ptr; 00299 00300 ptr = demangled_no_class = demangled_name; 00301 00302 while (1) 00303 { 00304 char c; 00305 00306 c = *ptr++; 00307 00308 if (c == 0 || c == '(') 00309 break; 00310 if (c == '.') 00311 demangled_no_class = ptr; 00312 } 00313 00314 fputs_filtered (demangled_no_class, stream); 00315 xfree (demangled_name); 00316 } 00317 00318 if (TYPE_FN_FIELD_STUB (f, j)) 00319 xfree (mangled_name); 00320 00321 fprintf_filtered (stream, ";\n"); 00322 } 00323 } 00324 00325 fprintfi_filtered (level, stream, "}"); 00326 } 00327 break; 00328 00329 default: 00330 c_type_print_base (type, stream, show, level, flags); 00331 } 00332 } 00333 00334 /* LEVEL is the depth to indent lines by. */ 00335 00336 void 00337 java_print_type (struct type *type, const char *varstring, 00338 struct ui_file *stream, int show, int level, 00339 const struct type_print_options *flags) 00340 { 00341 int demangled_args; 00342 00343 java_type_print_base (type, stream, show, level, flags); 00344 00345 if (varstring != NULL && *varstring != '\0') 00346 { 00347 fputs_filtered (" ", stream); 00348 fputs_filtered (varstring, stream); 00349 } 00350 00351 /* For demangled function names, we have the arglist as part of the name, 00352 so don't print an additional pair of ()'s. */ 00353 00354 demangled_args = varstring != NULL && strchr (varstring, '(') != NULL; 00355 c_type_print_varspec_suffix (type, stream, show, 0, demangled_args, flags); 00356 }