* java-*: Renamed to jv-*, to make fit within 14 characters.
authorPer Bothner <per@bothner.com>
Thu, 31 Jul 1997 22:39:34 +0000 (22:39 +0000)
committerPer Bothner <per@bothner.com>
Thu, 31 Jul 1997 22:39:34 +0000 (22:39 +0000)
* jv-lang.h (java_type_print):  Added declaration.
* jv-typeprint.c:  New file.  Provides java_print_type.
* jv-lang.c (java_link_class_type):  New function.
(java_language_defn):  Replace c_print_type by java_print_type.
* Makefile.in:  Update accordingly.

12 files changed:
gdb/.Sanitize
gdb/ChangeLog
gdb/Makefile.in
gdb/java-exp.y [deleted file]
gdb/java-lang.c [deleted file]
gdb/java-lang.h [deleted file]
gdb/java-valprint.c [deleted file]
gdb/jv-exp.y [new file with mode: 0644]
gdb/jv-lang.c [new file with mode: 0644]
gdb/jv-lang.h [new file with mode: 0644]
gdb/jv-typeprint.c [new file with mode: 0644]
gdb/jv-valprint.c [new file with mode: 0644]

index 06d8765c5d4d0b85943ef45b96e2060c7b772f8c..08d0b238c08595dc68891c9c01b07bd93fe89457 100644 (file)
@@ -263,10 +263,11 @@ inftarg.c
 irix4-nat.c
 irix5-nat.c
 isi-xdep.c
-java-exp.y
-java-lang.c
-java-lang.h
-java-valprint.c
+jv-exp.y
+jv-lang.c
+jv-lang.h
+jv-valprint.c
+jv-typeprint.c
 kdb-start.c
 language.c
 language.h
index a3e16a93dcfcd0d9fb9035a1b8ba51b24c46146b..6dd60eec376dab847ed5376d845ce87ecd2a6217 100644 (file)
@@ -1,3 +1,12 @@
+Wed Jul 30 14:04:18 1997  Per Bothner  <bothner@cygnus.com>
+
+       * java-*:  Renamed to jv-*, to make fit within 14 characters.
+       * jv-lang.h (java_type_print):  Added declaration.
+       * jv-typeprint.c:  New file.  Provides java_print_type.
+       * jv-lang.c (java_link_class_type):  New function.
+       (java_language_defn):  Replace c_print_type by java_print_type.
+       * Makefile.in:  Update accordingly.
+
 Tue Jul 29 10:12:44 1997  Felix Lee  <flee@cygnus.com>
 
        * Makefile.in (init.c): except some mswin files do need to be
index bec9aa8276d65eb391923edc0e943c16a33d4993..0637f5bef7c5666d67258a2ab73f2aa6c4b249fb 100644 (file)
@@ -381,7 +381,7 @@ SFILES = bcache.c blockframe.c breakpoint.c buildsym.c c-exp.y \
        elfread.c environ.c eval.c expprint.c \
        f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c \
        gdbtypes.c infcmd.c inflow.c infrun.c language.c \
-       java-exp.y java-lang.c java-valprint.c \
+       jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
        m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
        mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c parse.c \
        printcmd.c remote.c remote-nrom.c scm-exp.c scm-lang.c scm-valprint.c \
@@ -451,7 +451,7 @@ HFILES_NO_SRCDIR = bcache.h buildsym.h call-cmds.h coff-solib.h defs.h \
        gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \
        objfiles.h parser-defs.h partial-stab.h serial.h signals.h solib.h \
        symfile.h stabsread.h target.h terminal.h typeprint.h xcoffsolib.h \
-       c-lang.h ch-lang.h f-lang.h java-lang.h m2-lang.h \
+       c-lang.h ch-lang.h f-lang.h jv-lang.h m2-lang.h \
        complaints.h valprint.h \
        29k-share/udi/udiids.h 29k-share/udi_soc nindy-share/b.out.h \
        nindy-share/block_io.h nindy-share/coff.h \
@@ -498,7 +498,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \
        dbxread.o coffread.o elfread.o \
        dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
        c-lang.o ch-exp.o ch-lang.o f-lang.o \
-       java-lang.o java-valprint.o m2-lang.o \
+       jv-lang.o jv-valprint.o jv-typeprint.o m2-lang.o \
        scm-exp.o scm-lang.o scm-valprint.o complaints.o typeprint.o \
        c-typeprint.o ch-typeprint.o f-typeprint.o m2-typeprint.o \
        c-valprint.o cp-valprint.o ch-valprint.o f-valprint.o m2-valprint.o \
@@ -517,8 +517,8 @@ NTSSTART = kdb-start.o
 SUBDIRS = doc testsuite nlm mswin
 
 # For now, shortcut the "configure GDB for fewer languages" stuff.
-YYFILES = c-exp.tab.c java-exp.tab.c f-exp.tab.c m2-exp.tab.c
-YYOBJ = c-exp.tab.o java-exp.tab.o f-exp.tab.o m2-exp.tab.o
+YYFILES = c-exp.tab.c jv-exp.tab.c f-exp.tab.c m2-exp.tab.c
+YYOBJ = c-exp.tab.o jv-exp.tab.o f-exp.tab.o m2-exp.tab.o
 
 # Things which need to be built when making a distribution.
 
@@ -666,10 +666,10 @@ libgdb-files: $(LIBGDBDEPS) Makefile.in
 saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c
        #setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS
        #load ./init.c $(SFILES)
-       #unload $(srcdir)/c-exp.y $(srcdir)/java-exp.y $(srcdir)/m2-exp.y
+       #unload $(srcdir)/c-exp.y $(srcdir)/jv-exp.y $(srcdir)/m2-exp.y
        #unload vx-share/*.h
        #unload nindy-share/[A-Z]*
-       #load c-exp.tab.c java-exp.tab.c m2-exp.tab.c
+       #load c-exp.tab.c jv-exp.tab.c m2-exp.tab.c
        #load copying.c version.c
        #load ../opcodes/libopcodes.a
        #load ../libiberty/libiberty.a
@@ -773,7 +773,7 @@ maintainer-clean realclean: distclean clean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
        @$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(SUBDIRS)" subdir_do
-       rm -f c-exp.tab.c java-exp.tab.c f-exp.tab.c m2-exp.tab.c
+       rm -f c-exp.tab.c jv-exp.tab.c f-exp.tab.c m2-exp.tab.c
        rm -f TAGS $(INFOFILES)
        rm -f nm.h tm.h xm.h config.status
 
@@ -850,9 +850,9 @@ c-exp.tab.c: c-exp.y
        -rm y.tab.c
        mv c-exp.new ./c-exp.tab.c
 
-java-exp.tab.o: java-exp.tab.c
-java-exp.tab.c: java-exp.y
-       $(YACC) $(YFLAGS) $(srcdir)/java-exp.y
+jv-exp.tab.o: jv-exp.tab.c
+jv-exp.tab.c: jv-exp.y
+       $(YACC) $(YFLAGS) $(srcdir)/jv-exp.y
        -sed -e '/extern.*malloc/d' \
             -e '/extern.*realloc/d' \
             -e '/extern.*free/d' \
@@ -860,9 +860,9 @@ java-exp.tab.c: java-exp.y
             -e 's/malloc/xmalloc/g' \
             -e 's/realloc/xrealloc/g' \
             -e '/^#line.*y.tab.c/d' \
-         < y.tab.c > java-exp.new
+         < y.tab.c > jv-exp.new
        -rm y.tab.c
-       mv java-exp.new ./java-exp.tab.c
+       mv jv-exp.new ./jv-exp.tab.c
 
 f-exp.tab.o: f-exp.tab.c
 f-exp.tab.c: f-exp.y c-exp.tab.c
@@ -897,7 +897,7 @@ m2-exp.tab.c: m2-exp.y
        mv m2-exp.new ./m2-exp.tab.c
 
 # These files are updated atomically, so make never has to remove them
-.PRECIOUS: m2-exp.tab.c java-exp.tab.c f-exp.tab.c c-exp.tab.c
+.PRECIOUS: m2-exp.tab.c jv-exp.tab.c f-exp.tab.c c-exp.tab.c
 
 lint: $(LINTFILES)
        $(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES) \
@@ -1631,7 +1631,7 @@ c-exp.tab.o: c-exp.tab.c c-lang.h $(defs_h) $(expression_h) \
        $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
        $(bfd_h) objfiles.h symfile.h
 
-java-exp.tab.o: java-exp.tab.c java-lang.h $(defs_h) $(expression_h) \
+jv-exp.tab.o: jv-exp.tab.c jv-lang.h $(defs_h) $(expression_h) \
        $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
        $(bfd_h) objfiles.h symfile.h
 
diff --git a/gdb/java-exp.y b/gdb/java-exp.y
deleted file mode 100644 (file)
index 0e9ac47..0000000
+++ /dev/null
@@ -1,1233 +0,0 @@
-/* YACC parser for Java expressions, for GDB.
-   Copyright (C) 1997.
-   Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-/* Parse a C expression from text in a string,
-   and return the result as a  struct expression  pointer.
-   That structure contains arithmetic operations in reverse polish,
-   with constants represented by operations that are followed by special data.
-   See expression.h for the details of the format.
-   What is important here is that it can be built up sequentially
-   during the process of parsing; the lower levels of the tree always
-   come first in the result.
-
-   Note that malloc's and realloc's in this file are transformed to
-   xmalloc and xrealloc respectively by the same sed command in the
-   makefile that remaps any other malloc/realloc inserted by the parser
-   generator.  Doing this with #defines and trying to control the interaction
-   with include files (<malloc.h> and <stdlib.h> for example) just became
-   too messy, particularly when such includes can be inserted at random
-   times by the parser generator.  */
-  
-%{
-
-#include "defs.h"
-#include "gdb_string.h"
-#include <ctype.h>
-#include "expression.h"
-#include "value.h"
-#include "parser-defs.h"
-#include "language.h"
-#include "java-lang.h"
-#include "bfd.h" /* Required by objfiles.h.  */
-#include "symfile.h" /* Required by objfiles.h.  */
-#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
-
-/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
-   as well as gratuitiously global symbol names, so we can have multiple
-   yacc generated parsers in gdb.  Note that these are only the variables
-   produced by yacc.  If other parser generators (bison, byacc, etc) produce
-   additional global names that conflict at link time, then those parser
-   generators need to be fixed instead of adding those names to this list. */
-
-#define        yymaxdepth java_maxdepth
-#define        yyparse java_parse
-#define        yylex   java_lex
-#define        yyerror java_error
-#define        yylval  java_lval
-#define        yychar  java_char
-#define        yydebug java_debug
-#define        yypact  java_pact       
-#define        yyr1    java_r1                 
-#define        yyr2    java_r2                 
-#define        yydef   java_def                
-#define        yychk   java_chk                
-#define        yypgo   java_pgo                
-#define        yyact   java_act                
-#define        yyexca  java_exca
-#define yyerrflag java_errflag
-#define yynerrs        java_nerrs
-#define        yyps    java_ps
-#define        yypv    java_pv
-#define        yys     java_s
-#define        yy_yys  java_yys
-#define        yystate java_state
-#define        yytmp   java_tmp
-#define        yyv     java_v
-#define        yy_yyv  java_yyv
-#define        yyval   java_val
-#define        yylloc  java_lloc
-#define yyreds java_reds               /* With YYDEBUG defined */
-#define yytoks java_toks               /* With YYDEBUG defined */
-#define yylhs  java_yylhs
-#define yylen  java_yylen
-#define yydefred java_yydefred
-#define yydgoto        java_yydgoto
-#define yysindex java_yysindex
-#define yyrindex java_yyrindex
-#define yygindex java_yygindex
-#define yytable         java_yytable
-#define yycheck         java_yycheck
-
-#ifndef YYDEBUG
-#define        YYDEBUG 0               /* Default to no yydebug support */
-#endif
-
-int
-yyparse PARAMS ((void));
-
-static int
-yylex PARAMS ((void));
-
-void
-yyerror PARAMS ((char *));
-
-static struct type * java_type_from_name PARAMS ((struct stoken));
-static void push_variable PARAMS ((struct stoken));
-
-%}
-
-/* Although the yacc "value" of an expression is not used,
-   since the result is stored in the structure being created,
-   other node types do have values.  */
-
-%union
-  {
-    LONGEST lval;
-    struct {
-      LONGEST val;
-      struct type *type;
-    } typed_val_int;
-    struct {
-      DOUBLEST dval;
-      struct type *type;
-    } typed_val_float;
-    struct symbol *sym;
-    struct type *tval;
-    struct stoken sval;
-    struct ttype tsym;
-    struct symtoken ssym;
-    struct block *bval;
-    enum exp_opcode opcode;
-    struct internalvar *ivar;
-    int *ivec;
-  }
-
-%{
-/* YYSTYPE gets defined by %union */
-static int
-parse_number PARAMS ((char *, int, int, YYSTYPE *));
-%}
-
-%type <lval> rcurly Dims Dims_opt
-%type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
-%type <tval> IntegralType FloatingPointType NumericType PrimitiveType
-
-%token <typed_val_int> INTEGER_LITERAL
-%token <typed_val_float> FLOATING_POINT_LITERAL
-
-%token <sval> IDENTIFIER
-%token <sval> STRING_LITERAL
-%token <lval> BOOLEAN_LITERAL
-%token <tsym> TYPENAME
-%type <sval> Name SimpleName QualifiedName ForcedName
-
-/* A NAME_OR_INT is a symbol which is not known in the symbol table,
-   but which would parse as a valid number in the current input radix.
-   E.g. "c" when input_radix==16.  Depending on the parse, it will be
-   turned into a name or into a number.  */
-
-%token <sval> NAME_OR_INT 
-
-%token ERROR
-
-/* Special type cases, put in to allow the parser to distinguish different
-   legal basetypes.  */
-%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
-
-%token VARIABLE
-
-%token <opcode> ASSIGN_MODIFY
-
-%token THIS SUPER NEW
-
-%left ','
-%right '=' ASSIGN_MODIFY
-%right '?'
-%left OROR
-%left ANDAND
-%left '|'
-%left '^'
-%left '&'
-%left EQUAL NOTEQUAL
-%left '<' '>' LEQ GEQ
-%left LSH RSH
-%left '+' '-'
-%left '*' '/' '%'
-%right INCREMENT DECREMENT
-%right '.' '[' '('
-
-\f
-%%
-
-start   :      exp1
-/*     |       type_exp FIXME */
-       ;
-
-StringLiteral:
-       STRING_LITERAL
-               {
-                 write_exp_elt_opcode (OP_STRING);
-                 write_exp_string ($1);
-                 write_exp_elt_opcode (OP_STRING);
-               }
-;
-
-Literal        :
-       INTEGER_LITERAL
-               { write_exp_elt_opcode (OP_LONG);
-                 write_exp_elt_type ($1.type);
-                 write_exp_elt_longcst ((LONGEST)($1.val));
-                 write_exp_elt_opcode (OP_LONG); }
-|      NAME_OR_INT
-               { YYSTYPE val;
-                 parse_number ($1.ptr, $1.length, 0, &val);
-                 write_exp_elt_opcode (OP_LONG);
-                 write_exp_elt_type (val.typed_val_int.type);
-                 write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
-                 write_exp_elt_opcode (OP_LONG);
-               }
-|      FLOATING_POINT_LITERAL
-               { write_exp_elt_opcode (OP_DOUBLE);
-                 write_exp_elt_type ($1.type);
-                 write_exp_elt_dblcst ($1.dval);
-                 write_exp_elt_opcode (OP_DOUBLE); }
-|      BOOLEAN_LITERAL
-               { write_exp_elt_opcode (OP_LONG);
-                 write_exp_elt_type (java_boolean_type);
-                 write_exp_elt_longcst ((LONGEST)$1);
-                 write_exp_elt_opcode (OP_LONG); }
-|      StringLiteral
-       ;
-
-/* UNUSED:
-Type:
-       PrimitiveType
-|      ReferenceType
-;
-*/
-
-PrimitiveType:
-       NumericType
-|      BOOLEAN
-               { $$ = java_boolean_type; }
-;
-
-NumericType:
-       IntegralType
-|      FloatingPointType
-;
-
-IntegralType:
-       BYTE
-               { $$ = java_byte_type; }
-|      SHORT
-               { $$ = java_short_type; }
-|      INT
-               { $$ = java_int_type; }
-|      LONG
-               { $$ = java_long_type; }
-|      CHAR
-               { $$ = java_char_type; }
-;
-
-FloatingPointType:
-       FLOAT
-               { $$ = java_float_type; }
-|      DOUBLE
-               { $$ = java_double_type; }
-;
-
-/* UNUSED:
-ReferenceType:
-       ClassOrInterfaceType
-|      ArrayType
-;
-*/
-
-ClassOrInterfaceType:
-       Name
-               { $$ = java_type_from_name ($1); }
-;
-
-ClassType:
-       ClassOrInterfaceType
-;
-
-/* UNUSED:
-ArrayType:
-       PrimitiveType Dims
-               { $$ = java_array_type ($1, $2); }
-|      Name Dims
-               { $$ = java_array_type (java_type_from_name ($1), $2); }
-;
-*/
-
-Name:
-       IDENTIFIER
-|      QualifiedName
-;
-
-ForcedName:
-       SimpleName
-|      QualifiedName
-;
-
-SimpleName:
-       IDENTIFIER
-|      NAME_OR_INT
-;
-
-QualifiedName:
-       Name '.' SimpleName
-               { $$.length = $1.length + $3.length + 1;
-                 if ($1.ptr + $1.length + 1 == $3.ptr
-                     && $1.ptr[$1.length] == '.')
-                   $$.ptr = $1.ptr;  /* Optimization. */
-                 else
-                   {
-                     $$.ptr = (char *) malloc ($$.length + 1);
-                     make_cleanup (free, $$.ptr);
-                     sprintf ($$.ptr, "%.*s.%.*s",
-                              $1.length, $1.ptr, $3.length, $3.ptr);
-               } }
-;
-
-/*
-type_exp:      type
-                       { write_exp_elt_opcode(OP_TYPE);
-                         write_exp_elt_type($1);
-                         write_exp_elt_opcode(OP_TYPE);}
-       ;
-       */
-
-/* Expressions, including the comma operator.  */
-exp1   :       Expression
-       |       exp1 ',' Expression
-                       { write_exp_elt_opcode (BINOP_COMMA); }
-       ;
-
-Primary:
-       PrimaryNoNewArray
-|      ArrayCreationExpression
-;
-
-PrimaryNoNewArray:
-       Literal
-|      THIS
-               { write_exp_elt_opcode (OP_THIS);
-                 write_exp_elt_opcode (OP_THIS); }
-|      '(' Expression ')'
-|      ClassInstanceCreationExpression
-|      FieldAccess
-|      MethodInvocation
-|      ArrayAccess
-|      lcurly ArgumentList rcurly
-               { write_exp_elt_opcode (OP_ARRAY);
-                 write_exp_elt_longcst ((LONGEST) 0);
-                 write_exp_elt_longcst ((LONGEST) $3);
-                 write_exp_elt_opcode (OP_ARRAY); }
-;
-
-lcurly:
-       '{'
-               { start_arglist (); }
-;
-
-rcurly:
-       '}'
-               { $$ = end_arglist () - 1; }
-;
-
-ClassInstanceCreationExpression:
-       NEW ClassType '(' ArgumentList_opt ')'
-               { error ("FIXME - ClassInstanceCreationExpression"); }
-;
-
-ArgumentList:
-       Expression
-               { arglist_len = 1; }
-|      ArgumentList ',' Expression
-               { arglist_len++; }
-;
-
-ArgumentList_opt:
-       /* EMPTY */
-               { arglist_len = 0; }
-| ArgumentList
-;
-
-ArrayCreationExpression:
-       NEW PrimitiveType DimExprs Dims_opt
-               { error ("FIXME - ArrayCreatiionExpression"); }
-|      NEW ClassOrInterfaceType DimExprs Dims_opt
-               { error ("FIXME - ArrayCreatiionExpression"); }
-;
-
-DimExprs:
-       DimExpr
-|      DimExprs DimExpr
-;
-
-DimExpr:
-       '[' Expression ']'
-;
-
-Dims:
-       '[' ']'
-               { $$ = 1; }
-|      Dims '[' ']'
-       { $$ = $1 + 1; }
-;
-
-Dims_opt:
-       Dims
-|      /* EMPTY */
-               { $$ = 0; }
-;
-
-FieldAccess:
-       Primary '.' SimpleName
-               { write_exp_elt_opcode (STRUCTOP_STRUCT);
-                 write_exp_string ($3);
-                 write_exp_elt_opcode (STRUCTOP_STRUCT); }
-/*|    SUPER '.' SimpleName { FIXME } */
-;
-
-MethodInvocation:
-       Name '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
-|      Primary '.' SimpleName '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
-|      SUPER '.' SimpleName '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
-;
-
-ArrayAccess:
-       Name '[' Expression ']'
-               { error ("ArrayAccess"); } /* FIXME - NASTY */
-|      PrimaryNoNewArray '[' Expression ']'
-               { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
-;
-
-PostfixExpression:
-       Primary
-|      Name
-               { push_variable ($1); }
-|      VARIABLE
-               /* Already written by write_dollar_variable. */
-|      PostIncrementExpression
-|      PostDecrementExpression
-;
-
-PostIncrementExpression:
-       PostfixExpression INCREMENT
-               { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
-;
-
-PostDecrementExpression:
-       PostfixExpression DECREMENT
-               { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
-;
-
-UnaryExpression:
-       PreIncrementExpression
-|      PreDecrementExpression
-|      '+' UnaryExpression
-|      '-' UnaryExpression
-               { write_exp_elt_opcode (UNOP_NEG); }
-|      '*' UnaryExpression 
-               { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java  */
-|      UnaryExpressionNotPlusMinus
-;
-
-PreIncrementExpression:
-       INCREMENT UnaryExpression
-               { write_exp_elt_opcode (UNOP_PREINCREMENT); }
-;
-
-PreDecrementExpression:
-       DECREMENT UnaryExpression
-               { write_exp_elt_opcode (UNOP_PREDECREMENT); }
-;
-
-UnaryExpressionNotPlusMinus:
-       PostfixExpression
-|      '~' UnaryExpression
-               { write_exp_elt_opcode (UNOP_COMPLEMENT); }
-|      '!' UnaryExpression
-               { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
-|      CastExpression
-       ;
-
-CastExpression:
-       '(' PrimitiveType Dims_opt ')' UnaryExpression
-               { write_exp_elt_opcode (UNOP_CAST);
-                 write_exp_elt_type (java_array_type ($2, $3));
-                 write_exp_elt_opcode (UNOP_CAST); }
-|      '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
-|      '(' Name Dims ')' UnaryExpressionNotPlusMinus
-               { write_exp_elt_opcode (UNOP_CAST);
-                 write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
-                 write_exp_elt_opcode (UNOP_CAST); }
-;
-
-
-MultiplicativeExpression:
-       UnaryExpression
-|      MultiplicativeExpression '*' UnaryExpression
-               { write_exp_elt_opcode (BINOP_MUL); }
-|      MultiplicativeExpression '/' UnaryExpression
-               { write_exp_elt_opcode (BINOP_DIV); }
-|      MultiplicativeExpression '%' UnaryExpression
-               { write_exp_elt_opcode (BINOP_REM); }
-;
-
-AdditiveExpression:
-       MultiplicativeExpression
-|      AdditiveExpression '+' MultiplicativeExpression
-               { write_exp_elt_opcode (BINOP_ADD); }
-|      AdditiveExpression '-' MultiplicativeExpression
-               { write_exp_elt_opcode (BINOP_SUB); }
-;
-
-ShiftExpression:
-       AdditiveExpression
-|      ShiftExpression LSH AdditiveExpression
-               { write_exp_elt_opcode (BINOP_LSH); }
-|      ShiftExpression RSH AdditiveExpression
-               { write_exp_elt_opcode (BINOP_RSH); }
-/* |   ShiftExpression >>> AdditiveExpression { FIXME } */
-;
-
-RelationalExpression:
-       ShiftExpression
-|      RelationalExpression '<' ShiftExpression
-               { write_exp_elt_opcode (BINOP_LESS); }
-|      RelationalExpression '>' ShiftExpression
-               { write_exp_elt_opcode (BINOP_GTR); }
-|      RelationalExpression LEQ ShiftExpression
-               { write_exp_elt_opcode (BINOP_LEQ); }
-|      RelationalExpression GEQ ShiftExpression
-               { write_exp_elt_opcode (BINOP_GEQ); }
-/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
-;
-
-EqualityExpression:
-       RelationalExpression
-|      EqualityExpression EQUAL RelationalExpression
-               { write_exp_elt_opcode (BINOP_EQUAL); }
-|      EqualityExpression NOTEQUAL RelationalExpression
-               { write_exp_elt_opcode (BINOP_NOTEQUAL); }
-;
-
-AndExpression:
-       EqualityExpression
-|      AndExpression '&' EqualityExpression
-               { write_exp_elt_opcode (BINOP_BITWISE_AND); }
-;
-
-ExclusiveOrExpression:
-       AndExpression
-|      ExclusiveOrExpression '^' AndExpression
-               { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
-;
-InclusiveOrExpression:
-       ExclusiveOrExpression
-|      InclusiveOrExpression '|' ExclusiveOrExpression
-               { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
-;
-
-ConditionalAndExpression:
-       InclusiveOrExpression
-|      ConditionalAndExpression ANDAND InclusiveOrExpression
-               { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
-;
-
-ConditionalOrExpression:
-       ConditionalAndExpression
-|      ConditionalOrExpression OROR ConditionalAndExpression
-               { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
-;
-
-ConditionalExpression:
-       ConditionalOrExpression
-|      ConditionalOrExpression '?' Expression ':' ConditionalExpression
-               { write_exp_elt_opcode (TERNOP_COND); }
-;
-
-AssignmentExpression:
-       ConditionalExpression
-|      Assignment
-;
-                         
-Assignment:
-       LeftHandSide '=' ConditionalExpression
-               { write_exp_elt_opcode (BINOP_ASSIGN); }
-|      LeftHandSide ASSIGN_MODIFY ConditionalExpression
-               { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
-                 write_exp_elt_opcode ($2);
-                 write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
-;
-
-LeftHandSide:
-       ForcedName
-               { push_variable ($1); }
-|      VARIABLE
-               /* Already written by write_dollar_variable. */
-|      FieldAccess
-|      ArrayAccess
-;
-
-
-Expression:
-       AssignmentExpression
-;
-
-%%
-/* Take care of parsing a number (anything that starts with a digit).
-   Set yylval and return the token type; update lexptr.
-   LEN is the number of characters in it.  */
-
-/*** Needs some error checking for the float case ***/
-
-static int
-parse_number (p, len, parsed_float, putithere)
-     register char *p;
-     register int len;
-     int parsed_float;
-     YYSTYPE *putithere;
-{
-  register ULONGEST n = 0;
-  ULONGEST limit, limit_div_base;
-
-  register int c;
-  register int base = input_radix;
-
-  struct type *type;
-
-  if (parsed_float)
-    {
-      /* It's a float since it contains a point or an exponent.  */
-      char c;
-      int num = 0;     /* number of tokens scanned by scanf */
-      char saved_char = p[len];
-
-      p[len] = 0;      /* null-terminate the token */
-      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
-       num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
-      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
-       num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
-      else
-       {
-#ifdef PRINTF_HAS_LONG_DOUBLE
-         num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
-#else
-         /* Scan it into a double, then assign it to the long double.
-            This at least wins with values representable in the range
-            of doubles. */
-         double temp;
-         num = sscanf (p, "%lg%c", &temp, &c);
-         putithere->typed_val_float.dval = temp;
-#endif
-       }
-      p[len] = saved_char;     /* restore the input stream */
-      if (num != 1)            /* check scanf found ONLY a float ... */
-       return ERROR;
-      /* See if it has `f' or `d' suffix (float or double).  */
-
-      c = tolower (p[len - 1]);
-
-      if (c == 'f' || c == 'F')
-       putithere->typed_val_float.type = builtin_type_float;
-      else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
-       putithere->typed_val_float.type = builtin_type_double;
-      else
-       return ERROR;
-
-      return FLOATING_POINT_LITERAL;
-}
-
-  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
-  if (p[0] == '0')
-    switch (p[1])
-      {
-      case 'x':
-      case 'X':
-       if (len >= 3)
-         {
-           p += 2;
-           base = 16;
-           len -= 2;
-         }
-       break;
-
-      case 't':
-      case 'T':
-      case 'd':
-      case 'D':
-       if (len >= 3)
-         {
-           p += 2;
-           base = 10;
-           len -= 2;
-         }
-       break;
-
-      default:
-       base = 8;
-       break;
-      }
-
-  c = p[len-1];
-  limit = (ULONGEST)0xffffffff;
-  if (c == 'l' || c == 'L')
-    {
-      type = java_long_type;
-      len--;
-      /* A paranoid calculation of (1<<64)-1. */
-      limit = ((limit << 16) << 16) | limit;
-    }
-  else
-    {
-      type = java_int_type;
-    }
-  limit_div_base = limit / (ULONGEST) base;
-
-  while (--len >= 0)
-    {
-      c = *p++;
-      if (c >= '0' && c <= '9')
-       c -= '0';
-      else
-       {
-         if (c >= 'A' && c <= 'Z')
-           c += 'a' - 'A';
-         if (c >= 'a' && c - 'a' + 10 < base)
-           c -= 'a' + 10;
-         else
-           return ERROR;       /* Char not a digit */
-       }
-      if (c >= base)
-       return ERROR;
-      if (n > limit_div_base
-         || (n *= base) > limit - c)
-       error ("Numeric constant too large.");
-      n += c;
-       }
-
-   putithere->typed_val_int.val = n;
-   putithere->typed_val_int.type = type;
-   return INTEGER_LITERAL;
-}
-
-struct token
-{
-  char *operator;
-  int token;
-  enum exp_opcode opcode;
-};
-
-static const struct token tokentab3[] =
-  {
-    {">>=", ASSIGN_MODIFY, BINOP_RSH},
-    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
-  };
-
-static const struct token tokentab2[] =
-  {
-    {"+=", ASSIGN_MODIFY, BINOP_ADD},
-    {"-=", ASSIGN_MODIFY, BINOP_SUB},
-    {"*=", ASSIGN_MODIFY, BINOP_MUL},
-    {"/=", ASSIGN_MODIFY, BINOP_DIV},
-    {"%=", ASSIGN_MODIFY, BINOP_REM},
-    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
-    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
-    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
-    {"++", INCREMENT, BINOP_END},
-    {"--", DECREMENT, BINOP_END},
-    {"&&", ANDAND, BINOP_END},
-    {"||", OROR, BINOP_END},
-    {"<<", LSH, BINOP_END},
-    {">>", RSH, BINOP_END},
-    {"==", EQUAL, BINOP_END},
-    {"!=", NOTEQUAL, BINOP_END},
-    {"<=", LEQ, BINOP_END},
-    {">=", GEQ, BINOP_END}
-  };
-
-/* Read one token, getting characters through lexptr.  */
-
-static int
-yylex ()
-{
-  int c;
-  int namelen;
-  unsigned int i;
-  char *tokstart;
-  char *tokptr;
-  int tempbufindex;
-  static char *tempbuf;
-  static int tempbufsize;
-  
- retry:
-
-  tokstart = lexptr;
-  /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (STREQN (tokstart, tokentab3[i].operator, 3))
-      {
-       lexptr += 3;
-       yylval.opcode = tokentab3[i].opcode;
-       return tokentab3[i].token;
-      }
-
-  /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (STREQN (tokstart, tokentab2[i].operator, 2))
-      {
-       lexptr += 2;
-       yylval.opcode = tokentab2[i].opcode;
-       return tokentab2[i].token;
-      }
-
-  switch (c = *tokstart)
-    {
-    case 0:
-      return 0;
-
-    case ' ':
-    case '\t':
-    case '\n':
-      lexptr++;
-      goto retry;
-
-    case '\'':
-      /* We either have a character constant ('0' or '\177' for example)
-        or we have a quoted symbol reference ('foo(int,int)' in C++
-        for example). */
-      lexptr++;
-      c = *lexptr++;
-      if (c == '\\')
-       c = parse_escape (&lexptr);
-      else if (c == '\'')
-       error ("Empty character constant.");
-
-      yylval.typed_val_int.val = c;
-      yylval.typed_val_int.type = builtin_type_char;
-
-      c = *lexptr++;
-      if (c != '\'')
-       {
-         namelen = skip_quoted (tokstart) - tokstart;
-         if (namelen > 2)
-           {
-             lexptr = tokstart + namelen;
-             if (lexptr[-1] != '\'')
-               error ("Unmatched single quote.");
-             namelen -= 2;
-             tokstart++;
-             goto tryname;
-           }
-         error ("Invalid character constant.");
-       }
-      return INTEGER_LITERAL;
-
-    case '(':
-      paren_depth++;
-      lexptr++;
-      return c;
-
-    case ')':
-      if (paren_depth == 0)
-       return 0;
-      paren_depth--;
-      lexptr++;
-      return c;
-
-    case ',':
-      if (comma_terminates && paren_depth == 0)
-       return 0;
-      lexptr++;
-      return c;
-
-    case '.':
-      /* Might be a floating point number.  */
-      if (lexptr[1] < '0' || lexptr[1] > '9')
-       goto symbol;            /* Nope, must be a symbol. */
-      /* FALL THRU into number case.  */
-
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      {
-       /* It's a number.  */
-       int got_dot = 0, got_e = 0, toktype;
-       register char *p = tokstart;
-       int hex = input_radix > 10;
-
-       if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
-         {
-           p += 2;
-           hex = 1;
-         }
-       else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
-         {
-           p += 2;
-           hex = 0;
-         }
-
-       for (;; ++p)
-         {
-           /* This test includes !hex because 'e' is a valid hex digit
-              and thus does not indicate a floating point number when
-              the radix is hex.  */
-           if (!hex && !got_e && (*p == 'e' || *p == 'E'))
-             got_dot = got_e = 1;
-           /* This test does not include !hex, because a '.' always indicates
-              a decimal floating point number regardless of the radix.  */
-           else if (!got_dot && *p == '.')
-             got_dot = 1;
-           else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
-                    && (*p == '-' || *p == '+'))
-             /* This is the sign of the exponent, not the end of the
-                number.  */
-             continue;
-           /* We will take any letters or digits.  parse_number will
-              complain if past the radix, or if L or U are not final.  */
-           else if ((*p < '0' || *p > '9')
-                    && ((*p < 'a' || *p > 'z')
-                                 && (*p < 'A' || *p > 'Z')))
-             break;
-         }
-       toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
-        if (toktype == ERROR)
-         {
-           char *err_copy = (char *) alloca (p - tokstart + 1);
-
-           memcpy (err_copy, tokstart, p - tokstart);
-           err_copy[p - tokstart] = 0;
-           error ("Invalid number \"%s\".", err_copy);
-         }
-       lexptr = p;
-       return toktype;
-      }
-
-    case '+':
-    case '-':
-    case '*':
-    case '/':
-    case '%':
-    case '|':
-    case '&':
-    case '^':
-    case '~':
-    case '!':
-    case '<':
-    case '>':
-    case '[':
-    case ']':
-    case '?':
-    case ':':
-    case '=':
-    case '{':
-    case '}':
-    symbol:
-      lexptr++;
-      return c;
-
-    case '"':
-
-      /* Build the gdb internal form of the input string in tempbuf,
-        translating any standard C escape forms seen.  Note that the
-        buffer is null byte terminated *only* for the convenience of
-        debugging gdb itself and printing the buffer contents when
-        the buffer contains no embedded nulls.  Gdb does not depend
-        upon the buffer being null byte terminated, it uses the length
-        string instead.  This allows gdb to handle C strings (as well
-        as strings in other languages) with embedded null bytes */
-
-      tokptr = ++tokstart;
-      tempbufindex = 0;
-
-      do {
-       /* Grow the static temp buffer if necessary, including allocating
-          the first one on demand. */
-       if (tempbufindex + 1 >= tempbufsize)
-         {
-           tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
-         }
-       switch (*tokptr)
-         {
-         case '\0':
-         case '"':
-           /* Do nothing, loop will terminate. */
-           break;
-         case '\\':
-           tokptr++;
-           c = parse_escape (&tokptr);
-           if (c == -1)
-             {
-               continue;
-             }
-           tempbuf[tempbufindex++] = c;
-           break;
-         default:
-           tempbuf[tempbufindex++] = *tokptr++;
-           break;
-         }
-      } while ((*tokptr != '"') && (*tokptr != '\0'));
-      if (*tokptr++ != '"')
-       {
-         error ("Unterminated string in expression.");
-       }
-      tempbuf[tempbufindex] = '\0';    /* See note above */
-      yylval.sval.ptr = tempbuf;
-      yylval.sval.length = tempbufindex;
-      lexptr = tokptr;
-      return (STRING_LITERAL);
-    }
-
-  if (!(c == '_' || c == '$'
-       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
-    /* We must have come across a bad character (e.g. ';').  */
-    error ("Invalid character '%c' in expression.", c);
-
-  /* It's a name.  See how long it is.  */
-  namelen = 0;
-  for (c = tokstart[namelen];
-       (c == '_' || c == '$' || (c >= '0' && c <= '9')
-       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
-    {
-       if (c == '<')
-        {
-          int i = namelen;
-          while (tokstart[++i] && tokstart[i] != '>');
-          if (tokstart[i] == '>')
-            namelen = i;
-         }
-       c = tokstart[++namelen];
-     }
-
-  /* The token "if" terminates the expression and is NOT 
-     removed from the input stream.  */
-  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
-    {
-      return 0;
-    }
-
-  lexptr += namelen;
-
-  tryname:
-
-  /* Catch specific keywords.  Should be done with a data structure.  */
-  switch (namelen)
-    {
-    case 7:
-      if (STREQN (tokstart, "boolean", 7))
-       return BOOLEAN;
-      break;
-    case 6:
-      if (STREQN (tokstart, "double", 6))      
-       return DOUBLE;
-      break;
-    case 5:
-      if (STREQN (tokstart, "short", 5))
-       return SHORT;
-      if (STREQN (tokstart, "false", 5))
-       {
-         yylval.lval = 0;
-         return BOOLEAN_LITERAL;
-       }
-      if (STREQN (tokstart, "super", 5))
-       return SUPER;
-      if (STREQN (tokstart, "float", 5))
-       return FLOAT;
-      break;
-    case 4:
-      if (STREQN (tokstart, "long", 4))
-       return LONG;
-      if (STREQN (tokstart, "byte", 4))
-       return BYTE;
-      if (STREQN (tokstart, "char", 4))
-       return CHAR;
-      if (STREQN (tokstart, "true", 4))
-       {
-         yylval.lval = 1;
-         return BOOLEAN_LITERAL;
-       }
-      if (current_language->la_language == language_cplus
-         && STREQN (tokstart, "this", 4))
-       {
-         static const char this_name[] =
-                                { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
-
-         if (lookup_symbol (this_name, expression_context_block,
-                            VAR_NAMESPACE, (int *) NULL,
-                            (struct symtab **) NULL))
-           return THIS;
-       }
-      break;
-    case 3:
-      if (STREQN (tokstart, "int", 3))
-       return INT;
-      if (STREQN (tokstart, "new", 3))
-       return NEW;
-      break;
-    default:
-      break;
-    }
-
-  yylval.sval.ptr = tokstart;
-  yylval.sval.length = namelen;
-
-  if (*tokstart == '$')
-    {
-      write_dollar_variable (yylval.sval);
-      return VARIABLE;
-    }
-
-  /* Input names that aren't symbols but ARE valid hex numbers,
-     when the input radix permits them, can be names or numbers
-     depending on the parse.  Note we support radixes > 16 here.  */
-  if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
-       (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
-    {
-      YYSTYPE newlval; /* Its value is ignored.  */
-      int hextype = parse_number (tokstart, namelen, 0, &newlval);
-      if (hextype == INTEGER_LITERAL)
-       return NAME_OR_INT;
-    }
-  return IDENTIFIER;
-}
-
-void
-yyerror (msg)
-     char *msg;
-{
-  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
-}
-
-static struct type *
-java_type_from_name (name)
-     struct stoken name;
-{
-  char *tmp = copy_name (name);
-  struct type *typ = java_lookup_class (tmp);
-  if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
-    error ("No class named %s.", tmp);
-  return typ;
-}
-
-static void
-push_variable (name)
-     struct stoken name;
-{
-  char *tmp = copy_name (name);
-  int is_a_field_of_this = 0;
-  struct symbol *sym;
-  struct type *typ;
-  sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
-                      &is_a_field_of_this, (struct symtab **) NULL);
-  if (sym)
-    {
-      if (symbol_read_needs_frame (sym))
-       {
-         if (innermost_block == 0 ||
-             contained_in (block_found, innermost_block))
-           innermost_block = block_found;
-       }
-
-      write_exp_elt_opcode (OP_VAR_VALUE);
-      /* We want to use the selected frame, not another more inner frame
-        which happens to be in the same block.  */
-      write_exp_elt_block (NULL);
-      write_exp_elt_sym (sym);
-      write_exp_elt_opcode (OP_VAR_VALUE);
-      return;
-    }
-  if (is_a_field_of_this)
-    {
-      /* it hangs off of `this'.  Must not inadvertently convert from a
-        method call to data ref.  */
-      if (innermost_block == 0 || 
-         contained_in (block_found, innermost_block))
-       innermost_block = block_found;
-      write_exp_elt_opcode (OP_THIS);
-      write_exp_elt_opcode (OP_THIS);
-      write_exp_elt_opcode (STRUCTOP_PTR);
-      write_exp_string (name);
-      write_exp_elt_opcode (STRUCTOP_PTR);
-      return;
-    }
-
-  typ = java_lookup_class (tmp);
-  if (typ != NULL)
-    {
-      write_exp_elt_opcode(OP_TYPE);
-      write_exp_elt_type(typ);
-      write_exp_elt_opcode(OP_TYPE);
-    }
-  else
-    {
-      struct minimal_symbol *msymbol;
-
-      msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
-      if (msymbol != NULL)
-       {
-         write_exp_msymbol (msymbol,
-                            lookup_function_type (builtin_type_int),
-                            builtin_type_int);
-       }
-      else if (!have_full_symbols () && !have_partial_symbols ())
-       error ("No symbol table is loaded.  Use the \"file\" command.");
-      else
-       error ("No symbol \"%s\" in current context.", tmp);
-    }
-
-}
diff --git a/gdb/java-lang.c b/gdb/java-lang.c
deleted file mode 100644 (file)
index 66cf392..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/* Java language support routines for GDB, the GNU debugger.
-   Copyright 1997 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include "defs.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "expression.h"
-#include "parser-defs.h"
-#include "language.h"
-#include "gdbtypes.h"
-#include "symtab.h"
-#include "symfile.h"
-#include "objfiles.h"
-#include "gdb_string.h"
-#include "value.h"
-#include "c-lang.h"
-#include "java-lang.h"
-#include "gdbcore.h"
-
-struct type *java_int_type;
-struct type *java_byte_type;
-struct type *java_short_type;
-struct type *java_long_type;
-struct type *java_boolean_type;
-struct type *java_char_type;
-struct type *java_float_type;
-struct type *java_double_type;
-struct type *java_void_type;
-
-struct type *java_object_type;
-
-/* This objfile contains symtabs that have been dynamically created
-   to record dynamically loaded Java classes and dynamically
-   compiled java methods. */
-struct objfile *dynamics_objfile = NULL;
-
-struct objfile *
-get_dynamics_objfile ()
-{
-  if (dynamics_objfile == NULL)
-    {
-      dynamics_objfile = allocate_objfile (NULL, 0);
-    }
-  return dynamics_objfile;
-}
-
-#if 1
-/* symtab contains classes read from the inferior. */
-
-static struct symtab *class_symtab = NULL;
-
-/* Maximum number of class in class_symtab before relocation is needed. */
-
-static int class_symtab_space;
-
-struct symtab *
-get_java_class_symtab ()
-{
-  if (class_symtab == NULL)
-    {
-      struct objfile *objfile = get_dynamics_objfile();
-      struct blockvector *bv;
-      struct block *bl;
-      class_symtab = allocate_symtab ("<java-classes>", objfile);
-      class_symtab->language = language_java;
-      bv = (struct blockvector *)
-       obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
-      BLOCKVECTOR_NBLOCKS (bv) = 1;
-      BLOCKVECTOR (class_symtab) = bv;
-
-      /* Allocate dummy STATIC_BLOCK. */
-      bl = (struct block *)
-       obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
-      BLOCK_NSYMS (bl) = 0;
-      BLOCK_START (bl) = 0;
-      BLOCK_END (bl) = 0;
-      BLOCK_FUNCTION (bl) = NULL;
-      BLOCK_SUPERBLOCK (bl) = NULL;
-      BLOCK_GCC_COMPILED (bl) = 0;
-      BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
-
-      /* Allocate GLOBAL_BLOCK.  This has to be relocatable. */
-      class_symtab_space = 128;
-      bl = (struct block *)
-       mmalloc (objfile->md,
-                sizeof (struct block)
-                + ((class_symtab_space - 1) * sizeof (struct symbol *)));
-      *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-      BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
-      class_symtab->free_ptr = (char *) bl;
-    }
-  return class_symtab;
-}
-
-static void
-add_class_symtab_symbol (sym)
-     struct symbol *sym;
-{
-  struct symtab *symtab = get_java_class_symtab ();
-  struct blockvector *bv = BLOCKVECTOR (symtab);
-  struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-  if (BLOCK_NSYMS (bl) >= class_symtab_space)
-    {
-      /* Need to re-allocate. */
-      class_symtab_space *= 2;
-      bl = (struct block *)
-       mrealloc (symtab->objfile->md, bl,
-                 sizeof (struct block)
-                 + ((class_symtab_space - 1) * sizeof (struct symbol *)));
-      class_symtab->free_ptr = (char *) bl;
-      BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
-    }
-  
-  BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
-  BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
-}
-
-struct symbol *
-add_class_symbol (type, addr)
-     struct type *type;
-     CORE_ADDR addr;
-{
-  struct symbol *sym;
-  sym = (struct symbol *)
-    obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
-  memset (sym, 0, sizeof (struct symbol));
-  SYMBOL_LANGUAGE (sym) = language_java;
-  SYMBOL_NAME (sym) = TYPE_NAME (type);
-  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-  /*  SYMBOL_VALUE (sym) = valu;*/
-  SYMBOL_TYPE (sym) = type;
-  SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
-  SYMBOL_VALUE_ADDRESS (sym) = addr;
-  return sym;
-}
-#endif
-
-struct type *
-java_lookup_class (name)
-     char *name;
-{
-  struct symbol *sym;
-  sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE,
-                      (int *) 0, (struct symtab **) NULL);
-  if (sym == NULL)
-    {
-      /* FIXME - should search inferior's symbol table. */
-      return NULL;
-    }
-  return SYMBOL_TYPE (sym);
-}
-
-/* Return a nul-terminated string (allocated on OBSTACK) for
-   a name given by NAME (which has type Utf8Const*). */
-
-char *
-get_java_utf8_name (obstack, name)
-     struct obstack *obstack;
-     value_ptr name;
-{
-  char *chrs;
-  value_ptr temp = name;
-  int name_length = (int) value_as_long
-    (value_struct_elt (&temp, NULL, "length", NULL, "structure"));
-  temp = name;
-  temp = value_struct_elt (&temp, NULL, "data", NULL, "structure");
-  chrs = obstack_alloc (obstack, name_length+1);
-  chrs [name_length] = '\0';
-  read_memory_section (VALUE_ADDRESS (temp) + VALUE_OFFSET (temp),
-                      chrs, name_length, NULL);
-  return chrs;
-}
-
-value_ptr
-java_class_from_object (obj_val)
-     value_ptr obj_val;
-{
-  value_ptr dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
-  return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure");
-}
-
-/* Check if CLASS_IS_PRIMITIVE(value of clas): */
-int
-java_class_is_primitive (clas)
-     value_ptr clas;
-{
-  value_ptr dtable = value_struct_elt (&clas, NULL, "dtable", NULL, "struct");
-  CORE_ADDR i = value_as_pointer (dtable);
-  return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
-}
-
-/* Read a Kaffe Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
-
-struct type *
-type_from_class (clas)
-     value_ptr clas;
-{
-  struct type *type;
-  struct type *tsuper;
-  int ninterfaces, nfields;
-  char *name;
-  value_ptr temp;
-  struct objfile *objfile = get_dynamics_objfile();
-  value_ptr utf8_name, fields, field, method, methods;
-  char *nptr;
-  CORE_ADDR addr;
-  struct block *bl;
-  int i, j;
-  int type_is_object = 0;
-  int is_array = 0;
-  int nmethods;
-  struct fn_field *fn_fields;
-  struct fn_fieldlist *fn_fieldlists;
-  char *unqualified_name;
-
-  type = check_typedef (VALUE_TYPE (clas));
-  if (TYPE_CODE (type) == TYPE_CODE_PTR)
-    {
-      if (value_logical_not (clas))
-       return NULL;
-      clas = value_ind (clas);
-    }
-  addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
-
-  get_java_class_symtab ();
-  bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
-  for (i = BLOCK_NSYMS (bl);  --i >= 0; )
-    {
-      struct symbol *sym = BLOCK_SYM (bl, i);
-      if (SYMBOL_VALUE_ADDRESS (sym) == addr)
-       return SYMBOL_TYPE (sym);
-    }
-
-  if (java_class_is_primitive (clas))
-    {
-      value_ptr sig;
-      temp = clas;
-      sig = value_struct_elt (&temp, NULL, "msize", NULL, "structure");
-      return java_primitive_type (value_as_long (sig));
-    }
-
-  /* Get Class name. */
-  /* if clasloader non-null, prepend loader address. FIXME */
-  temp = clas;
-  utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
-  name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
-
-  type = alloc_type (objfile);
-  TYPE_CODE (type) = TYPE_CODE_STRUCT;
-  INIT_CPLUS_SPECIFIC (type);
-
-  if (name[0] == '[')
-    {
-      is_array = 1;
-      temp = clas;
-      /* Set array element type. */
-      temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
-      VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
-      TYPE_TARGET_TYPE (type) = type_from_class (temp);
-    }
-  unqualified_name = name;
-  for (nptr = name;  *nptr != 0;  nptr++)
-    {
-      if (*nptr == '/')
-       {
-         *nptr = '.';
-         unqualified_name = nptr+1;
-       }
-    }
-
-  ALLOCATE_CPLUS_STRUCT_TYPE (type);
-  TYPE_NAME (type) = name;
-
-  add_class_symtab_symbol (add_class_symbol (type, addr));
-
-  temp = clas;
-  temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
-  if (name != NULL && strcmp (name, "java.lang.Object") == 0)
-    {
-      tsuper = get_java_object_type ();
-      if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
-       tsuper = TYPE_TARGET_TYPE (tsuper);
-      type_is_object = 1;
-    }
-  else
-    tsuper = type_from_class (temp);
-
-#if 1
-  ninterfaces = 0;
-#else
-  temp = clas;
-  ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
-#endif
-  TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
-  temp = clas;
-  nfields = value_as_long (value_struct_elt (&temp, NULL, "nfields", NULL, "structure"));
-  nfields += TYPE_N_BASECLASSES (type);
-  TYPE_NFIELDS (type) = nfields;
-  TYPE_FIELDS (type) = (struct field *)
-    TYPE_ALLOC (type, sizeof (struct field) * nfields);
-
-  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
-
-  TYPE_FIELD_PRIVATE_BITS (type) =
-    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-  B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
-
-  TYPE_FIELD_PROTECTED_BITS (type) =
-    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-  B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
-
-  TYPE_FIELD_IGNORE_BITS (type) =
-    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
-  B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
-
-  TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
-    TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
-  B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
-
-  if (tsuper != NULL)
-    {
-      TYPE_BASECLASS (type, 0) = tsuper;
-      if (type_is_object)
-       SET_TYPE_FIELD_PRIVATE (type, 0);
-    }
-
-
-  temp = clas;
-  temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
-  TYPE_LENGTH (type) = JAVA_OBJECT_SIZE + value_as_long (temp);
-
-  fields = NULL;
-  for (i = TYPE_N_BASECLASSES (type);  i < nfields;  i++)
-    {
-      int accflags;
-      int boffset;
-      if (fields == NULL)
-       {
-         temp = clas;
-         fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
-         field = value_ind (fields);
-       }
-      else
-       { /* Re-use field value for next field. */
-         VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
-         VALUE_LAZY (field) = 1;
-       }
-      temp = field;
-      temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
-      TYPE_FIELD_NAME (type, i) =
-       get_java_utf8_name (&objfile->type_obstack, temp);
-      temp = field;
-      accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
-                                                 NULL, "structure"));
-      boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
-                                                 NULL, "structure"));
-      if (accflags & 0x0001) /* public access */
-       {
-         /* ??? */
-       }
-      if (accflags & 0x0002) /* private access */
-       {
-         SET_TYPE_FIELD_PRIVATE (type, i);
-       }
-      if (accflags & 0x0004) /* protected access */
-       {
-         SET_TYPE_FIELD_PROTECTED (type, i);
-       }
-      if (accflags & 0x0008)  /* ACC_STATIC */
-       {
-         TYPE_FIELD_BITPOS (type, i) = -1;
-         /* Hack for TYPE_FIELD_STATIC_PHYSNAME to prevent a crash. FIXME. */
-         type->fields[i].bitsize = (long) "???";
-       }
-      else
-       TYPE_FIELD_BITPOS (type, i) = 8 * (JAVA_OBJECT_SIZE + boffset);
-      if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */
-       {
-         TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */
-       }
-      else
-       {
-         struct type *ftype;
-         temp = field;
-         temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
-         ftype = type_from_class (temp);
-         if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
-           ftype = lookup_pointer_type (ftype);
-         TYPE_FIELD_TYPE (type, i) = ftype;
-       }
-    }
-
-  temp = clas;
-  nmethods = value_as_long (value_struct_elt (&temp, NULL, "nmethods",
-                                             NULL, "structure"));
-  TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
-  j = nmethods * sizeof (struct fn_field);
-  fn_fields = (struct fn_field*)
-    obstack_alloc (&dynamics_objfile->symbol_obstack, j);
-  memset (fn_fields, 0, j);
-  fn_fieldlists = (struct fn_fieldlist*)
-    alloca (nmethods * sizeof (struct fn_fieldlist));
-
-  methods = NULL;
-  for (i = 0;  i < nmethods;  i++)
-    {
-      char *mname;
-      int k;
-      if (methods == NULL)
-       {
-         temp = clas;
-         methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
-         method = value_ind (methods);
-       }
-      else
-       { /* Re-use method value for next method. */
-         VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
-         VALUE_LAZY (method) = 1;
-       }
-
-      /* Get method name. */
-      temp = method;
-      temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
-      mname = get_java_utf8_name (&objfile->type_obstack, temp);
-      if (strcmp (mname, "<init>") == 0)
-       mname = unqualified_name;
-
-      /* Check for an existing method with the same name.
-       * This makes building the fn_fieldslists an O(nmethods**2)
-       * operation.  That could be using hashing, but I doubt it
-       * is worth it.  Note that we do maintain the order of methods
-       * in the inferior's Method table (as long as that is grouped
-       * by method name), which I think is desirable.  --PB */
-      for (k = 0, j = TYPE_NFN_FIELDS (type);  ; )
-       {
-         if (--j < 0)
-           { /* No match - new method name. */
-             j = TYPE_NFN_FIELDS(type)++;
-             fn_fieldlists[j].name = mname;
-             fn_fieldlists[j].length = 1;
-             fn_fieldlists[j].fn_fields = &fn_fields[i];
-             k = i;
-             break;
-           }
-         if (strcmp (mname, fn_fieldlists[j].name) == 0)
-           { /* Found an existing method with the same name. */
-             int l;
-             if (mname != unqualified_name)
-               obstack_free (&objfile->type_obstack, mname);
-             mname = fn_fieldlists[j].name;
-             fn_fieldlists[j].length++;
-             k = i - k;  /* Index of new slot. */
-             /* Shift intervening fn_fields (between k and i) down. */
-             for (l = i;  l > k;  l--) fn_fields[l] = fn_fields[l-1];
-             for (l = TYPE_NFN_FIELDS (type);  --l > j; )
-               fn_fieldlists[l].fn_fields++;
-             break;
-           }
-         k += fn_fieldlists[j].length;
-       }
-      fn_fields[k].physname = "";
-      fn_fields[k].is_stub = 1;
-      fn_fields[k].type = make_function_type (java_void_type, NULL); /* FIXME*/
-      TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
-    }
-
-  j = TYPE_NFN_FIELDS(type) * sizeof (struct fn_fieldlist);
-  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist*)
-    obstack_alloc (&dynamics_objfile->symbol_obstack, j);
-  memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
-  return type;
-}
-
-struct type*
-get_java_object_type ()
-{
-  return java_object_type;
-}
-
-int
-is_object_type (type)
-     struct type *type;
-{
-  CHECK_TYPEDEF (type);
-  if (TYPE_CODE (type) == TYPE_CODE_PTR)
-    {
-      struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
-      char *name;
-      if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
-       return 0;
-      while (TYPE_N_BASECLASSES (ttype) > 0)
-       ttype = TYPE_BASECLASS (ttype, 0);
-      name = TYPE_NAME (ttype);
-      if (name != NULL && strcmp (name, "java.lang.Object") == 0)
-       return 1;
-      name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
-      if (name != NULL && strcmp (name, "dtable") == 0)
-       {
-         if (java_object_type == NULL)
-           java_object_type = type;
-         return 1;
-       }
-    }
-  return 0;
-}
-
-struct type*
-java_primitive_type (signature)
-     int signature;
-{
-  switch (signature)
-    {
-    case 'B':  return java_byte_type;
-    case 'S':  return java_short_type;
-    case 'I':  return java_int_type;
-    case 'J':  return java_long_type;
-    case 'Z':  return java_boolean_type;
-    case 'C':  return java_char_type;
-    case 'F':  return java_float_type;
-    case 'D':  return java_double_type;
-    case 'V':  return java_void_type;
-    }
-  error ("unknown signature '%c' for primitive type", (char) signature);
-}
-
-/* Return the type of TYPE followed by DIMS pairs of [ ].
-   If DIMS == 0, TYPE is returned. */
-
-struct type *
-java_array_type (type, dims)
-     struct type *type;
-     int dims;
-{
-  if (dims == 0)
-    return type;
-  error ("array types not implemented");
-}
-
-/* Create a Java string in the inferior from a (Utf8) literal. */
-
-value_ptr
-java_value_string (ptr, len)
-     char *ptr;
-     int len;
-{
-  error ("not implemented - java_value_string"); /* FIXME */
-}
-
-static value_ptr
-evaluate_subexp_java (expect_type, exp, pos, noside)
-     struct type *expect_type;
-     register struct expression *exp;
-     register int *pos;
-     enum noside noside;
-{
-  int pc = *pos;
-  int i;
-  enum exp_opcode op = exp->elts[*pos].opcode;
-  value_ptr arg1;
-  switch (op)
-    {
-    case UNOP_IND:
-      if (noside == EVAL_SKIP)
-       goto standard;
-      (*pos)++;
-      arg1 = evaluate_subexp_standard (expect_type, exp, pos, EVAL_NORMAL);
-      if (is_object_type (VALUE_TYPE (arg1)))
-       {
-         struct type *type = type_from_class (java_class_from_object (arg1));
-         arg1 = value_cast (lookup_pointer_type (type), arg1);
-       }
-      if (noside == EVAL_SKIP)
-       goto nosideret;
-      return value_ind (arg1);
-    case OP_STRING:
-      (*pos)++;
-      i = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
-      if (noside == EVAL_SKIP)
-       goto nosideret;
-      return java_value_string (&exp->elts[pc + 2].string, i);
-    default:
-      break;
-    }
-standard:
-  return evaluate_subexp_standard (expect_type, exp, pos, noside);
- nosideret:
-  return value_from_longest (builtin_type_long, (LONGEST) 1);
-}
-
-static struct type *
-java_create_fundamental_type (objfile, typeid)
-     struct objfile *objfile;
-     int typeid;
-{
-  switch (typeid)
-    {
-    case FT_VOID:           return java_void_type;
-    case FT_BOOLEAN:        return java_boolean_type;
-    case FT_CHAR:           return java_char_type;
-    case FT_FLOAT:          return java_float_type;
-    case FT_DBL_PREC_FLOAT: return java_double_type;
-    case FT_BYTE: case FT_SIGNED_CHAR:       return java_byte_type;
-    case FT_SHORT: case FT_SIGNED_SHORT:     return java_short_type;
-    case FT_INTEGER: case FT_SIGNED_INTEGER: return java_int_type;
-    case FT_LONG: case FT_SIGNED_LONG:       return java_long_type;
-    }
-  return c_create_fundamental_type (objfile, typeid);
-}
-
-/* Table mapping opcodes into strings for printing operators
-   and precedences of the operators.  */
-
-const struct op_print java_op_print_tab[] =
-  {
-    {",",  BINOP_COMMA, PREC_COMMA, 0},
-    {"=",  BINOP_ASSIGN, PREC_ASSIGN, 1},
-    {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
-    {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
-    {"|",  BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
-    {"^",  BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
-    {"&",  BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
-    {"==", BINOP_EQUAL, PREC_EQUAL, 0},
-    {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
-    {"<=", BINOP_LEQ, PREC_ORDER, 0},
-    {">=", BINOP_GEQ, PREC_ORDER, 0},
-    {">",  BINOP_GTR, PREC_ORDER, 0},
-    {"<",  BINOP_LESS, PREC_ORDER, 0},
-    {">>", BINOP_RSH, PREC_SHIFT, 0},
-    {"<<", BINOP_LSH, PREC_SHIFT, 0},
-#if 0
-    {">>>", BINOP_???, PREC_SHIFT, 0},
-#endif
-    {"+",  BINOP_ADD, PREC_ADD, 0},
-    {"-",  BINOP_SUB, PREC_ADD, 0},
-    {"*",  BINOP_MUL, PREC_MUL, 0},
-    {"/",  BINOP_DIV, PREC_MUL, 0},
-    {"%",  BINOP_REM, PREC_MUL, 0},
-    {"-",  UNOP_NEG, PREC_PREFIX, 0},
-    {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
-    {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
-    {"*",  UNOP_IND, PREC_PREFIX, 0},
-#if 0
-    {"instanceof", ???, ???, 0},
-#endif
-    {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
-    {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
-    {NULL, 0, 0, 0}
-};
-
-const struct language_defn java_language_defn = {
-  "java",                              /* Language name */
-  language_java,
-  c_builtin_types,
-  range_check_off,
-  type_check_off,
-  java_parse,
-  java_error,
-  evaluate_subexp_java,
-  c_printchar,                 /* Print a character constant */
-  c_printstr,                  /* Function to print string constant */
-  java_create_fundamental_type,        /* Create fundamental type in this language */
-  c_print_type,                        /* Print a type using appropriate syntax */
-  java_val_print,              /* Print a value using appropriate syntax */
-  java_value_print,            /* Print a top-level value */
-  {"",      "",    "",   ""},  /* Binary format info */
-  {"0%lo",   "0",   "o",  ""}, /* Octal format info */
-  {"%ld",    "",    "d",  ""}, /* Decimal format info */
-  {"0x%lx",  "0x",  "x",  ""}, /* Hex format info */
-  java_op_print_tab,           /* expression operators for printing */
-  1,                           /* c-style arrays */
-  0,                           /* String lower bound */
-  &builtin_type_char,          /* Type of string elements */ 
-  LANG_MAGIC
-};
-
-void
-_initialize_jave_language ()
-{
-
-  java_int_type    = init_type (TYPE_CODE_INT,  4, 0, "int", NULL);
-  java_short_type  = init_type (TYPE_CODE_INT,  2, 0, "short", NULL);
-  java_long_type   = init_type (TYPE_CODE_INT,  8, 0, "long", NULL);
-  java_byte_type   = init_type (TYPE_CODE_INT,  1, 0, "byte", NULL);
-  java_boolean_type= init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
-  java_char_type   = init_type (TYPE_CODE_CHAR, 2, 0, "char", NULL);
-  java_float_type  = init_type (TYPE_CODE_FLT,  4, 0, "float", NULL);
-  java_double_type = init_type (TYPE_CODE_FLT,  8, 0, "double", NULL);
-  java_void_type   = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
-
-  add_language (&java_language_defn);
-}
-
-/* Cleanup code that should be urn on every "run".
-   We need some hook to have this actually be called ... FIXME */
-
-void java_rerun_cleanup ()
-{
-  if (class_symtab != NULL)
-    {
-      free_symtab (class_symtab); /* ??? */
-      class_symtab = NULL;
-    }
-  if (dynamics_objfile != NULL)
-    {
-      free_objfile (dynamics_objfile);
-      dynamics_objfile = NULL;
-    }
-
-  java_object_type = NULL;
-}
diff --git a/gdb/java-lang.h b/gdb/java-lang.h
deleted file mode 100644 (file)
index 20f8b40..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Java language support definitions for GDB, the GNU debugger.
-   Copyright 1997 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-extern int
-java_parse PARAMS ((void));    /* Defined in java-exp.y */
-
-extern void
-java_error PARAMS ((char *));  /* Defined in java-exp.y */
-
-#define JAVA_OBJECT_SIZE (6 * 4)  /* sizeof (struct Object) FIXME ! */
-
-extern struct type *java_int_type;
-extern struct type *java_byte_type;
-extern struct type *java_short_type;
-extern struct type *java_long_type;
-extern struct type *java_boolean_type;
-extern struct type *java_char_type;
-extern struct type *java_float_type;
-extern struct type *java_double_type;
-extern struct type *java_void_type;
-
-/* This objfile contains symtabs that have been dynamically created
-   to record dynamically loaded Java classes and dynamically
-   compiled java methods. */
-extern struct objfile *dynamics_objfile;
-
-extern int
-java_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
-                       int, enum val_prettyprint));
-
-extern int
-java_value_print PARAMS ((struct value *, GDB_FILE *, int,
-                         enum val_prettyprint));
-
-extern value_ptr java_class_from_object PARAMS ((value_ptr));
-
-extern struct type *type_from_class PARAMS ((struct value*));
-
-extern struct type *java_primitive_type PARAMS ((int));
-
-extern struct type *java_array_type PARAMS ((struct type*, int));
-
-extern struct type *get_java_object_type ();
-
-extern struct type * java_lookup_class PARAMS((char *));
-
-extern int is_object_type PARAMS ((struct type*));
diff --git a/gdb/java-valprint.c b/gdb/java-valprint.c
deleted file mode 100644 (file)
index 511ac08..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Support for printing Java values for GDB, the GNU debugger.
-   Copyright 1997 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include "defs.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "expression.h"
-#include "value.h"
-#include "demangle.h"
-#include "valprint.h"
-#include "language.h"
-#include "java-lang.h"
-#include "c-lang.h"
-
-int
-java_value_print (val, stream, format, pretty)
-     value_ptr val;
-     GDB_FILE *stream;
-     int format;
-     enum val_prettyprint pretty;
-{
-  struct type *type = VALUE_TYPE (val);
-  if (TYPE_CODE (type) == TYPE_CODE_PTR)
-    {
-      fprintf_filtered (stream, "(");
-      type_print (TYPE_TARGET_TYPE (type), "", stream, -1);
-      fprintf_filtered (stream, ") ");
-    }
-  return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
-                    VALUE_ADDRESS (val) + VALUE_OFFSET (val),
-                    stream, format, 1, 0, pretty));
-}
-
-int
-java_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
-            pretty)
-     struct type *type;
-     char *valaddr;
-     CORE_ADDR address;
-     GDB_FILE *stream;
-     int format;
-     int deref_ref;
-     int recurse;
-     enum val_prettyprint pretty;
-{
-  if (is_object_type (type))
-    {
-      CORE_ADDR obj_addr = unpack_pointer (type, valaddr);
-      if (obj_addr != 0)
-       {
-         value_ptr obj_val
-           = value_at (TYPE_TARGET_TYPE (type), obj_addr, NULL);
-         type = type_from_class (java_class_from_object (obj_val));
-         type = lookup_pointer_type (type);
-       }
-    }
-  return c_val_print (type, valaddr, address, stream, format,
-                     deref_ref, recurse, pretty);
-}
diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y
new file mode 100644 (file)
index 0000000..d204993
--- /dev/null
@@ -0,0 +1,1233 @@
+/* YACC parser for Java expressions, for GDB.
+   Copyright (C) 1997.
+   Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Parse a C expression from text in a string,
+   and return the result as a  struct expression  pointer.
+   That structure contains arithmetic operations in reverse polish,
+   with constants represented by operations that are followed by special data.
+   See expression.h for the details of the format.
+   What is important here is that it can be built up sequentially
+   during the process of parsing; the lower levels of the tree always
+   come first in the result.
+
+   Note that malloc's and realloc's in this file are transformed to
+   xmalloc and xrealloc respectively by the same sed command in the
+   makefile that remaps any other malloc/realloc inserted by the parser
+   generator.  Doing this with #defines and trying to control the interaction
+   with include files (<malloc.h> and <stdlib.h> for example) just became
+   too messy, particularly when such includes can be inserted at random
+   times by the parser generator.  */
+  
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "bfd.h" /* Required by objfiles.h.  */
+#include "symfile.h" /* Required by objfiles.h.  */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+   as well as gratuitiously global symbol names, so we can have multiple
+   yacc generated parsers in gdb.  Note that these are only the variables
+   produced by yacc.  If other parser generators (bison, byacc, etc) produce
+   additional global names that conflict at link time, then those parser
+   generators need to be fixed instead of adding those names to this list. */
+
+#define        yymaxdepth java_maxdepth
+#define        yyparse java_parse
+#define        yylex   java_lex
+#define        yyerror java_error
+#define        yylval  java_lval
+#define        yychar  java_char
+#define        yydebug java_debug
+#define        yypact  java_pact       
+#define        yyr1    java_r1                 
+#define        yyr2    java_r2                 
+#define        yydef   java_def                
+#define        yychk   java_chk                
+#define        yypgo   java_pgo                
+#define        yyact   java_act                
+#define        yyexca  java_exca
+#define yyerrflag java_errflag
+#define yynerrs        java_nerrs
+#define        yyps    java_ps
+#define        yypv    java_pv
+#define        yys     java_s
+#define        yy_yys  java_yys
+#define        yystate java_state
+#define        yytmp   java_tmp
+#define        yyv     java_v
+#define        yy_yyv  java_yyv
+#define        yyval   java_val
+#define        yylloc  java_lloc
+#define yyreds java_reds               /* With YYDEBUG defined */
+#define yytoks java_toks               /* With YYDEBUG defined */
+#define yylhs  java_yylhs
+#define yylen  java_yylen
+#define yydefred java_yydefred
+#define yydgoto        java_yydgoto
+#define yysindex java_yysindex
+#define yyrindex java_yyrindex
+#define yygindex java_yygindex
+#define yytable         java_yytable
+#define yycheck         java_yycheck
+
+#ifndef YYDEBUG
+#define        YYDEBUG 0               /* Default to no yydebug support */
+#endif
+
+int
+yyparse PARAMS ((void));
+
+static int
+yylex PARAMS ((void));
+
+void
+yyerror PARAMS ((char *));
+
+static struct type * java_type_from_name PARAMS ((struct stoken));
+static void push_variable PARAMS ((struct stoken));
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+   since the result is stored in the structure being created,
+   other node types do have values.  */
+
+%union
+  {
+    LONGEST lval;
+    struct {
+      LONGEST val;
+      struct type *type;
+    } typed_val_int;
+    struct {
+      DOUBLEST dval;
+      struct type *type;
+    } typed_val_float;
+    struct symbol *sym;
+    struct type *tval;
+    struct stoken sval;
+    struct ttype tsym;
+    struct symtoken ssym;
+    struct block *bval;
+    enum exp_opcode opcode;
+    struct internalvar *ivar;
+    int *ivec;
+  }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int
+parse_number PARAMS ((char *, int, int, YYSTYPE *));
+%}
+
+%type <lval> rcurly Dims Dims_opt
+%type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
+%type <tval> IntegralType FloatingPointType NumericType PrimitiveType
+
+%token <typed_val_int> INTEGER_LITERAL
+%token <typed_val_float> FLOATING_POINT_LITERAL
+
+%token <sval> IDENTIFIER
+%token <sval> STRING_LITERAL
+%token <lval> BOOLEAN_LITERAL
+%token <tsym> TYPENAME
+%type <sval> Name SimpleName QualifiedName ForcedName
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+   but which would parse as a valid number in the current input radix.
+   E.g. "c" when input_radix==16.  Depending on the parse, it will be
+   turned into a name or into a number.  */
+
+%token <sval> NAME_OR_INT 
+
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+   legal basetypes.  */
+%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
+
+%token VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+%token THIS SUPER NEW
+
+%left ','
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OROR
+%left ANDAND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '+' '-'
+%left '*' '/' '%'
+%right INCREMENT DECREMENT
+%right '.' '[' '('
+
+\f
+%%
+
+start   :      exp1
+/*     |       type_exp FIXME */
+       ;
+
+StringLiteral:
+       STRING_LITERAL
+               {
+                 write_exp_elt_opcode (OP_STRING);
+                 write_exp_string ($1);
+                 write_exp_elt_opcode (OP_STRING);
+               }
+;
+
+Literal        :
+       INTEGER_LITERAL
+               { write_exp_elt_opcode (OP_LONG);
+                 write_exp_elt_type ($1.type);
+                 write_exp_elt_longcst ((LONGEST)($1.val));
+                 write_exp_elt_opcode (OP_LONG); }
+|      NAME_OR_INT
+               { YYSTYPE val;
+                 parse_number ($1.ptr, $1.length, 0, &val);
+                 write_exp_elt_opcode (OP_LONG);
+                 write_exp_elt_type (val.typed_val_int.type);
+                 write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+                 write_exp_elt_opcode (OP_LONG);
+               }
+|      FLOATING_POINT_LITERAL
+               { write_exp_elt_opcode (OP_DOUBLE);
+                 write_exp_elt_type ($1.type);
+                 write_exp_elt_dblcst ($1.dval);
+                 write_exp_elt_opcode (OP_DOUBLE); }
+|      BOOLEAN_LITERAL
+               { write_exp_elt_opcode (OP_LONG);
+                 write_exp_elt_type (java_boolean_type);
+                 write_exp_elt_longcst ((LONGEST)$1);
+                 write_exp_elt_opcode (OP_LONG); }
+|      StringLiteral
+       ;
+
+/* UNUSED:
+Type:
+       PrimitiveType
+|      ReferenceType
+;
+*/
+
+PrimitiveType:
+       NumericType
+|      BOOLEAN
+               { $$ = java_boolean_type; }
+;
+
+NumericType:
+       IntegralType
+|      FloatingPointType
+;
+
+IntegralType:
+       BYTE
+               { $$ = java_byte_type; }
+|      SHORT
+               { $$ = java_short_type; }
+|      INT
+               { $$ = java_int_type; }
+|      LONG
+               { $$ = java_long_type; }
+|      CHAR
+               { $$ = java_char_type; }
+;
+
+FloatingPointType:
+       FLOAT
+               { $$ = java_float_type; }
+|      DOUBLE
+               { $$ = java_double_type; }
+;
+
+/* UNUSED:
+ReferenceType:
+       ClassOrInterfaceType
+|      ArrayType
+;
+*/
+
+ClassOrInterfaceType:
+       Name
+               { $$ = java_type_from_name ($1); }
+;
+
+ClassType:
+       ClassOrInterfaceType
+;
+
+/* UNUSED:
+ArrayType:
+       PrimitiveType Dims
+               { $$ = java_array_type ($1, $2); }
+|      Name Dims
+               { $$ = java_array_type (java_type_from_name ($1), $2); }
+;
+*/
+
+Name:
+       IDENTIFIER
+|      QualifiedName
+;
+
+ForcedName:
+       SimpleName
+|      QualifiedName
+;
+
+SimpleName:
+       IDENTIFIER
+|      NAME_OR_INT
+;
+
+QualifiedName:
+       Name '.' SimpleName
+               { $$.length = $1.length + $3.length + 1;
+                 if ($1.ptr + $1.length + 1 == $3.ptr
+                     && $1.ptr[$1.length] == '.')
+                   $$.ptr = $1.ptr;  /* Optimization. */
+                 else
+                   {
+                     $$.ptr = (char *) malloc ($$.length + 1);
+                     make_cleanup (free, $$.ptr);
+                     sprintf ($$.ptr, "%.*s.%.*s",
+                              $1.length, $1.ptr, $3.length, $3.ptr);
+               } }
+;
+
+/*
+type_exp:      type
+                       { write_exp_elt_opcode(OP_TYPE);
+                         write_exp_elt_type($1);
+                         write_exp_elt_opcode(OP_TYPE);}
+       ;
+       */
+
+/* Expressions, including the comma operator.  */
+exp1   :       Expression
+       |       exp1 ',' Expression
+                       { write_exp_elt_opcode (BINOP_COMMA); }
+       ;
+
+Primary:
+       PrimaryNoNewArray
+|      ArrayCreationExpression
+;
+
+PrimaryNoNewArray:
+       Literal
+|      THIS
+               { write_exp_elt_opcode (OP_THIS);
+                 write_exp_elt_opcode (OP_THIS); }
+|      '(' Expression ')'
+|      ClassInstanceCreationExpression
+|      FieldAccess
+|      MethodInvocation
+|      ArrayAccess
+|      lcurly ArgumentList rcurly
+               { write_exp_elt_opcode (OP_ARRAY);
+                 write_exp_elt_longcst ((LONGEST) 0);
+                 write_exp_elt_longcst ((LONGEST) $3);
+                 write_exp_elt_opcode (OP_ARRAY); }
+;
+
+lcurly:
+       '{'
+               { start_arglist (); }
+;
+
+rcurly:
+       '}'
+               { $$ = end_arglist () - 1; }
+;
+
+ClassInstanceCreationExpression:
+       NEW ClassType '(' ArgumentList_opt ')'
+               { error ("FIXME - ClassInstanceCreationExpression"); }
+;
+
+ArgumentList:
+       Expression
+               { arglist_len = 1; }
+|      ArgumentList ',' Expression
+               { arglist_len++; }
+;
+
+ArgumentList_opt:
+       /* EMPTY */
+               { arglist_len = 0; }
+| ArgumentList
+;
+
+ArrayCreationExpression:
+       NEW PrimitiveType DimExprs Dims_opt
+               { error ("FIXME - ArrayCreatiionExpression"); }
+|      NEW ClassOrInterfaceType DimExprs Dims_opt
+               { error ("FIXME - ArrayCreatiionExpression"); }
+;
+
+DimExprs:
+       DimExpr
+|      DimExprs DimExpr
+;
+
+DimExpr:
+       '[' Expression ']'
+;
+
+Dims:
+       '[' ']'
+               { $$ = 1; }
+|      Dims '[' ']'
+       { $$ = $1 + 1; }
+;
+
+Dims_opt:
+       Dims
+|      /* EMPTY */
+               { $$ = 0; }
+;
+
+FieldAccess:
+       Primary '.' SimpleName
+               { write_exp_elt_opcode (STRUCTOP_STRUCT);
+                 write_exp_string ($3);
+                 write_exp_elt_opcode (STRUCTOP_STRUCT); }
+/*|    SUPER '.' SimpleName { FIXME } */
+;
+
+MethodInvocation:
+       Name '(' ArgumentList_opt ')'
+               { error ("method invocation not implemented"); }
+|      Primary '.' SimpleName '(' ArgumentList_opt ')'
+               { error ("method invocation not implemented"); }
+|      SUPER '.' SimpleName '(' ArgumentList_opt ')'
+               { error ("method invocation not implemented"); }
+;
+
+ArrayAccess:
+       Name '[' Expression ']'
+               { error ("ArrayAccess"); } /* FIXME - NASTY */
+|      PrimaryNoNewArray '[' Expression ']'
+               { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+;
+
+PostfixExpression:
+       Primary
+|      Name
+               { push_variable ($1); }
+|      VARIABLE
+               /* Already written by write_dollar_variable. */
+|      PostIncrementExpression
+|      PostDecrementExpression
+;
+
+PostIncrementExpression:
+       PostfixExpression INCREMENT
+               { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+;
+
+PostDecrementExpression:
+       PostfixExpression DECREMENT
+               { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+;
+
+UnaryExpression:
+       PreIncrementExpression
+|      PreDecrementExpression
+|      '+' UnaryExpression
+|      '-' UnaryExpression
+               { write_exp_elt_opcode (UNOP_NEG); }
+|      '*' UnaryExpression 
+               { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java  */
+|      UnaryExpressionNotPlusMinus
+;
+
+PreIncrementExpression:
+       INCREMENT UnaryExpression
+               { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+;
+
+PreDecrementExpression:
+       DECREMENT UnaryExpression
+               { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+;
+
+UnaryExpressionNotPlusMinus:
+       PostfixExpression
+|      '~' UnaryExpression
+               { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+|      '!' UnaryExpression
+               { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+|      CastExpression
+       ;
+
+CastExpression:
+       '(' PrimitiveType Dims_opt ')' UnaryExpression
+               { write_exp_elt_opcode (UNOP_CAST);
+                 write_exp_elt_type (java_array_type ($2, $3));
+                 write_exp_elt_opcode (UNOP_CAST); }
+|      '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
+|      '(' Name Dims ')' UnaryExpressionNotPlusMinus
+               { write_exp_elt_opcode (UNOP_CAST);
+                 write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
+                 write_exp_elt_opcode (UNOP_CAST); }
+;
+
+
+MultiplicativeExpression:
+       UnaryExpression
+|      MultiplicativeExpression '*' UnaryExpression
+               { write_exp_elt_opcode (BINOP_MUL); }
+|      MultiplicativeExpression '/' UnaryExpression
+               { write_exp_elt_opcode (BINOP_DIV); }
+|      MultiplicativeExpression '%' UnaryExpression
+               { write_exp_elt_opcode (BINOP_REM); }
+;
+
+AdditiveExpression:
+       MultiplicativeExpression
+|      AdditiveExpression '+' MultiplicativeExpression
+               { write_exp_elt_opcode (BINOP_ADD); }
+|      AdditiveExpression '-' MultiplicativeExpression
+               { write_exp_elt_opcode (BINOP_SUB); }
+;
+
+ShiftExpression:
+       AdditiveExpression
+|      ShiftExpression LSH AdditiveExpression
+               { write_exp_elt_opcode (BINOP_LSH); }
+|      ShiftExpression RSH AdditiveExpression
+               { write_exp_elt_opcode (BINOP_RSH); }
+/* |   ShiftExpression >>> AdditiveExpression { FIXME } */
+;
+
+RelationalExpression:
+       ShiftExpression
+|      RelationalExpression '<' ShiftExpression
+               { write_exp_elt_opcode (BINOP_LESS); }
+|      RelationalExpression '>' ShiftExpression
+               { write_exp_elt_opcode (BINOP_GTR); }
+|      RelationalExpression LEQ ShiftExpression
+               { write_exp_elt_opcode (BINOP_LEQ); }
+|      RelationalExpression GEQ ShiftExpression
+               { write_exp_elt_opcode (BINOP_GEQ); }
+/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
+;
+
+EqualityExpression:
+       RelationalExpression
+|      EqualityExpression EQUAL RelationalExpression
+               { write_exp_elt_opcode (BINOP_EQUAL); }
+|      EqualityExpression NOTEQUAL RelationalExpression
+               { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+;
+
+AndExpression:
+       EqualityExpression
+|      AndExpression '&' EqualityExpression
+               { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+;
+
+ExclusiveOrExpression:
+       AndExpression
+|      ExclusiveOrExpression '^' AndExpression
+               { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+;
+InclusiveOrExpression:
+       ExclusiveOrExpression
+|      InclusiveOrExpression '|' ExclusiveOrExpression
+               { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+;
+
+ConditionalAndExpression:
+       InclusiveOrExpression
+|      ConditionalAndExpression ANDAND InclusiveOrExpression
+               { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+;
+
+ConditionalOrExpression:
+       ConditionalAndExpression
+|      ConditionalOrExpression OROR ConditionalAndExpression
+               { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+;
+
+ConditionalExpression:
+       ConditionalOrExpression
+|      ConditionalOrExpression '?' Expression ':' ConditionalExpression
+               { write_exp_elt_opcode (TERNOP_COND); }
+;
+
+AssignmentExpression:
+       ConditionalExpression
+|      Assignment
+;
+                         
+Assignment:
+       LeftHandSide '=' ConditionalExpression
+               { write_exp_elt_opcode (BINOP_ASSIGN); }
+|      LeftHandSide ASSIGN_MODIFY ConditionalExpression
+               { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+                 write_exp_elt_opcode ($2);
+                 write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+;
+
+LeftHandSide:
+       ForcedName
+               { push_variable ($1); }
+|      VARIABLE
+               /* Already written by write_dollar_variable. */
+|      FieldAccess
+|      ArrayAccess
+;
+
+
+Expression:
+       AssignmentExpression
+;
+
+%%
+/* Take care of parsing a number (anything that starts with a digit).
+   Set yylval and return the token type; update lexptr.
+   LEN is the number of characters in it.  */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+     register char *p;
+     register int len;
+     int parsed_float;
+     YYSTYPE *putithere;
+{
+  register ULONGEST n = 0;
+  ULONGEST limit, limit_div_base;
+
+  register int c;
+  register int base = input_radix;
+
+  struct type *type;
+
+  if (parsed_float)
+    {
+      /* It's a float since it contains a point or an exponent.  */
+      char c;
+      int num = 0;     /* number of tokens scanned by scanf */
+      char saved_char = p[len];
+
+      p[len] = 0;      /* null-terminate the token */
+      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+       num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
+      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+       num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
+      else
+       {
+#ifdef PRINTF_HAS_LONG_DOUBLE
+         num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
+#else
+         /* Scan it into a double, then assign it to the long double.
+            This at least wins with values representable in the range
+            of doubles. */
+         double temp;
+         num = sscanf (p, "%lg%c", &temp, &c);
+         putithere->typed_val_float.dval = temp;
+#endif
+       }
+      p[len] = saved_char;     /* restore the input stream */
+      if (num != 1)            /* check scanf found ONLY a float ... */
+       return ERROR;
+      /* See if it has `f' or `d' suffix (float or double).  */
+
+      c = tolower (p[len - 1]);
+
+      if (c == 'f' || c == 'F')
+       putithere->typed_val_float.type = builtin_type_float;
+      else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
+       putithere->typed_val_float.type = builtin_type_double;
+      else
+       return ERROR;
+
+      return FLOATING_POINT_LITERAL;
+}
+
+  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+  if (p[0] == '0')
+    switch (p[1])
+      {
+      case 'x':
+      case 'X':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 16;
+           len -= 2;
+         }
+       break;
+
+      case 't':
+      case 'T':
+      case 'd':
+      case 'D':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 10;
+           len -= 2;
+         }
+       break;
+
+      default:
+       base = 8;
+       break;
+      }
+
+  c = p[len-1];
+  limit = (ULONGEST)0xffffffff;
+  if (c == 'l' || c == 'L')
+    {
+      type = java_long_type;
+      len--;
+      /* A paranoid calculation of (1<<64)-1. */
+      limit = ((limit << 16) << 16) | limit;
+    }
+  else
+    {
+      type = java_int_type;
+    }
+  limit_div_base = limit / (ULONGEST) base;
+
+  while (--len >= 0)
+    {
+      c = *p++;
+      if (c >= '0' && c <= '9')
+       c -= '0';
+      else
+       {
+         if (c >= 'A' && c <= 'Z')
+           c += 'a' - 'A';
+         if (c >= 'a' && c - 'a' + 10 < base)
+           c -= 'a' + 10;
+         else
+           return ERROR;       /* Char not a digit */
+       }
+      if (c >= base)
+       return ERROR;
+      if (n > limit_div_base
+         || (n *= base) > limit - c)
+       error ("Numeric constant too large.");
+      n += c;
+       }
+
+   putithere->typed_val_int.val = n;
+   putithere->typed_val_int.type = type;
+   return INTEGER_LITERAL;
+}
+
+struct token
+{
+  char *operator;
+  int token;
+  enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+  {
+    {">>=", ASSIGN_MODIFY, BINOP_RSH},
+    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+  };
+
+static const struct token tokentab2[] =
+  {
+    {"+=", ASSIGN_MODIFY, BINOP_ADD},
+    {"-=", ASSIGN_MODIFY, BINOP_SUB},
+    {"*=", ASSIGN_MODIFY, BINOP_MUL},
+    {"/=", ASSIGN_MODIFY, BINOP_DIV},
+    {"%=", ASSIGN_MODIFY, BINOP_REM},
+    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+    {"++", INCREMENT, BINOP_END},
+    {"--", DECREMENT, BINOP_END},
+    {"&&", ANDAND, BINOP_END},
+    {"||", OROR, BINOP_END},
+    {"<<", LSH, BINOP_END},
+    {">>", RSH, BINOP_END},
+    {"==", EQUAL, BINOP_END},
+    {"!=", NOTEQUAL, BINOP_END},
+    {"<=", LEQ, BINOP_END},
+    {">=", GEQ, BINOP_END}
+  };
+
+/* Read one token, getting characters through lexptr.  */
+
+static int
+yylex ()
+{
+  int c;
+  int namelen;
+  unsigned int i;
+  char *tokstart;
+  char *tokptr;
+  int tempbufindex;
+  static char *tempbuf;
+  static int tempbufsize;
+  
+ retry:
+
+  tokstart = lexptr;
+  /* See if it is a special token of length 3.  */
+  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+    if (STREQN (tokstart, tokentab3[i].operator, 3))
+      {
+       lexptr += 3;
+       yylval.opcode = tokentab3[i].opcode;
+       return tokentab3[i].token;
+      }
+
+  /* See if it is a special token of length 2.  */
+  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+    if (STREQN (tokstart, tokentab2[i].operator, 2))
+      {
+       lexptr += 2;
+       yylval.opcode = tokentab2[i].opcode;
+       return tokentab2[i].token;
+      }
+
+  switch (c = *tokstart)
+    {
+    case 0:
+      return 0;
+
+    case ' ':
+    case '\t':
+    case '\n':
+      lexptr++;
+      goto retry;
+
+    case '\'':
+      /* We either have a character constant ('0' or '\177' for example)
+        or we have a quoted symbol reference ('foo(int,int)' in C++
+        for example). */
+      lexptr++;
+      c = *lexptr++;
+      if (c == '\\')
+       c = parse_escape (&lexptr);
+      else if (c == '\'')
+       error ("Empty character constant.");
+
+      yylval.typed_val_int.val = c;
+      yylval.typed_val_int.type = builtin_type_char;
+
+      c = *lexptr++;
+      if (c != '\'')
+       {
+         namelen = skip_quoted (tokstart) - tokstart;
+         if (namelen > 2)
+           {
+             lexptr = tokstart + namelen;
+             if (lexptr[-1] != '\'')
+               error ("Unmatched single quote.");
+             namelen -= 2;
+             tokstart++;
+             goto tryname;
+           }
+         error ("Invalid character constant.");
+       }
+      return INTEGER_LITERAL;
+
+    case '(':
+      paren_depth++;
+      lexptr++;
+      return c;
+
+    case ')':
+      if (paren_depth == 0)
+       return 0;
+      paren_depth--;
+      lexptr++;
+      return c;
+
+    case ',':
+      if (comma_terminates && paren_depth == 0)
+       return 0;
+      lexptr++;
+      return c;
+
+    case '.':
+      /* Might be a floating point number.  */
+      if (lexptr[1] < '0' || lexptr[1] > '9')
+       goto symbol;            /* Nope, must be a symbol. */
+      /* FALL THRU into number case.  */
+
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      {
+       /* It's a number.  */
+       int got_dot = 0, got_e = 0, toktype;
+       register char *p = tokstart;
+       int hex = input_radix > 10;
+
+       if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+         {
+           p += 2;
+           hex = 1;
+         }
+       else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+         {
+           p += 2;
+           hex = 0;
+         }
+
+       for (;; ++p)
+         {
+           /* This test includes !hex because 'e' is a valid hex digit
+              and thus does not indicate a floating point number when
+              the radix is hex.  */
+           if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+             got_dot = got_e = 1;
+           /* This test does not include !hex, because a '.' always indicates
+              a decimal floating point number regardless of the radix.  */
+           else if (!got_dot && *p == '.')
+             got_dot = 1;
+           else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+                    && (*p == '-' || *p == '+'))
+             /* This is the sign of the exponent, not the end of the
+                number.  */
+             continue;
+           /* We will take any letters or digits.  parse_number will
+              complain if past the radix, or if L or U are not final.  */
+           else if ((*p < '0' || *p > '9')
+                    && ((*p < 'a' || *p > 'z')
+                                 && (*p < 'A' || *p > 'Z')))
+             break;
+         }
+       toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+        if (toktype == ERROR)
+         {
+           char *err_copy = (char *) alloca (p - tokstart + 1);
+
+           memcpy (err_copy, tokstart, p - tokstart);
+           err_copy[p - tokstart] = 0;
+           error ("Invalid number \"%s\".", err_copy);
+         }
+       lexptr = p;
+       return toktype;
+      }
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '%':
+    case '|':
+    case '&':
+    case '^':
+    case '~':
+    case '!':
+    case '<':
+    case '>':
+    case '[':
+    case ']':
+    case '?':
+    case ':':
+    case '=':
+    case '{':
+    case '}':
+    symbol:
+      lexptr++;
+      return c;
+
+    case '"':
+
+      /* Build the gdb internal form of the input string in tempbuf,
+        translating any standard C escape forms seen.  Note that the
+        buffer is null byte terminated *only* for the convenience of
+        debugging gdb itself and printing the buffer contents when
+        the buffer contains no embedded nulls.  Gdb does not depend
+        upon the buffer being null byte terminated, it uses the length
+        string instead.  This allows gdb to handle C strings (as well
+        as strings in other languages) with embedded null bytes */
+
+      tokptr = ++tokstart;
+      tempbufindex = 0;
+
+      do {
+       /* Grow the static temp buffer if necessary, including allocating
+          the first one on demand. */
+       if (tempbufindex + 1 >= tempbufsize)
+         {
+           tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+         }
+       switch (*tokptr)
+         {
+         case '\0':
+         case '"':
+           /* Do nothing, loop will terminate. */
+           break;
+         case '\\':
+           tokptr++;
+           c = parse_escape (&tokptr);
+           if (c == -1)
+             {
+               continue;
+             }
+           tempbuf[tempbufindex++] = c;
+           break;
+         default:
+           tempbuf[tempbufindex++] = *tokptr++;
+           break;
+         }
+      } while ((*tokptr != '"') && (*tokptr != '\0'));
+      if (*tokptr++ != '"')
+       {
+         error ("Unterminated string in expression.");
+       }
+      tempbuf[tempbufindex] = '\0';    /* See note above */
+      yylval.sval.ptr = tempbuf;
+      yylval.sval.length = tempbufindex;
+      lexptr = tokptr;
+      return (STRING_LITERAL);
+    }
+
+  if (!(c == '_' || c == '$'
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+    /* We must have come across a bad character (e.g. ';').  */
+    error ("Invalid character '%c' in expression.", c);
+
+  /* It's a name.  See how long it is.  */
+  namelen = 0;
+  for (c = tokstart[namelen];
+       (c == '_' || c == '$' || (c >= '0' && c <= '9')
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
+    {
+       if (c == '<')
+        {
+          int i = namelen;
+          while (tokstart[++i] && tokstart[i] != '>');
+          if (tokstart[i] == '>')
+            namelen = i;
+         }
+       c = tokstart[++namelen];
+     }
+
+  /* The token "if" terminates the expression and is NOT 
+     removed from the input stream.  */
+  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+    {
+      return 0;
+    }
+
+  lexptr += namelen;
+
+  tryname:
+
+  /* Catch specific keywords.  Should be done with a data structure.  */
+  switch (namelen)
+    {
+    case 7:
+      if (STREQN (tokstart, "boolean", 7))
+       return BOOLEAN;
+      break;
+    case 6:
+      if (STREQN (tokstart, "double", 6))      
+       return DOUBLE;
+      break;
+    case 5:
+      if (STREQN (tokstart, "short", 5))
+       return SHORT;
+      if (STREQN (tokstart, "false", 5))
+       {
+         yylval.lval = 0;
+         return BOOLEAN_LITERAL;
+       }
+      if (STREQN (tokstart, "super", 5))
+       return SUPER;
+      if (STREQN (tokstart, "float", 5))
+       return FLOAT;
+      break;
+    case 4:
+      if (STREQN (tokstart, "long", 4))
+       return LONG;
+      if (STREQN (tokstart, "byte", 4))
+       return BYTE;
+      if (STREQN (tokstart, "char", 4))
+       return CHAR;
+      if (STREQN (tokstart, "true", 4))
+       {
+         yylval.lval = 1;
+         return BOOLEAN_LITERAL;
+       }
+      if (current_language->la_language == language_cplus
+         && STREQN (tokstart, "this", 4))
+       {
+         static const char this_name[] =
+                                { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+         if (lookup_symbol (this_name, expression_context_block,
+                            VAR_NAMESPACE, (int *) NULL,
+                            (struct symtab **) NULL))
+           return THIS;
+       }
+      break;
+    case 3:
+      if (STREQN (tokstart, "int", 3))
+       return INT;
+      if (STREQN (tokstart, "new", 3))
+       return NEW;
+      break;
+    default:
+      break;
+    }
+
+  yylval.sval.ptr = tokstart;
+  yylval.sval.length = namelen;
+
+  if (*tokstart == '$')
+    {
+      write_dollar_variable (yylval.sval);
+      return VARIABLE;
+    }
+
+  /* Input names that aren't symbols but ARE valid hex numbers,
+     when the input radix permits them, can be names or numbers
+     depending on the parse.  Note we support radixes > 16 here.  */
+  if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+       (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+    {
+      YYSTYPE newlval; /* Its value is ignored.  */
+      int hextype = parse_number (tokstart, namelen, 0, &newlval);
+      if (hextype == INTEGER_LITERAL)
+       return NAME_OR_INT;
+    }
+  return IDENTIFIER;
+}
+
+void
+yyerror (msg)
+     char *msg;
+{
+  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+static struct type *
+java_type_from_name (name)
+     struct stoken name;
+{
+  char *tmp = copy_name (name);
+  struct type *typ = java_lookup_class (tmp);
+  if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
+    error ("No class named %s.", tmp);
+  return typ;
+}
+
+static void
+push_variable (name)
+     struct stoken name;
+{
+  char *tmp = copy_name (name);
+  int is_a_field_of_this = 0;
+  struct symbol *sym;
+  struct type *typ;
+  sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
+                      &is_a_field_of_this, (struct symtab **) NULL);
+  if (sym)
+    {
+      if (symbol_read_needs_frame (sym))
+       {
+         if (innermost_block == 0 ||
+             contained_in (block_found, innermost_block))
+           innermost_block = block_found;
+       }
+
+      write_exp_elt_opcode (OP_VAR_VALUE);
+      /* We want to use the selected frame, not another more inner frame
+        which happens to be in the same block.  */
+      write_exp_elt_block (NULL);
+      write_exp_elt_sym (sym);
+      write_exp_elt_opcode (OP_VAR_VALUE);
+      return;
+    }
+  if (is_a_field_of_this)
+    {
+      /* it hangs off of `this'.  Must not inadvertently convert from a
+        method call to data ref.  */
+      if (innermost_block == 0 || 
+         contained_in (block_found, innermost_block))
+       innermost_block = block_found;
+      write_exp_elt_opcode (OP_THIS);
+      write_exp_elt_opcode (OP_THIS);
+      write_exp_elt_opcode (STRUCTOP_PTR);
+      write_exp_string (name);
+      write_exp_elt_opcode (STRUCTOP_PTR);
+      return;
+    }
+
+  typ = java_lookup_class (tmp);
+  if (typ != NULL)
+    {
+      write_exp_elt_opcode(OP_TYPE);
+      write_exp_elt_type(typ);
+      write_exp_elt_opcode(OP_TYPE);
+    }
+  else
+    {
+      struct minimal_symbol *msymbol;
+
+      msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
+      if (msymbol != NULL)
+       {
+         write_exp_msymbol (msymbol,
+                            lookup_function_type (builtin_type_int),
+                            builtin_type_int);
+       }
+      else if (!have_full_symbols () && !have_partial_symbols ())
+       error ("No symbol table is loaded.  Use the \"file\" command.");
+      else
+       error ("No symbol \"%s\" in current context.", tmp);
+    }
+
+}
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
new file mode 100644 (file)
index 0000000..2e722f8
--- /dev/null
@@ -0,0 +1,763 @@
+/* Java language support routines for GDB, the GNU debugger.
+   Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "gdbtypes.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "c-lang.h"
+#include "jv-lang.h"
+#include "gdbcore.h"
+
+struct type *java_int_type;
+struct type *java_byte_type;
+struct type *java_short_type;
+struct type *java_long_type;
+struct type *java_boolean_type;
+struct type *java_char_type;
+struct type *java_float_type;
+struct type *java_double_type;
+struct type *java_void_type;
+
+struct type *java_object_type;
+
+/* This objfile contains symtabs that have been dynamically created
+   to record dynamically loaded Java classes and dynamically
+   compiled java methods. */
+struct objfile *dynamics_objfile = NULL;
+
+struct type *java_link_class_type PARAMS((struct type*, value_ptr));
+
+struct objfile *
+get_dynamics_objfile ()
+{
+  if (dynamics_objfile == NULL)
+    {
+      dynamics_objfile = allocate_objfile (NULL, 0);
+    }
+  return dynamics_objfile;
+}
+
+#if 1
+/* symtab contains classes read from the inferior. */
+
+static struct symtab *class_symtab = NULL;
+
+/* Maximum number of class in class_symtab before relocation is needed. */
+
+static int class_symtab_space;
+
+struct symtab *
+get_java_class_symtab ()
+{
+  if (class_symtab == NULL)
+    {
+      struct objfile *objfile = get_dynamics_objfile();
+      struct blockvector *bv;
+      struct block *bl;
+      class_symtab = allocate_symtab ("<java-classes>", objfile);
+      class_symtab->language = language_java;
+      bv = (struct blockvector *)
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
+      BLOCKVECTOR_NBLOCKS (bv) = 1;
+      BLOCKVECTOR (class_symtab) = bv;
+
+      /* Allocate dummy STATIC_BLOCK. */
+      bl = (struct block *)
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+      BLOCK_NSYMS (bl) = 0;
+      BLOCK_START (bl) = 0;
+      BLOCK_END (bl) = 0;
+      BLOCK_FUNCTION (bl) = NULL;
+      BLOCK_SUPERBLOCK (bl) = NULL;
+      BLOCK_GCC_COMPILED (bl) = 0;
+      BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
+
+      /* Allocate GLOBAL_BLOCK.  This has to be relocatable. */
+      class_symtab_space = 128;
+      bl = (struct block *)
+       mmalloc (objfile->md,
+                sizeof (struct block)
+                + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+      *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+      BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+      class_symtab->free_ptr = (char *) bl;
+    }
+  return class_symtab;
+}
+
+static void
+add_class_symtab_symbol (sym)
+     struct symbol *sym;
+{
+  struct symtab *symtab = get_java_class_symtab ();
+  struct blockvector *bv = BLOCKVECTOR (symtab);
+  struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+  if (BLOCK_NSYMS (bl) >= class_symtab_space)
+    {
+      /* Need to re-allocate. */
+      class_symtab_space *= 2;
+      bl = (struct block *)
+       mrealloc (symtab->objfile->md, bl,
+                 sizeof (struct block)
+                 + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+      class_symtab->free_ptr = (char *) bl;
+      BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+    }
+  
+  BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
+  BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
+}
+
+struct symbol *
+add_class_symbol (type, addr)
+     struct type *type;
+     CORE_ADDR addr;
+{
+  struct symbol *sym;
+  sym = (struct symbol *)
+    obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
+  memset (sym, 0, sizeof (struct symbol));
+  SYMBOL_LANGUAGE (sym) = language_java;
+  SYMBOL_NAME (sym) = TYPE_NAME (type);
+  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+  /*  SYMBOL_VALUE (sym) = valu;*/
+  SYMBOL_TYPE (sym) = type;
+  SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+  SYMBOL_VALUE_ADDRESS (sym) = addr;
+  return sym;
+}
+#endif
+
+struct type *
+java_lookup_class (name)
+     char *name;
+{
+  struct symbol *sym;
+  sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE,
+                      (int *) 0, (struct symtab **) NULL);
+  if (sym != NULL)
+    return SYMBOL_TYPE (sym);
+#if 0
+  CORE_ADDR addr;
+  if (called from parser)
+    {
+      call lookup_class (or similar) in inferior;
+      if not found:
+       return NULL;
+      addr = found in inferior;
+    }
+  else
+    addr = 0;
+  struct type *type;
+  type = alloc_type (objfile);
+  TYPE_CODE (type) = TYPE_CODE_STRUCT;
+  INIT_CPLUS_SPECIFIC (type);
+  TYPE_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
+  TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+  TYPE ? = addr;
+  return type;
+#else
+  /* FIXME - should search inferior's symbol table. */
+  return NULL;
+#endif
+}
+
+/* Return a nul-terminated string (allocated on OBSTACK) for
+   a name given by NAME (which has type Utf8Const*). */
+
+char *
+get_java_utf8_name (obstack, name)
+     struct obstack *obstack;
+     value_ptr name;
+{
+  char *chrs;
+  value_ptr temp = name;
+  int name_length = (int) value_as_long
+    (value_struct_elt (&temp, NULL, "length", NULL, "structure"));
+  temp = name;
+  temp = value_struct_elt (&temp, NULL, "data", NULL, "structure");
+  chrs = obstack_alloc (obstack, name_length+1);
+  chrs [name_length] = '\0';
+  read_memory_section (VALUE_ADDRESS (temp) + VALUE_OFFSET (temp),
+                      chrs, name_length, NULL);
+  return chrs;
+}
+
+value_ptr
+java_class_from_object (obj_val)
+     value_ptr obj_val;
+{
+  value_ptr dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
+  return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure");
+}
+
+/* Check if CLASS_IS_PRIMITIVE(value of clas): */
+int
+java_class_is_primitive (clas)
+     value_ptr clas;
+{
+  value_ptr dtable = value_struct_elt (&clas, NULL, "dtable", NULL, "struct");
+  CORE_ADDR i = value_as_pointer (dtable);
+  return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
+}
+
+/* Read a Kaffe Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
+
+struct type *
+type_from_class (clas)
+     value_ptr clas;
+{
+  struct type *type;
+  char *name;
+  value_ptr temp;
+  struct objfile *objfile = get_dynamics_objfile();
+  value_ptr utf8_name;
+  char *nptr;
+  CORE_ADDR addr;
+  struct block *bl;
+  int i;
+  int is_array = 0;
+
+  type = check_typedef (VALUE_TYPE (clas));
+  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    {
+      if (value_logical_not (clas))
+       return NULL;
+      clas = value_ind (clas);
+    }
+  addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
+
+  get_java_class_symtab ();
+  bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
+  for (i = BLOCK_NSYMS (bl);  --i >= 0; )
+    {
+      struct symbol *sym = BLOCK_SYM (bl, i);
+      if (SYMBOL_VALUE_ADDRESS (sym) == addr)
+       return SYMBOL_TYPE (sym);
+    }
+
+  if (java_class_is_primitive (clas))
+    {
+      value_ptr sig;
+      temp = clas;
+      sig = value_struct_elt (&temp, NULL, "msize", NULL, "structure");
+      return java_primitive_type (value_as_long (sig));
+    }
+
+  /* Get Class name. */
+  /* if clasloader non-null, prepend loader address. FIXME */
+  temp = clas;
+  utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+  name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
+
+  type = alloc_type (objfile);
+  TYPE_CODE (type) = TYPE_CODE_STRUCT;
+  INIT_CPLUS_SPECIFIC (type);
+
+  if (name[0] == '[')
+    {
+      is_array = 1;
+      temp = clas;
+      /* Set array element type. */
+      temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+      VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
+      TYPE_TARGET_TYPE (type) = type_from_class (temp);
+    }
+  for (nptr = name;  *nptr != 0;  nptr++)
+    {
+      if (*nptr == '/')
+       *nptr = '.';
+    }
+
+  ALLOCATE_CPLUS_STRUCT_TYPE (type);
+  TYPE_NAME (type) = name;
+
+  add_class_symtab_symbol (add_class_symbol (type, addr));
+  return java_link_class_type (type, clas);
+}
+
+/* Fill in class TYPE with data from the CLAS value. */ 
+
+struct type *
+java_link_class_type (type, clas)
+     struct type *type;
+     value_ptr clas;
+{
+  value_ptr temp;
+  char *unqualified_name;
+  char *name = TYPE_NAME (type);
+  int ninterfaces, nfields, nmethods;
+  int type_is_object = 0;
+  struct fn_field *fn_fields;
+  struct fn_fieldlist *fn_fieldlists;
+  value_ptr fields, field, method, methods;
+  int i, j;
+  struct objfile *objfile = get_dynamics_objfile();
+  struct type *tsuper;
+
+  unqualified_name = strrchr (name, '.');
+  if (unqualified_name == NULL)
+    unqualified_name = name;
+
+  temp = clas;
+  temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
+  if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+    {
+      tsuper = get_java_object_type ();
+      if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
+       tsuper = TYPE_TARGET_TYPE (tsuper);
+      type_is_object = 1;
+    }
+  else
+    tsuper = type_from_class (temp);
+
+#if 1
+  ninterfaces = 0;
+#else
+  temp = clas;
+  ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
+#endif
+  TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
+  temp = clas;
+  nfields = value_as_long (value_struct_elt (&temp, NULL, "nfields", NULL, "structure"));
+  nfields += TYPE_N_BASECLASSES (type);
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, sizeof (struct field) * nfields);
+
+  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+  TYPE_FIELD_PRIVATE_BITS (type) =
+    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+  B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+  TYPE_FIELD_PROTECTED_BITS (type) =
+    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+  B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+  TYPE_FIELD_IGNORE_BITS (type) =
+    (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+  B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+  TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
+    TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
+  B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+  if (tsuper != NULL)
+    {
+      TYPE_BASECLASS (type, 0) = tsuper;
+      if (type_is_object)
+       SET_TYPE_FIELD_PRIVATE (type, 0);
+    }
+
+
+  temp = clas;
+  temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
+  TYPE_LENGTH (type) = JAVA_OBJECT_SIZE + value_as_long (temp);
+
+  fields = NULL;
+  for (i = TYPE_N_BASECLASSES (type);  i < nfields;  i++)
+    {
+      int accflags;
+      int boffset;
+      if (fields == NULL)
+       {
+         temp = clas;
+         fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
+         field = value_ind (fields);
+       }
+      else
+       { /* Re-use field value for next field. */
+         VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
+         VALUE_LAZY (field) = 1;
+       }
+      temp = field;
+      temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+      TYPE_FIELD_NAME (type, i) =
+       get_java_utf8_name (&objfile->type_obstack, temp);
+      temp = field;
+      accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
+                                                 NULL, "structure"));
+      boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
+                                                 NULL, "structure"));
+      if (accflags & 0x0001) /* public access */
+       {
+         /* ??? */
+       }
+      if (accflags & 0x0002) /* private access */
+       {
+         SET_TYPE_FIELD_PRIVATE (type, i);
+       }
+      if (accflags & 0x0004) /* protected access */
+       {
+         SET_TYPE_FIELD_PROTECTED (type, i);
+       }
+      if (accflags & 0x0008)  /* ACC_STATIC */
+       {
+         TYPE_FIELD_BITPOS (type, i) = -1;
+         /* Hack for TYPE_FIELD_STATIC_PHYSNAME to prevent a crash. FIXME. */
+         type->fields[i].bitsize = (long) "???";
+       }
+      else
+       TYPE_FIELD_BITPOS (type, i) = 8 * (JAVA_OBJECT_SIZE + boffset);
+      if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */
+       {
+         TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */
+       }
+      else
+       {
+         struct type *ftype;
+         temp = field;
+         temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
+         ftype = type_from_class (temp);
+         if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
+           ftype = lookup_pointer_type (ftype);
+         TYPE_FIELD_TYPE (type, i) = ftype;
+       }
+    }
+
+  temp = clas;
+  nmethods = value_as_long (value_struct_elt (&temp, NULL, "nmethods",
+                                             NULL, "structure"));
+  TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
+  j = nmethods * sizeof (struct fn_field);
+  fn_fields = (struct fn_field*)
+    obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+  memset (fn_fields, 0, j);
+  fn_fieldlists = (struct fn_fieldlist*)
+    alloca (nmethods * sizeof (struct fn_fieldlist));
+
+  methods = NULL;
+  for (i = 0;  i < nmethods;  i++)
+    {
+      char *mname;
+      int k;
+      if (methods == NULL)
+       {
+         temp = clas;
+         methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+         method = value_ind (methods);
+       }
+      else
+       { /* Re-use method value for next method. */
+         VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
+         VALUE_LAZY (method) = 1;
+       }
+
+      /* Get method name. */
+      temp = method;
+      temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+      mname = get_java_utf8_name (&objfile->type_obstack, temp);
+      if (strcmp (mname, "<init>") == 0)
+       mname = unqualified_name;
+
+      /* Check for an existing method with the same name.
+       * This makes building the fn_fieldslists an O(nmethods**2)
+       * operation.  That could be using hashing, but I doubt it
+       * is worth it.  Note that we do maintain the order of methods
+       * in the inferior's Method table (as long as that is grouped
+       * by method name), which I think is desirable.  --PB */
+      for (k = 0, j = TYPE_NFN_FIELDS (type);  ; )
+       {
+         if (--j < 0)
+           { /* No match - new method name. */
+             j = TYPE_NFN_FIELDS(type)++;
+             fn_fieldlists[j].name = mname;
+             fn_fieldlists[j].length = 1;
+             fn_fieldlists[j].fn_fields = &fn_fields[i];
+             k = i;
+             break;
+           }
+         if (strcmp (mname, fn_fieldlists[j].name) == 0)
+           { /* Found an existing method with the same name. */
+             int l;
+             if (mname != unqualified_name)
+               obstack_free (&objfile->type_obstack, mname);
+             mname = fn_fieldlists[j].name;
+             fn_fieldlists[j].length++;
+             k = i - k;  /* Index of new slot. */
+             /* Shift intervening fn_fields (between k and i) down. */
+             for (l = i;  l > k;  l--) fn_fields[l] = fn_fields[l-1];
+             for (l = TYPE_NFN_FIELDS (type);  --l > j; )
+               fn_fieldlists[l].fn_fields++;
+             break;
+           }
+         k += fn_fieldlists[j].length;
+       }
+      fn_fields[k].physname = "";
+      fn_fields[k].is_stub = 1;
+      fn_fields[k].type = make_function_type (java_void_type, NULL); /* FIXME*/
+      TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
+    }
+
+  j = TYPE_NFN_FIELDS(type) * sizeof (struct fn_fieldlist);
+  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist*)
+    obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+  memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
+  return type;
+}
+
+struct type*
+get_java_object_type ()
+{
+  return java_object_type;
+}
+
+int
+is_object_type (type)
+     struct type *type;
+{
+  CHECK_TYPEDEF (type);
+  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    {
+      struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
+      char *name;
+      if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
+       return 0;
+      while (TYPE_N_BASECLASSES (ttype) > 0)
+       ttype = TYPE_BASECLASS (ttype, 0);
+      name = TYPE_NAME (ttype);
+      if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+       return 1;
+      name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
+      if (name != NULL && strcmp (name, "dtable") == 0)
+       {
+         if (java_object_type == NULL)
+           java_object_type = type;
+         return 1;
+       }
+    }
+  return 0;
+}
+
+struct type*
+java_primitive_type (signature)
+     int signature;
+{
+  switch (signature)
+    {
+    case 'B':  return java_byte_type;
+    case 'S':  return java_short_type;
+    case 'I':  return java_int_type;
+    case 'J':  return java_long_type;
+    case 'Z':  return java_boolean_type;
+    case 'C':  return java_char_type;
+    case 'F':  return java_float_type;
+    case 'D':  return java_double_type;
+    case 'V':  return java_void_type;
+    }
+  error ("unknown signature '%c' for primitive type", (char) signature);
+}
+
+/* Return the type of TYPE followed by DIMS pairs of [ ].
+   If DIMS == 0, TYPE is returned. */
+
+struct type *
+java_array_type (type, dims)
+     struct type *type;
+     int dims;
+{
+  if (dims == 0)
+    return type;
+  error ("array types not implemented");
+}
+
+/* Create a Java string in the inferior from a (Utf8) literal. */
+
+value_ptr
+java_value_string (ptr, len)
+     char *ptr;
+     int len;
+{
+  error ("not implemented - java_value_string"); /* FIXME */
+}
+
+static value_ptr
+evaluate_subexp_java (expect_type, exp, pos, noside)
+     struct type *expect_type;
+     register struct expression *exp;
+     register int *pos;
+     enum noside noside;
+{
+  int pc = *pos;
+  int i;
+  enum exp_opcode op = exp->elts[*pos].opcode;
+  value_ptr arg1;
+  switch (op)
+    {
+    case UNOP_IND:
+      if (noside == EVAL_SKIP)
+       goto standard;
+      (*pos)++;
+      arg1 = evaluate_subexp_standard (expect_type, exp, pos, EVAL_NORMAL);
+      if (is_object_type (VALUE_TYPE (arg1)))
+       {
+         struct type *type = type_from_class (java_class_from_object (arg1));
+         arg1 = value_cast (lookup_pointer_type (type), arg1);
+       }
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      return value_ind (arg1);
+    case OP_STRING:
+      (*pos)++;
+      i = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      return java_value_string (&exp->elts[pc + 2].string, i);
+    default:
+      break;
+    }
+standard:
+  return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ nosideret:
+  return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+static struct type *
+java_create_fundamental_type (objfile, typeid)
+     struct objfile *objfile;
+     int typeid;
+{
+  switch (typeid)
+    {
+    case FT_VOID:           return java_void_type;
+    case FT_BOOLEAN:        return java_boolean_type;
+    case FT_CHAR:           return java_char_type;
+    case FT_FLOAT:          return java_float_type;
+    case FT_DBL_PREC_FLOAT: return java_double_type;
+    case FT_BYTE: case FT_SIGNED_CHAR:       return java_byte_type;
+    case FT_SHORT: case FT_SIGNED_SHORT:     return java_short_type;
+    case FT_INTEGER: case FT_SIGNED_INTEGER: return java_int_type;
+    case FT_LONG: case FT_SIGNED_LONG:       return java_long_type;
+    }
+  return c_create_fundamental_type (objfile, typeid);
+}
+
+/* Table mapping opcodes into strings for printing operators
+   and precedences of the operators.  */
+
+const struct op_print java_op_print_tab[] =
+  {
+    {",",  BINOP_COMMA, PREC_COMMA, 0},
+    {"=",  BINOP_ASSIGN, PREC_ASSIGN, 1},
+    {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+    {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+    {"|",  BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+    {"^",  BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+    {"&",  BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+    {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+    {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+    {"<=", BINOP_LEQ, PREC_ORDER, 0},
+    {">=", BINOP_GEQ, PREC_ORDER, 0},
+    {">",  BINOP_GTR, PREC_ORDER, 0},
+    {"<",  BINOP_LESS, PREC_ORDER, 0},
+    {">>", BINOP_RSH, PREC_SHIFT, 0},
+    {"<<", BINOP_LSH, PREC_SHIFT, 0},
+#if 0
+    {">>>", BINOP_???, PREC_SHIFT, 0},
+#endif
+    {"+",  BINOP_ADD, PREC_ADD, 0},
+    {"-",  BINOP_SUB, PREC_ADD, 0},
+    {"*",  BINOP_MUL, PREC_MUL, 0},
+    {"/",  BINOP_DIV, PREC_MUL, 0},
+    {"%",  BINOP_REM, PREC_MUL, 0},
+    {"-",  UNOP_NEG, PREC_PREFIX, 0},
+    {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+    {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
+    {"*",  UNOP_IND, PREC_PREFIX, 0},
+#if 0
+    {"instanceof", ???, ???, 0},
+#endif
+    {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+    {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+    {NULL, 0, 0, 0}
+};
+
+const struct language_defn java_language_defn = {
+  "java",                              /* Language name */
+  language_java,
+  c_builtin_types,
+  range_check_off,
+  type_check_off,
+  java_parse,
+  java_error,
+  evaluate_subexp_java,
+  c_printchar,                 /* Print a character constant */
+  c_printstr,                  /* Function to print string constant */
+  java_create_fundamental_type,        /* Create fundamental type in this language */
+  java_print_type,             /* Print a type using appropriate syntax */
+  java_val_print,              /* Print a value using appropriate syntax */
+  java_value_print,            /* Print a top-level value */
+  {"",      "",    "",   ""},  /* Binary format info */
+  {"0%lo",   "0",   "o",  ""}, /* Octal format info */
+  {"%ld",    "",    "d",  ""}, /* Decimal format info */
+  {"0x%lx",  "0x",  "x",  ""}, /* Hex format info */
+  java_op_print_tab,           /* expression operators for printing */
+  1,                           /* c-style arrays */
+  0,                           /* String lower bound */
+  &builtin_type_char,          /* Type of string elements */ 
+  LANG_MAGIC
+};
+
+void
+_initialize_jave_language ()
+{
+
+  java_int_type    = init_type (TYPE_CODE_INT,  4, 0, "int", NULL);
+  java_short_type  = init_type (TYPE_CODE_INT,  2, 0, "short", NULL);
+  java_long_type   = init_type (TYPE_CODE_INT,  8, 0, "long", NULL);
+  java_byte_type   = init_type (TYPE_CODE_INT,  1, 0, "byte", NULL);
+  java_boolean_type= init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
+  java_char_type   = init_type (TYPE_CODE_CHAR, 2, 0, "char", NULL);
+  java_float_type  = init_type (TYPE_CODE_FLT,  4, 0, "float", NULL);
+  java_double_type = init_type (TYPE_CODE_FLT,  8, 0, "double", NULL);
+  java_void_type   = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
+
+  add_language (&java_language_defn);
+}
+
+/* Cleanup code that should be urn on every "run".
+   We need some hook to have this actually be called ... FIXME */
+
+void java_rerun_cleanup ()
+{
+  if (class_symtab != NULL)
+    {
+      free_symtab (class_symtab); /* ??? */
+      class_symtab = NULL;
+    }
+  if (dynamics_objfile != NULL)
+    {
+      free_objfile (dynamics_objfile);
+      dynamics_objfile = NULL;
+    }
+
+  java_object_type = NULL;
+}
diff --git a/gdb/jv-lang.h b/gdb/jv-lang.h
new file mode 100644 (file)
index 0000000..814fb4a
--- /dev/null
@@ -0,0 +1,66 @@
+/* Java language support definitions for GDB, the GNU debugger.
+   Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+extern int
+java_parse PARAMS ((void));    /* Defined in jv-exp.y */
+
+extern void
+java_error PARAMS ((char *));  /* Defined in jv-exp.y */
+
+#define JAVA_OBJECT_SIZE (6 * 4)  /* sizeof (struct Object) FIXME ! */
+
+extern struct type *java_int_type;
+extern struct type *java_byte_type;
+extern struct type *java_short_type;
+extern struct type *java_long_type;
+extern struct type *java_boolean_type;
+extern struct type *java_char_type;
+extern struct type *java_float_type;
+extern struct type *java_double_type;
+extern struct type *java_void_type;
+
+/* This objfile contains symtabs that have been dynamically created
+   to record dynamically loaded Java classes and dynamically
+   compiled java methods. */
+extern struct objfile *dynamics_objfile;
+
+extern int
+java_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
+                       int, enum val_prettyprint));
+
+extern int
+java_value_print PARAMS ((struct value *, GDB_FILE *, int,
+                         enum val_prettyprint));
+
+extern value_ptr java_class_from_object PARAMS ((value_ptr));
+
+extern struct type *type_from_class PARAMS ((struct value*));
+
+extern struct type *java_primitive_type PARAMS ((int));
+
+extern struct type *java_array_type PARAMS ((struct type*, int));
+
+extern struct type *get_java_object_type ();
+
+extern struct type * java_lookup_class PARAMS((char *));
+
+extern int is_object_type PARAMS ((struct type*));
+
+extern void                    /* Defined in jv-typeprint.c */
+java_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
diff --git a/gdb/jv-typeprint.c b/gdb/jv-typeprint.c
new file mode 100644 (file)
index 0000000..2f31214
--- /dev/null
@@ -0,0 +1,36 @@
+/* Support for printing Java types for GDB, the GNU debugger.
+   Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+
+/* LEVEL is the depth to indent lines by.  */
+
+void
+java_print_type (type, varstring, stream, show, level)
+     struct type *type;
+     char *varstring;
+     GDB_FILE *stream;
+     int show;
+     int level;
+{
+  c_print_type (type, varstring, stream, show, level);
+}
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
new file mode 100644 (file)
index 0000000..af60b17
--- /dev/null
@@ -0,0 +1,75 @@
+/* Support for printing Java values for GDB, the GNU debugger.
+   Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "c-lang.h"
+
+int
+java_value_print (val, stream, format, pretty)
+     value_ptr val;
+     GDB_FILE *stream;
+     int format;
+     enum val_prettyprint pretty;
+{
+  struct type *type = VALUE_TYPE (val);
+  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+    {
+      fprintf_filtered (stream, "(");
+      type_print (TYPE_TARGET_TYPE (type), "", stream, -1);
+      fprintf_filtered (stream, ") ");
+    }
+  return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
+                    VALUE_ADDRESS (val) + VALUE_OFFSET (val),
+                    stream, format, 1, 0, pretty));
+}
+
+int
+java_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
+            pretty)
+     struct type *type;
+     char *valaddr;
+     CORE_ADDR address;
+     GDB_FILE *stream;
+     int format;
+     int deref_ref;
+     int recurse;
+     enum val_prettyprint pretty;
+{
+  if (is_object_type (type))
+    {
+      CORE_ADDR obj_addr = unpack_pointer (type, valaddr);
+      if (obj_addr != 0)
+       {
+         value_ptr obj_val
+           = value_at (TYPE_TARGET_TYPE (type), obj_addr, NULL);
+         type = type_from_class (java_class_from_object (obj_val));
+         type = lookup_pointer_type (type);
+       }
+    }
+  return c_val_print (type, valaddr, address, stream, format,
+                     deref_ref, recurse, pretty);
+}