/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 1996, 1997
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000
Free Software Foundation, Inc.
This file is part of GDB.
}
;
+space_identifier : '@' NAME
+ { push_type_address_space (copy_name ($2.stoken));
+ push_type (tp_space_identifier);
+ }
+ ;
-ptype : typebase
- /* "const" and "volatile" are curently ignored. A type qualifier
- before the type is currently handled in the typebase rule.
- The reason for recognizing these here (shift/reduce conflicts)
- might be obsolete now that some pointer to member rules have
- been deleted. */
- | typebase CONST_KEYWORD
- | typebase VOLATILE_KEYWORD
- | typebase abs_decl
- { $$ = follow_types ($1); }
- | typebase CONST_KEYWORD abs_decl
- { $$ = follow_types ($1); }
- | typebase VOLATILE_KEYWORD abs_decl
- { $$ = follow_types ($1); }
+const_or_volatile: const_or_volatile_noopt
+ |
+ ;
+
+cv_with_space_id : const_or_volatile space_identifier const_or_volatile
+ ;
+
+const_or_volatile_or_space_identifier_noopt: cv_with_space_id
+ | const_or_volatile_noopt
+ ;
+
+const_or_volatile_or_space_identifier:
+ const_or_volatile_or_space_identifier_noopt
+ |
;
abs_decl: '*'
{ $$ = builtin_type_short; }
| LONG INT_KEYWORD
{ $$ = builtin_type_long; }
+ | LONG SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_long; }
+ | LONG SIGNED_KEYWORD
+ { $$ = builtin_type_long; }
+ | SIGNED_KEYWORD LONG INT_KEYWORD
+ { $$ = builtin_type_long; }
| UNSIGNED LONG INT_KEYWORD
{ $$ = builtin_type_unsigned_long; }
+ | LONG UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_long; }
+ | LONG UNSIGNED
+ { $$ = builtin_type_unsigned_long; }
| LONG LONG
{ $$ = builtin_type_long_long; }
| LONG LONG INT_KEYWORD
{ $$ = builtin_type_long_long; }
+ | LONG LONG SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | LONG LONG SIGNED_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | SIGNED_KEYWORD LONG LONG
+ { $$ = builtin_type_long_long; }
| UNSIGNED LONG LONG
{ $$ = builtin_type_unsigned_long_long; }
| UNSIGNED LONG LONG INT_KEYWORD
{ $$ = builtin_type_unsigned_long_long; }
+ | LONG LONG UNSIGNED
+ { $$ = builtin_type_unsigned_long_long; }
+ | LONG LONG UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_long_long; }
+ | SIGNED_KEYWORD LONG LONG
+ { $$ = lookup_signed_typename ("long long"); }
+ | SIGNED_KEYWORD LONG LONG INT_KEYWORD
+ { $$ = lookup_signed_typename ("long long"); }
| SHORT INT_KEYWORD
{ $$ = builtin_type_short; }
+ | SHORT SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_short; }
+ | SHORT SIGNED_KEYWORD
+ { $$ = builtin_type_short; }
| UNSIGNED SHORT INT_KEYWORD
{ $$ = builtin_type_unsigned_short; }
+ | SHORT UNSIGNED
+ { $$ = builtin_type_unsigned_short; }
+ | SHORT UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_short; }
| DOUBLE_KEYWORD
{ $$ = builtin_type_double; }
| LONG DOUBLE_KEYWORD
{ $$ = lookup_template_type(copy_name($2), $4,
expression_context_block);
}
- /* "const" and "volatile" are curently ignored. A type qualifier
- after the type is handled in the ptype rule. I think these could
- be too. */
- | CONST_KEYWORD typebase { $$ = $2; }
- | VOLATILE_KEYWORD typebase { $$ = $2; }
+ | const_or_volatile_or_space_identifier_noopt typebase
+ { $$ = follow_types ($2); }
+ | typebase const_or_volatile_or_space_identifier_noopt
+ { $$ = follow_types ($1); }
;
typename: TYPENAME
}
;
+ptype : typebase
+ | ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier
+ { $$ = follow_types ($1); }
+ ;
+
+const_and_volatile: CONST_KEYWORD VOLATILE_KEYWORD
+ | VOLATILE_KEYWORD CONST_KEYWORD
+ ;
+
+const_or_volatile_noopt: const_and_volatile
+ { push_type (tp_const);
+ push_type (tp_volatile);
+ }
+ | CONST_KEYWORD
+ { push_type (tp_const); }
+ | VOLATILE_KEYWORD
+ { push_type (tp_volatile); }
+ ;
+
name : NAME { $$ = $1.stoken; }
| BLOCKNAME { $$ = $1.stoken; }
| TYPENAME { $$ = $1.stoken; }
retry:
+ /* Check if this is a macro invocation that we need to expand. */
+ if (! scanning_macro_expansion ())
+ {
+ char *expanded = macro_expand_next (&lexptr,
+ expression_macro_lookup_func,
+ expression_macro_lookup_baton);
+
+ if (expanded)
+ scan_macro_expansion (expanded);
+ }
+
+ prev_lexptr = lexptr;
unquoted_expr = 1;
tokstart = lexptr;
switch (c = *tokstart)
{
case 0:
- return 0;
+ /* If we were just scanning the result of a macro expansion,
+ then we need to resume scanning the original text.
+ Otherwise, we were already scanning the original text, and
+ we're really done. */
+ if (scanning_macro_expansion ())
+ {
+ finished_macro_expansion ();
+ goto retry;
+ }
+ else
+ return 0;
case ' ':
case '\t':
return c;
case ',':
- if (comma_terminates && paren_depth == 0)
+ if (comma_terminates
+ && paren_depth == 0
+ && ! scanning_macro_expansion ())
return 0;
lexptr++;
return c;
c = tokstart[++namelen];
}
- /* The token "if" terminates the expression and is NOT
- removed from the input stream. */
- if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ /* The token "if" terminates the expression and is NOT removed from
+ the input stream. It doesn't count if it appears in the
+ expansion of a macro. */
+ if (namelen == 2
+ && tokstart[0] == 'i'
+ && tokstart[1] == 'f'
+ && ! scanning_macro_expansion ())
{
return 0;
}
return TYPENAME;
}
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
- return TYPENAME;
+ return TYPENAME;
/* Input names that aren't symbols but ARE valid hex numbers,
when the input radix permits them, can be names or numbers
yyerror (msg)
char *msg;
{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
}