This file is part of GDB.
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
\f
/* Parse a C expression from text in a string,
and return the result as a struct expression pointer.
An array should be preceded in the list by the size of the array. */
enum type_pieces
{tp_end = -1, tp_pointer, tp_reference, tp_array, tp_function};
-static enum type_pieces *type_stack;
+/* The stack can contain either an enum type_pieces or an int. */
+union type_stack_elt {
+ enum type_pieces piece;
+ int int_val;
+};
+static union type_stack_elt *type_stack;
static int type_stack_depth, type_stack_size;
static void push_type ();
+static void push_type_int ();
static enum type_pieces pop_type ();
+static int pop_type_int ();
/* Allow debugging of parsing. */
#define YYDEBUG 1
write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
}
+ | typebase COLONCOLON '~' name
+ {
+ struct type *type = $1;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("`%s' is not defined as an aggregate type.",
+ TYPE_NAME (type));
+
+ if (strcmp (type_name_no_tag (type), $4.ptr))
+ error ("invalid destructor `%s::~%s'",
+ type_name_no_tag (type), $4.ptr);
+
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (type);
+ write_exp_string ($4);
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_opcode (UNOP_LOGNOT);
+ }
| COLONCOLON name
{
char *name = copy_name ($2);
{
case LOC_REGISTER:
case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
case LOC_LOCAL:
case LOC_LOCAL_ARG:
if (innermost_block == 0 ||
contained_in (block_found,
innermost_block))
innermost_block = block_found;
+ case LOC_UNDEF:
+ case LOC_CONST:
+ case LOC_STATIC:
+ case LOC_TYPEDEF:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ case LOC_CONST_BYTES:
+
+ /* In this case the expression can
+ be evaluated regardless of what
+ frame we are in, so there is no
+ need to check for the
+ innermost_block. These cases are
+ listed so that gcc -Wall will
+ report types that may not have
+ been considered. */
+
+ break;
}
write_exp_elt_opcode (OP_VAR_VALUE);
write_exp_elt_sym (sym);
follow_type = lookup_reference_type (follow_type);
break;
case tp_array:
- array_size = (int) pop_type ();
+ array_size = pop_type_int ();
if (array_size != -1)
follow_type = create_array_type (follow_type,
array_size);
{ push_type (tp_pointer); $$ = 0; }
| '*' abs_decl
{ push_type (tp_pointer); $$ = $2; }
+ | '&'
+ { push_type (tp_reference); $$ = 0; }
+ | '&' abs_decl
+ { push_type (tp_reference); $$ = $2; }
| direct_abs_decl
;
{ $$ = $2; }
| direct_abs_decl array_mod
{
- push_type ((enum type_pieces) $2);
+ push_type_int ($2);
push_type (tp_array);
}
| array_mod
{
- push_type ((enum type_pieces) $1);
+ push_type_int ($1);
push_type (tp_array);
$$ = 0;
}
{ $$ = builtin_type_long; }
| UNSIGNED LONG INT_KEYWORD
{ $$ = builtin_type_unsigned_long; }
+ | LONG LONG
+ { $$ = builtin_type_long_long; }
+ | LONG LONG INT_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | UNSIGNED LONG LONG
+ { $$ = builtin_type_unsigned_long_long; }
+ | UNSIGNED LONG LONG INT_KEYWORD
+ { $$ = builtin_type_unsigned_long_long; }
| SHORT INT_KEYWORD
{ $$ = builtin_type_short; }
| UNSIGNED SHORT INT_KEYWORD
enum exp_opcode opcode;
};
-static struct token tokentab3[] =
+const static struct token tokentab3[] =
{
{">>=", ASSIGN_MODIFY, BINOP_RSH},
{"<<=", ASSIGN_MODIFY, BINOP_LSH}
};
-static struct token tokentab2[] =
+const static struct token tokentab2[] =
{
{"+=", ASSIGN_MODIFY, BINOP_ADD},
{"-=", ASSIGN_MODIFY, BINOP_SUB},
}
}
+/* ARGSUSED */
static void
yyerror (msg)
char *msg;
if (type_stack_depth == type_stack_size)
{
type_stack_size *= 2;
- type_stack = (enum type_pieces *)
- xrealloc (type_stack, type_stack_size * sizeof (enum type_pieces));
+ type_stack = (union type_stack_elt *)
+ xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
+ }
+ type_stack[type_stack_depth++].piece = tp;
+}
+
+static void
+push_type_int (n)
+ int n;
+{
+ if (type_stack_depth == type_stack_size)
+ {
+ type_stack_size *= 2;
+ type_stack = (union type_stack_elt *)
+ xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
}
- type_stack[type_stack_depth++] = tp;
+ type_stack[type_stack_depth++].int_val = n;
}
static enum type_pieces
pop_type ()
{
if (type_stack_depth)
- return type_stack[--type_stack_depth];
+ return type_stack[--type_stack_depth].piece;
return tp_end;
}
+static int
+pop_type_int ()
+{
+ if (type_stack_depth)
+ return type_stack[--type_stack_depth].int_val;
+ /* "Can't happen". */
+ return 0;
+}
+
void
_initialize_expread ()
{
type_stack_size = 80;
type_stack_depth = 0;
- type_stack = (enum type_pieces *)
- xmalloc (type_stack_size * sizeof (enum type_pieces));
+ type_stack = (union type_stack_elt *)
+ xmalloc (type_stack_size * sizeof (*type_stack));
}