%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++. */
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 the number is too big to be an int, or it's got an l suffix
then it's a long. Work out if this has to be a long by
shifting right and and seeing if anything remains, and the
- target int size is different to the target long size. */
-
- if ((TARGET_INT_BIT != TARGET_LONG_BIT && (n >> TARGET_INT_BIT)) || long_p)
+ target int size is different to the target long size.
+
+ In the expression below, we could have tested
+ (n >> TARGET_INT_BIT)
+ to see if it was zero,
+ but too many compilers warn about that, when ints and longs
+ are the same size. So we shift it twice, with fewer bits
+ each time, for the same result. */
+
+ if ( (TARGET_INT_BIT != TARGET_LONG_BIT
+ && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
+ || 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;
}
/* Read one token, getting characters through lexptr. */
-int
+static int
yylex ()
{
int c;