X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fc-exp.y;h=9df0aee428ffe8af76ab93153a88a26e097ec0e3;hb=3bcbaac54041e1226ae28cf918d4f5daf1a899af;hp=d4291f7b979806d8615d98c7d01171277b9a4648;hpb=d0352a18a504a4e7b761f6b3264cf11347d8d056;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/c-exp.y b/gdb/c-exp.y index d4291f7b97..9df0aee428 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1,5 +1,6 @@ /* 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. @@ -48,6 +49,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 "charset.h" /* Flag indicating we're dealing with HP-compiled objects */ extern int hp_som_som_object_present; @@ -88,6 +90,8 @@ extern int hp_som_som_object_present; #define yylloc c_lloc #define yyreds c_reds /* With YYDEBUG defined */ #define yytoks c_toks /* With YYDEBUG defined */ +#define yyname c_name /* With YYDEBUG defined */ +#define yyrule c_rule /* With YYDEBUG defined */ #define yylhs c_yylhs #define yylen c_yylen #define yydefred c_yydefred @@ -99,9 +103,11 @@ extern int hp_som_som_object_present; #define yycheck c_yycheck #ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ +#define YYDEBUG 1 /* Default to yydebug support */ #endif +#define YYFPRINTF parser_fprintf + int yyparse (void); static int yylex (void); @@ -193,7 +199,6 @@ static int parse_number (char *, int, int, YYSTYPE *); %token ASSIGN_MODIFY /* C++ */ -%token THIS %token TRUEKEYWORD %token FALSEKEYWORD @@ -242,9 +247,11 @@ exp1 : exp /* Expressions, not including the comma operator. */ exp : '*' exp %prec UNARY { write_exp_elt_opcode (UNOP_IND); } + ; exp : '&' exp %prec UNARY { write_exp_elt_opcode (UNOP_ADDR); } + ; exp : '-' exp %prec UNARY { write_exp_elt_opcode (UNOP_NEG); } @@ -526,11 +533,6 @@ exp : STRING ; /* C++. */ -exp : THIS - { write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); } - ; - exp : TRUEKEYWORD { write_exp_elt_opcode (OP_LONG); write_exp_elt_type (builtin_type_bool); @@ -717,21 +719,26 @@ variable: name_not_typename } ; +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: '*' @@ -801,20 +808,52 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = 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 @@ -846,11 +885,10 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = 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 @@ -887,6 +925,25 @@ nonempty_typelist } ; +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; } @@ -1190,6 +1247,18 @@ yylex () 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; @@ -1214,7 +1283,17 @@ yylex () 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': @@ -1232,6 +1311,15 @@ yylex () c = parse_escape (&lexptr); else if (c == '\'') error ("Empty character constant."); + else if (! host_char_to_target (c, &c)) + { + int toklen = lexptr - tokstart + 1; + char *tok = alloca (toklen + 1); + memcpy (tok, tokstart, toklen); + tok[toklen] = '\0'; + error ("There is no character corresponding to %s in the target " + "character set `%s'.", tok, target_charset ()); + } yylval.typed_val_int.val = c; yylval.typed_val_int.type = builtin_type_char; @@ -1267,7 +1355,9 @@ yylex () return c; case ',': - if (comma_terminates && paren_depth == 0) + if (comma_terminates + && paren_depth == 0 + && ! scanning_macro_expansion ()) return 0; lexptr++; return c; @@ -1380,6 +1470,8 @@ yylex () tempbufindex = 0; do { + char *char_start_pos = tokptr; + /* Grow the static temp buffer if necessary, including allocating the first one on demand. */ if (tempbufindex + 1 >= tempbufsize) @@ -1402,7 +1494,19 @@ yylex () tempbuf[tempbufindex++] = c; break; default: - tempbuf[tempbufindex++] = *tokptr++; + c = *tokptr++; + if (! host_char_to_target (c, &c)) + { + int len = tokptr - char_start_pos; + char *copy = alloca (len + 1); + memcpy (copy, char_start_pos, len); + copy[len] = '\0'; + + error ("There is no character corresponding to `%s' " + "in the target character set `%s'.", + copy, target_charset ()); + } + tempbuf[tempbufindex++] = c; break; } } while ((*tokptr != '"') && (*tokptr != '\0')); @@ -1446,9 +1550,13 @@ yylex () 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; } @@ -1503,17 +1611,6 @@ yylex () { if (STREQN (tokstart, "true", 4)) return TRUEKEYWORD; - - if (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: @@ -1680,7 +1777,7 @@ yylex () 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 @@ -1710,5 +1807,8 @@ void yyerror (msg) char *msg; { + if (prev_lexptr) + lexptr = prev_lexptr; + error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); }