* i386-linux-tdep.c (I386_LINUX_RECORD_SIZE_*,
[deliverable/binutils-gdb.git] / gdb / jv-exp.y
index 828a557e4ffe457c47d52bbe6068540c84cc9b99..89ec3e9460771ad0400729a22b2ca70f617a9f18 100644 (file)
@@ -1,22 +1,21 @@
 /* YACC parser for Java expressions, for GDB.
-   Copyright (C) 1997.
+   Copyright (C) 1997, 1998, 1999, 2000, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
-This file is part of GDB.
+   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 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 3 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.
+   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.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Parse a Java expression from text in a string,
    and return the result as a  struct expression  pointer.
@@ -48,6 +47,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #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 */
+#include "block.h"
+
+#define parse_type builtin_type (parse_gdbarch)
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
@@ -85,6 +87,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define        yylloc  java_lloc
 #define yyreds java_reds               /* With YYDEBUG defined */
 #define yytoks java_toks               /* With YYDEBUG defined */
+#define yyname java_name               /* With YYDEBUG defined */
+#define yyrule java_rule               /* With YYDEBUG defined */
 #define yylhs  java_yylhs
 #define yylen  java_yylen
 #define yydefred java_yydefred
@@ -96,24 +100,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define yycheck         java_yycheck
 
 #ifndef YYDEBUG
-#define        YYDEBUG 0               /* Default to no yydebug support */
+#define        YYDEBUG 1               /* Default to yydebug support */
 #endif
 
-int
-yyparse PARAMS ((void));
+#define YYFPRINTF parser_fprintf
 
-static int
-yylex PARAMS ((void));
+int yyparse (void);
 
-void
-yyerror PARAMS ((char *));
+static int yylex (void);
 
-static struct type * java_type_from_name PARAMS ((struct stoken));
-static void push_expression_name PARAMS ((struct stoken));
-static void push_fieldnames PARAMS ((struct stoken));
+void yyerror (char *);
 
-static struct expression *copy_exp PARAMS ((struct expression *, int));
-static void insert_exp PARAMS ((int, struct expression *));
+static struct type *java_type_from_name (struct stoken);
+static void push_expression_name (struct stoken);
+static void push_fieldnames (struct stoken);
+
+static struct expression *copy_exp (struct expression *, int);
+static void insert_exp (int, struct expression *);
 
 %}
 
@@ -145,13 +148,12 @@ static void insert_exp PARAMS ((int, struct expression *));
 
 %{
 /* YYSTYPE gets defined by %union */
-static int
-parse_number PARAMS ((char *, int, int, YYSTYPE *));
+static int parse_number (char *, int, int, YYSTYPE *);
 %}
 
 %type <lval> rcurly Dims Dims_opt
 %type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
-%type <tval> IntegralType FloatingPointType NumericType PrimitiveType
+%type <tval> IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
 
 %token <typed_val_int> INTEGER_LITERAL
 %token <typed_val_float> FLOATING_POINT_LITERAL
@@ -179,7 +181,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
 
 %token <opcode> ASSIGN_MODIFY
 
-%token THIS SUPER NEW
+%token SUPER NEW
 
 %left ','
 %right '=' ASSIGN_MODIFY
@@ -201,7 +203,20 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
 %%
 
 start   :      exp1
-/*     |       type_exp FIXME */
+       |       type_exp
+       ;
+
+type_exp:      PrimitiveOrArrayType
+               {
+                 write_exp_elt_opcode(OP_TYPE);
+                 write_exp_elt_type($1);
+                 write_exp_elt_opcode(OP_TYPE);
+               }
+       ;
+
+PrimitiveOrArrayType:
+               PrimitiveType
+       |       ArrayType
        ;
 
 StringLiteral:
@@ -294,14 +309,12 @@ ClassType:
        ClassOrInterfaceType
 ;
 
-/* UNUSED:
 ArrayType:
        PrimitiveType Dims
                { $$ = java_array_type ($1, $2); }
 |      Name Dims
                { $$ = java_array_type (java_type_from_name ($1), $2); }
 ;
-*/
 
 Name:
        IDENTIFIER
@@ -354,9 +367,6 @@ Primary:
 
 PrimaryNoNewArray:
        Literal
-|      THIS
-               { write_exp_elt_opcode (OP_THIS);
-                 write_exp_elt_opcode (OP_THIS); }
 |      '(' Expression ')'
 |      ClassInstanceCreationExpression
 |      FieldAccess
@@ -381,7 +391,8 @@ rcurly:
 
 ClassInstanceCreationExpression:
        NEW ClassType '(' ArgumentList_opt ')'
-               { error ("FIXME - ClassInstanceCreationExpression"); }
+               { internal_error (__FILE__, __LINE__,
+                                 _("FIXME - ClassInstanceCreationExpression")); }
 ;
 
 ArgumentList:
@@ -399,9 +410,11 @@ ArgumentList_opt:
 
 ArrayCreationExpression:
        NEW PrimitiveType DimExprs Dims_opt
-               { error ("FIXME - ArrayCreatiionExpression"); }
+               { internal_error (__FILE__, __LINE__,
+                                 _("FIXME - ArrayCreationExpression")); }
 |      NEW ClassOrInterfaceType DimExprs Dims_opt
-               { error ("FIXME - ArrayCreatiionExpression"); }
+               { internal_error (__FILE__, __LINE__,
+                                 _("FIXME - ArrayCreationExpression")); }
 ;
 
 DimExprs:
@@ -434,13 +447,22 @@ FieldAccess:
 /*|    SUPER '.' SimpleName { FIXME } */
 ;
 
+FuncStart:
+       Name '('
+                { push_expression_name ($1); }
+;
+
 MethodInvocation:
-       Name '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
+       FuncStart
+                { start_arglist(); }
+       ArgumentList_opt ')'
+                { write_exp_elt_opcode (OP_FUNCALL);
+                 write_exp_elt_longcst ((LONGEST) end_arglist ());
+                 write_exp_elt_opcode (OP_FUNCALL); }
 |      Primary '.' SimpleName '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
+               { error (_("Form of method invocation not implemented")); }
 |      SUPER '.' SimpleName '(' ArgumentList_opt ')'
-               { error ("method invocation not implemented"); }
+               { error (_("Form of method invocation not implemented")); }
 ;
 
 ArrayAccess:
@@ -530,7 +552,7 @@ CastExpression:
                  int i;
                  int base = expout_ptr - last_exp_size - 3;
                  if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
-                   error ("invalid cast expression");
+                   error (_("Invalid cast expression"));
                  type = expout->elts[base+1].type;
                  /* Remove the 'Expression' and slide the
                     UnaryExpressionNotPlusMinus down to replace it. */
@@ -669,17 +691,13 @@ Expression:
 /*** 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;
+parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
 {
-  register ULONGEST n = 0;
+  ULONGEST n = 0;
   ULONGEST limit, limit_div_base;
 
-  register int c;
-  register int base = input_radix;
+  int c;
+  int base = input_radix;
 
   struct type *type;
 
@@ -691,23 +709,8 @@ parse_number (p, len, parsed_float, putithere)
       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
-       }
+      num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
+                   &putithere->typed_val_float.dval, &c);
       p[len] = saved_char;     /* restore the input stream */
       if (num != 1)            /* check scanf found ONLY a float ... */
        return ERROR;
@@ -716,14 +719,14 @@ parse_number (p, len, parsed_float, putithere)
       c = tolower (p[len - 1]);
 
       if (c == 'f' || c == 'F')
-       putithere->typed_val_float.type = builtin_type_float;
+       putithere->typed_val_float.type = parse_type->builtin_float;
       else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
-       putithere->typed_val_float.type = builtin_type_double;
+       putithere->typed_val_float.type = parse_type->builtin_double;
       else
        return ERROR;
 
       return FLOATING_POINT_LITERAL;
-}
+    }
 
   /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
   if (p[0] == '0')
@@ -757,13 +760,13 @@ parse_number (p, len, parsed_float, putithere)
       }
 
   c = p[len-1];
+  /* A paranoid calculation of (1<<64)-1. */
   limit = (ULONGEST)0xffffffff;
+  limit = ((limit << 16) << 16) | limit;
   if (c == 'l' || c == 'L')
     {
       type = java_long_type;
       len--;
-      /* A paranoid calculation of (1<<64)-1. */
-      limit = ((limit << 16) << 16) | limit;
     }
   else
     {
@@ -786,13 +789,22 @@ parse_number (p, len, parsed_float, putithere)
        return ERROR;
       if (n > limit_div_base
          || (n *= base) > limit - c)
-       error ("Numeric constant too large.");
+       error (_("Numeric constant too large"));
       n += c;
        }
 
-   putithere->typed_val_int.val = n;
-   putithere->typed_val_int.type = type;
-   return INTEGER_LITERAL;
+  /* If the type is bigger than a 32-bit signed integer can be, implicitly
+     promote to long.  Java does not do this, so mark it as builtin_type_uint64
+     rather than java_long_type.  0x80000000 will become -0x80000000 instead
+     of 0x80000000L, because we don't know the sign at this point.
+  */
+  if (type == java_int_type && n > (ULONGEST)0x80000000)
+    type = builtin_type_uint64;
+
+  putithere->typed_val_int.val = n;
+  putithere->typed_val_int.type = type;
+
+  return INTEGER_LITERAL;
 }
 
 struct token
@@ -833,7 +845,7 @@ static const struct token tokentab2[] =
 /* Read one token, getting characters through lexptr.  */
 
 static int
-yylex ()
+yylex (void)
 {
   int c;
   int namelen;
@@ -846,10 +858,12 @@ yylex ()
   
  retry:
 
+  prev_lexptr = lexptr;
+
   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))
+    if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
       {
        lexptr += 3;
        yylval.opcode = tokentab3[i].opcode;
@@ -858,7 +872,7 @@ yylex ()
 
   /* 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))
+    if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
       {
        lexptr += 2;
        yylval.opcode = tokentab2[i].opcode;
@@ -885,10 +899,10 @@ yylex ()
       if (c == '\\')
        c = parse_escape (&lexptr);
       else if (c == '\'')
-       error ("Empty character constant.");
+       error (_("Empty character constant"));
 
       yylval.typed_val_int.val = c;
-      yylval.typed_val_int.type = builtin_type_char;
+      yylval.typed_val_int.type = java_char_type;
 
       c = *lexptr++;
       if (c != '\'')
@@ -898,12 +912,12 @@ yylex ()
            {
              lexptr = tokstart + namelen;
              if (lexptr[-1] != '\'')
-               error ("Unmatched single quote.");
+               error (_("Unmatched single quote"));
              namelen -= 2;
              tokstart++;
              goto tryname;
            }
-         error ("Invalid character constant.");
+         error (_("Invalid character constant"));
        }
       return INTEGER_LITERAL;
 
@@ -944,7 +958,7 @@ yylex ()
       {
        /* It's a number.  */
        int got_dot = 0, got_e = 0, toktype;
-       register char *p = tokstart;
+       char *p = tokstart;
        int hex = input_radix > 10;
 
        if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
@@ -988,7 +1002,7 @@ yylex ()
 
            memcpy (err_copy, tokstart, p - tokstart);
            err_copy[p - tokstart] = 0;
-           error ("Invalid number \"%s\".", err_copy);
+           error (_("Invalid number \"%s\""), err_copy);
          }
        lexptr = p;
        return toktype;
@@ -1060,7 +1074,7 @@ yylex ()
       } while ((*tokptr != '"') && (*tokptr != '\0'));
       if (*tokptr++ != '"')
        {
-         error ("Unterminated string in expression.");
+         error (_("Unterminated string in expression"));
        }
       tempbuf[tempbufindex] = '\0';    /* See note above */
       yylval.sval.ptr = tempbuf;
@@ -1072,21 +1086,26 @@ yylex ()
   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);
+    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 == '<');)
+       (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;
-         }
+      if (c == '<')
+       {
+         int i = namelen;
+         while (tokstart[++i] && tokstart[i] != '>');
+         if (tokstart[i] == '>')
+           namelen = i;
+       }
        c = tokstart[++namelen];
      }
 
@@ -1105,54 +1124,43 @@ yylex ()
   switch (namelen)
     {
     case 7:
-      if (STREQN (tokstart, "boolean", 7))
+      if (strncmp (tokstart, "boolean", 7) == 0)
        return BOOLEAN;
       break;
     case 6:
-      if (STREQN (tokstart, "double", 6))      
+      if (strncmp (tokstart, "double", 6) == 0)      
        return DOUBLE;
       break;
     case 5:
-      if (STREQN (tokstart, "short", 5))
+      if (strncmp (tokstart, "short", 5) == 0)
        return SHORT;
-      if (STREQN (tokstart, "false", 5))
+      if (strncmp (tokstart, "false", 5) == 0)
        {
          yylval.lval = 0;
          return BOOLEAN_LITERAL;
        }
-      if (STREQN (tokstart, "super", 5))
+      if (strncmp (tokstart, "super", 5) == 0)
        return SUPER;
-      if (STREQN (tokstart, "float", 5))
+      if (strncmp (tokstart, "float", 5) == 0)
        return FLOAT;
       break;
     case 4:
-      if (STREQN (tokstart, "long", 4))
+      if (strncmp (tokstart, "long", 4) == 0)
        return LONG;
-      if (STREQN (tokstart, "byte", 4))
+      if (strncmp (tokstart, "byte", 4) == 0)
        return BYTE;
-      if (STREQN (tokstart, "char", 4))
+      if (strncmp (tokstart, "char", 4) == 0)
        return CHAR;
-      if (STREQN (tokstart, "true", 4))
+      if (strncmp (tokstart, "true", 4) == 0)
        {
          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))
+      if (strncmp (tokstart, "int", 3) == 0)
        return INT;
-      if (STREQN (tokstart, "new", 3))
+      if (strncmp (tokstart, "new", 3) == 0)
        return NEW;
       break;
     default:
@@ -1183,21 +1191,24 @@ yylex ()
 }
 
 void
-yyerror (msg)
-     char *msg;
+yyerror (char *msg)
 {
-  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+  if (prev_lexptr)
+    lexptr = prev_lexptr;
+
+  if (msg)
+    error (_("%s: near `%s'"), msg, lexptr);
+  else
+    error (_("error in expression, near `%s'"), lexptr);
 }
 
 static struct type *
-java_type_from_name (name)
-     struct stoken name;
+java_type_from_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);
+    error (_("No class named `%s'"), tmp);
   return typ;
 }
 
@@ -1205,15 +1216,13 @@ java_type_from_name (name)
    Otherwise, return 0. */
 
 static int
-push_variable (name)
-     struct stoken name;
+push_variable (struct stoken name)
 {
   char *tmp = copy_name (name);
   int is_a_field_of_this = 0;
   struct symbol *sym;
-  sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
-                      &is_a_field_of_this, (struct symtab **) NULL);
+  sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN,
+                      &is_a_field_of_this);
   if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
     {
       if (symbol_read_needs_frame (sym))
@@ -1249,12 +1258,11 @@ push_variable (name)
 }
 
 /* Assuming a reference expression has been pushed, emit the
-   STRUCTOP_STRUCT ops to access the field named NAME.  If NAME is a
+   STRUCTOP_PTR ops to access the field named NAME.  If NAME is a
    qualified name (has '.'), generate a field access for each part. */
 
 static void
-push_fieldnames (name)
-     struct stoken name;
+push_fieldnames (struct stoken name)
 {
   int i;
   struct stoken token;
@@ -1265,9 +1273,9 @@ push_fieldnames (name)
        {
          /* token.ptr is start of current field name. */
          token.length = &name.ptr[i] - token.ptr;
-         write_exp_elt_opcode (STRUCTOP_STRUCT);
+         write_exp_elt_opcode (STRUCTOP_PTR);
          write_exp_string (token);
-         write_exp_elt_opcode (STRUCTOP_STRUCT);
+         write_exp_elt_opcode (STRUCTOP_PTR);
          token.ptr += token.length + 1;
        }
       if (i >= name.length)
@@ -1279,9 +1287,7 @@ push_fieldnames (name)
    Handle a qualified name, where DOT_INDEX is the index of the first '.' */
 
 static void
-push_qualified_expression_name (name, dot_index)
-     struct stoken name;
-     int dot_index;
+push_qualified_expression_name (struct stoken name, int dot_index)
 {
   struct stoken token;
   char *tmp;
@@ -1340,15 +1346,14 @@ push_qualified_expression_name (name, dot_index)
       while (dot_index < name.length && name.ptr[dot_index] != '.')
        dot_index++;
     }
-  error ("unknown type `%.*s'", name.length, name.ptr);
+  error (_("unknown type `%.*s'"), name.length, name.ptr);
 }
 
 /* Handle Name in an expression (or LHS).
    Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
 
 static void
-push_expression_name (name)
-     struct stoken name;
+push_expression_name (struct stoken name)
 {
   char *tmp;
   struct type *typ;
@@ -1383,15 +1388,11 @@ push_expression_name (name)
 
       msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
       if (msymbol != NULL)
-       {
-         write_exp_msymbol (msymbol,
-                            lookup_function_type (builtin_type_int),
-                            builtin_type_int);
-       }
+       write_exp_msymbol (msymbol);
       else if (!have_full_symbols () && !have_partial_symbols ())
-       error ("No symbol table is loaded.  Use the \"file\" command.");
+       error (_("No symbol table is loaded.  Use the \"file\" command"));
       else
-       error ("No symbol \"%s\" in current context.", tmp);
+       error (_("No symbol \"%s\" in current context"), tmp);
     }
 
 }
@@ -1406,9 +1407,7 @@ push_expression_name (name)
    into a freshly malloc'ed struct expression.  Its language_defn is set
    to null.  */
 static struct expression *
-copy_exp (expr, endpos)
-     struct expression *expr;
-     int endpos;
+copy_exp (struct expression *expr, int endpos)
 {
   int len = length_of_subexp (expr, endpos);
   struct expression *new
@@ -1422,9 +1421,7 @@ copy_exp (expr, endpos)
 
 /* Insert the expression NEW into the current expression (expout) at POS.  */
 static void
-insert_exp (pos, new)
-     int pos;
-     struct expression *new;
+insert_exp (int pos, struct expression *new)
 {
   int newlen = new->nelts;
 
This page took 0.035494 seconds and 4 git commands to generate.