/* YACC parser for Java expressions, for GDB.
- Copyright 1997, 1998, 1999, 2000
+ 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.
#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
%token <opcode> ASSIGN_MODIFY
-%token THIS SUPER NEW
+%token SUPER NEW
%left ','
%right '=' ASSIGN_MODIFY
PrimaryNoNewArray:
Literal
-| THIS
- { write_exp_elt_opcode (OP_THIS);
- write_exp_elt_opcode (OP_THIS); }
| '(' Expression ')'
| ClassInstanceCreationExpression
| 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:
/*** 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;
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 SCANF_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;
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;
/* Read one token, getting characters through lexptr. */
static int
-yylex ()
+yylex (void)
{
int c;
int namelen;
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;
/* 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;
{
/* 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'))
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:
}
void
-yyerror (msg)
- char *msg;
+yyerror (char *msg)
{
if (prev_lexptr)
lexptr = prev_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);
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))
}
/* 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;
{
/* 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)
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;
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;
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"));
else
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
/* 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;