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