#include "language.h"
#include "c-lang.h"
-/* These MUST be included in any grammar file!!!! Please choose unique names!
- Note that this are a combined list of variables that can be produced
- by any one of bison, byacc, or yacc. */
+/* 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 c_maxdepth
#define yyparse c_parse
#define yylex c_lex
#define yy_yyv c_yyv
#define yyval c_val
#define yylloc c_lloc
-#define yyss c_yyss /* byacc */
-#define yyssp c_yysp /* byacc */
-#define yyvs c_yyvs /* byacc */
-#define yyvsp c_yyvsp /* byacc */
+#define yyreds c_reds /* With YYDEBUG defined */
+#define yytoks c_toks /* With YYDEBUG defined */
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
int
yyparse PARAMS ((void));
-int
+static int
yylex PARAMS ((void));
void
yyerror PARAMS ((char *));
-/* #define YYDEBUG 1 */
-
%}
/* Although the yacc "value" of an expression is not used,
%union
{
LONGEST lval;
- unsigned LONGEST ulval;
struct {
LONGEST val;
struct type *type;
parse_number PARAMS ((char *, int, int, YYSTYPE *));
%}
-%type <voidval> exp exp1 type_exp start variable qualified_name
+%type <voidval> exp exp1 type_exp start variable qualified_name lcurly
+%type <lval> rcurly
%type <tval> type typebase
%type <tvec> nonempty_typelist
/* %type <bval> block */
write_exp_elt_opcode (OP_FUNCALL); }
;
+lcurly : '{'
+ { start_arglist (); }
+ ;
+
arglist :
;
{ arglist_len++; }
;
-exp : '{' type '}' exp %prec UNARY
+rcurly : '}'
+ { $$ = end_arglist () - 1; }
+ ;
+exp : lcurly arglist rcurly %prec ARROW
+ { write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) $3);
+ write_exp_elt_opcode (OP_ARRAY); }
+ ;
+
+exp : lcurly type rcurly exp %prec UNARY
{ write_exp_elt_opcode (UNOP_MEMVAL);
write_exp_elt_type ($2);
write_exp_elt_opcode (UNOP_MEMVAL); }
;
exp : STRING
- { write_exp_elt_opcode (OP_STRING);
- write_exp_string ($1);
- write_exp_elt_opcode (OP_STRING); }
+ { /* C strings are converted into array constants with
+ an explicit null byte added at the end. Thus
+ the array upper bound is the string length.
+ There is no such thing in C as a completely empty
+ string. */
+ char *sp = $1.ptr; int count = $1.length;
+ while (count-- > 0)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)(*sp++));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)'\0');
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) ($1.length));
+ write_exp_elt_opcode (OP_ARRAY); }
;
/* C++. */
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- if (strcmp (type_name_no_tag (type), $4.ptr))
+ if (!STREQ (type_name_no_tag (type), $4.ptr))
error ("invalid destructor `%s::~%s'",
type_name_no_tag (type), $4.ptr);
{
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) msymbol -> address);
+ write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
if (msymbol -> type == mst_data ||
{
write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) msymbol -> address);
+ write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
write_exp_elt_opcode (OP_LONG);
write_exp_elt_opcode (UNOP_MEMVAL);
if (msymbol -> type == mst_data ||
int done = 0;
int array_size;
struct type *follow_type = $1;
+ struct type *range_type;
while (!done)
switch (pop_type ())
case tp_array:
array_size = pop_type_int ();
if (array_size != -1)
- follow_type =
- create_array_type ((struct type *) NULL,
- follow_type, builtin_type_int,
- 0, array_size - 1);
+ {
+ range_type =
+ create_range_type ((struct type *) NULL,
+ builtin_type_int, 0,
+ array_size - 1);
+ follow_type =
+ create_array_type ((struct type *) NULL,
+ follow_type, range_type);
+ }
else
follow_type = lookup_pointer_type (follow_type);
break;
register int base = input_radix;
int unsigned_p = 0;
int long_p = 0;
- LONGEST high_bit;
+ unsigned LONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
if ((TARGET_INT_BIT != TARGET_LONG_BIT && (n >> TARGET_INT_BIT)) || long_p)
{
- high_bit = ((LONGEST)1) << (TARGET_LONG_BIT-1);
+ high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
unsigned_type = builtin_type_unsigned_long;
signed_type = builtin_type_long;
}
else
{
- high_bit = ((LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
unsigned_type = builtin_type_unsigned_int;
signed_type = builtin_type_int;
}
enum exp_opcode opcode;
};
-const static struct token tokentab3[] =
+static const struct token tokentab3[] =
{
{">>=", ASSIGN_MODIFY, BINOP_RSH},
{"<<=", ASSIGN_MODIFY, BINOP_LSH}
};
-const static struct token tokentab2[] =
+static const struct token tokentab2[] =
{
{"+=", ASSIGN_MODIFY, BINOP_ADD},
{"-=", ASSIGN_MODIFY, BINOP_SUB},
/* Read one token, getting characters through lexptr. */
-int
+static int
yylex ()
{
int c;
tokstart = lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
- if (!strncmp (tokstart, tokentab3[i].operator, 3))
+ if (STREQN (tokstart, tokentab3[i].operator, 3))
{
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 (!strncmp (tokstart, tokentab2[i].operator, 2))
+ if (STREQN (tokstart, tokentab2[i].operator, 2))
{
lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
if (*tokstart == '$') {
for (c = 0; c < NUM_REGS; c++)
if (namelen - 1 == strlen (reg_names[c])
- && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
+ && STREQN (tokstart + 1, reg_names[c], namelen - 1))
{
yylval.lval = c;
return REGNAME;
}
for (c = 0; c < num_std_regs; c++)
if (namelen - 1 == strlen (std_regs[c].name)
- && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
+ && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
{
yylval.lval = std_regs[c].regnum;
return REGNAME;
switch (namelen)
{
case 8:
- if (!strncmp (tokstart, "unsigned", 8))
+ if (STREQN (tokstart, "unsigned", 8))
return UNSIGNED;
if (current_language->la_language == language_cplus
- && !strncmp (tokstart, "template", 8))
+ && STREQN (tokstart, "template", 8))
return TEMPLATE;
- if (!strncmp (tokstart, "volatile", 8))
+ if (STREQN (tokstart, "volatile", 8))
return VOLATILE_KEYWORD;
break;
case 6:
- if (!strncmp (tokstart, "struct", 6))
+ if (STREQN (tokstart, "struct", 6))
return STRUCT;
- if (!strncmp (tokstart, "signed", 6))
+ if (STREQN (tokstart, "signed", 6))
return SIGNED_KEYWORD;
- if (!strncmp (tokstart, "sizeof", 6))
+ if (STREQN (tokstart, "sizeof", 6))
return SIZEOF;
break;
case 5:
if (current_language->la_language == language_cplus
- && !strncmp (tokstart, "class", 5))
+ && STREQN (tokstart, "class", 5))
return CLASS;
- if (!strncmp (tokstart, "union", 5))
+ if (STREQN (tokstart, "union", 5))
return UNION;
- if (!strncmp (tokstart, "short", 5))
+ if (STREQN (tokstart, "short", 5))
return SHORT;
- if (!strncmp (tokstart, "const", 5))
+ if (STREQN (tokstart, "const", 5))
return CONST_KEYWORD;
break;
case 4:
- if (!strncmp (tokstart, "enum", 4))
+ if (STREQN (tokstart, "enum", 4))
return ENUM;
- if (!strncmp (tokstart, "long", 4))
+ if (STREQN (tokstart, "long", 4))
return LONG;
if (current_language->la_language == language_cplus
- && !strncmp (tokstart, "this", 4))
+ && STREQN (tokstart, "this", 4))
{
static const char this_name[] =
{ CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
}
break;
case 3:
- if (!strncmp (tokstart, "int", 3))
+ if (STREQN (tokstart, "int", 3))
return INT_KEYWORD;
break;
default: