X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fp-exp.y;h=19f5cebb06ac245c3d1f0650efd80b97cc9d0e2d;hb=3c853d931322f71b01a217f05bb8302f32a263d2;hp=92f93ff092f2c9ca5b1839ee602ec8f6deeea0c5;hpb=7877e97730123929da00a6fd91c7b8257f26d027;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/p-exp.y b/gdb/p-exp.y index 92f93ff092..19f5cebb06 100644 --- a/gdb/p-exp.y +++ b/gdb/p-exp.y @@ -1,22 +1,21 @@ /* YACC parser for Pascal expressions, for GDB. - Copyright (C) 2000, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2000, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. -This file is part of GDB. + This file is part of GDB. -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 2 of the License, or -(at your option) any later version. + 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 3 of the License, or + (at your option) any later version. -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. + 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 this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ /* This file is derived from c-exp.y */ @@ -58,6 +57,8 @@ Boston, MA 02110-1301, USA. */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ #include "block.h" +#define parse_type builtin_type (parse_gdbarch) + /* 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 @@ -157,7 +158,7 @@ static int parse_number (char *, int, int, YYSTYPE *); static struct type *current_type; - +static int leftdiv_is_integer; static void push_current_type (void); static void pop_current_type (void); static int search_field; @@ -233,6 +234,7 @@ static int search_field; start : { current_type = NULL; search_field = 0; + leftdiv_is_integer = 0; } normal_start {} ; @@ -332,7 +334,10 @@ exp : exp '(' { write_exp_elt_opcode (OP_FUNCALL); write_exp_elt_longcst ((LONGEST) end_arglist ()); write_exp_elt_opcode (OP_FUNCALL); - pop_current_type (); } + pop_current_type (); + if (current_type) + current_type = TYPE_TARGET_TYPE (current_type); + } ; arglist : @@ -367,8 +372,24 @@ exp : exp '*' exp { write_exp_elt_opcode (BINOP_MUL); } ; -exp : exp '/' exp - { write_exp_elt_opcode (BINOP_DIV); } +exp : exp '/' { + if (current_type && is_integral_type (current_type)) + leftdiv_is_integer = 1; + } + exp + { + if (leftdiv_is_integer && current_type + && is_integral_type (current_type)) + { + write_exp_elt_opcode (UNOP_CAST); + write_exp_elt_type (parse_type->builtin_long_double); + current_type = parse_type->builtin_long_double; + write_exp_elt_opcode (UNOP_CAST); + leftdiv_is_integer = 0; + } + + write_exp_elt_opcode (BINOP_DIV); + } ; exp : exp DIV exp @@ -396,27 +417,39 @@ exp : exp RSH exp ; exp : exp '=' exp - { write_exp_elt_opcode (BINOP_EQUAL); } + { write_exp_elt_opcode (BINOP_EQUAL); + current_type = parse_type->builtin_bool; + } ; exp : exp NOTEQUAL exp - { write_exp_elt_opcode (BINOP_NOTEQUAL); } + { write_exp_elt_opcode (BINOP_NOTEQUAL); + current_type = parse_type->builtin_bool; + } ; exp : exp LEQ exp - { write_exp_elt_opcode (BINOP_LEQ); } + { write_exp_elt_opcode (BINOP_LEQ); + current_type = parse_type->builtin_bool; + } ; exp : exp GEQ exp - { write_exp_elt_opcode (BINOP_GEQ); } + { write_exp_elt_opcode (BINOP_GEQ); + current_type = parse_type->builtin_bool; + } ; exp : exp '<' exp - { write_exp_elt_opcode (BINOP_LESS); } + { write_exp_elt_opcode (BINOP_LESS); + current_type = parse_type->builtin_bool; + } ; exp : exp '>' exp - { write_exp_elt_opcode (BINOP_GTR); } + { write_exp_elt_opcode (BINOP_GTR); + current_type = parse_type->builtin_bool; + } ; exp : exp ANDAND exp @@ -438,18 +471,21 @@ exp : exp ASSIGN exp exp : TRUEKEYWORD { write_exp_elt_opcode (OP_BOOL); write_exp_elt_longcst ((LONGEST) $1); + current_type = parse_type->builtin_bool; write_exp_elt_opcode (OP_BOOL); } ; exp : FALSEKEYWORD { write_exp_elt_opcode (OP_BOOL); write_exp_elt_longcst ((LONGEST) $1); + current_type = parse_type->builtin_bool; write_exp_elt_opcode (OP_BOOL); } ; exp : INT { write_exp_elt_opcode (OP_LONG); write_exp_elt_type ($1.type); + current_type = $1.type; write_exp_elt_longcst ((LONGEST)($1.val)); write_exp_elt_opcode (OP_LONG); } ; @@ -459,6 +495,7 @@ exp : NAME_OR_INT parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); write_exp_elt_opcode (OP_LONG); write_exp_elt_type (val.typed_val_int.type); + current_type = val.typed_val_int.type; write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); write_exp_elt_opcode (OP_LONG); } @@ -468,6 +505,7 @@ exp : NAME_OR_INT exp : FLOAT { write_exp_elt_opcode (OP_DOUBLE); write_exp_elt_type ($1.type); + current_type = $1.type; write_exp_elt_dblcst ($1.dval); write_exp_elt_opcode (OP_DOUBLE); } ; @@ -481,12 +519,15 @@ exp : VARIABLE exp : SIZEOF '(' type ')' %prec UNARY { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_int); + write_exp_elt_type (parse_type->builtin_int); CHECK_TYPEDEF ($3); write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); write_exp_elt_opcode (OP_LONG); } ; +exp : SIZEOF '(' exp ')' %prec UNARY + { write_exp_elt_opcode (UNOP_SIZEOF); } + exp : STRING { /* C strings are converted into array constants with an explicit null byte added at the end. Thus @@ -497,12 +538,12 @@ exp : STRING while (count-- > 0) { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_char); + write_exp_elt_type (parse_type->builtin_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_type (parse_type->builtin_char); write_exp_elt_longcst ((LONGEST)'\0'); write_exp_elt_opcode (OP_LONG); write_exp_elt_opcode (OP_ARRAY); @@ -559,8 +600,7 @@ block : BLOCKNAME block : block COLONCOLON name { struct symbol *tem = lookup_symbol (copy_name ($3), $1, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", copy_name ($3)); @@ -570,8 +610,7 @@ block : block COLONCOLON name variable: block COLONCOLON name { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (sym == 0) error ("No symbol \"%s\" in specified context.", copy_name ($3)); @@ -607,8 +646,7 @@ variable: qualified_name sym = lookup_symbol (name, (const struct block *) NULL, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (sym) { write_exp_elt_opcode (OP_VAR_VALUE); @@ -620,16 +658,11 @@ variable: qualified_name msymbol = lookup_minimal_symbol (name, NULL, NULL); if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } + write_exp_msymbol (msymbol); + else if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); else - if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"file\" command."); - else - error ("No symbol \"%s\" in current context.", name); + error ("No symbol \"%s\" in current context.", name); } ; @@ -640,9 +673,9 @@ variable: name_not_typename { if (symbol_read_needs_frame (sym)) { - if (innermost_block == 0 || - contained_in (block_found, - innermost_block)) + if (innermost_block == 0 + || contained_in (block_found, + innermost_block)) innermost_block = block_found; } @@ -661,8 +694,9 @@ variable: name_not_typename /* Object pascal: it hangs off of `this'. Must not inadvertently convert from a method call to data ref. */ - if (innermost_block == 0 || - contained_in (block_found, innermost_block)) + if (innermost_block == 0 + || contained_in (block_found, + innermost_block)) innermost_block = block_found; write_exp_elt_opcode (OP_THIS); write_exp_elt_opcode (OP_THIS); @@ -690,11 +724,7 @@ variable: name_not_typename msymbol = lookup_minimal_symbol (arg, NULL, NULL); if (msymbol != NULL) - { - write_exp_msymbol (msymbol, - lookup_function_type (builtin_type_int), - builtin_type_int); - } + write_exp_msymbol (msymbol); else if (!have_full_symbols () && !have_partial_symbols ()) error ("No symbol table is loaded. Use the \"file\" command."); else @@ -761,11 +791,7 @@ name_not_typename : NAME /*** Needs some error checking for the float case ***/ static int -parse_number (p, len, parsed_float, putithere) - char *p; - int len; - int parsed_float; - YYSTYPE *putithere; +parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere) { /* FIXME: Shouldn't these be unsigned? We don't deal with negative values here, and we do kind of silly things like cast to unsigned. */ @@ -790,30 +816,10 @@ parse_number (p, len, parsed_float, putithere) if (parsed_float) { - /* It's a float since it contains a point or an exponent. */ - char c; - int num = 0; /* number of tokens scanned by scanf */ - char saved_char = p[len]; - - p[len] = 0; /* null-terminate the token */ - num = sscanf (p, DOUBLEST_SCAN_FORMAT "%c", - &putithere->typed_val_float.dval, &c); - p[len] = saved_char; /* restore the input stream */ - if (num != 1) /* check scanf found ONLY a float ... */ - return ERROR; - /* See if it has `f' or `l' suffix (float or long double). */ - - c = tolower (p[len - 1]); - - if (c == 'f') - putithere->typed_val_float.type = builtin_type_float; - else if (c == 'l') - putithere->typed_val_float.type = builtin_type_long_double; - else if (isdigit (c) || c == '.') - putithere->typed_val_float.type = builtin_type_double; - else + if (! parse_c_float (parse_gdbarch, p, len, + &putithere->typed_val_float.dval, + &putithere->typed_val_float.type)) return ERROR; - return FLOAT; } @@ -916,9 +922,9 @@ parse_number (p, len, parsed_float, putithere) un = (ULONGEST)n >> 2; if (long_p == 0 - && (un >> (gdbarch_int_bit (current_gdbarch) - 2)) == 0) + && (un >> (gdbarch_int_bit (parse_gdbarch) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (gdbarch_int_bit (current_gdbarch) - 1); + high_bit = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch) - 1); /* A large decimal (not hex or octal) constant (between INT_MAX and UINT_MAX) is a long or unsigned long, according to ANSI, @@ -926,28 +932,28 @@ parse_number (p, len, parsed_float, putithere) int. This probably should be fixed. GCC gives a warning on such constants. */ - unsigned_type = builtin_type_unsigned_int; - signed_type = builtin_type_int; + unsigned_type = parse_type->builtin_unsigned_int; + signed_type = parse_type->builtin_int; } else if (long_p <= 1 - && (un >> (gdbarch_long_bit (current_gdbarch) - 2)) == 0) + && (un >> (gdbarch_long_bit (parse_gdbarch) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (gdbarch_long_bit (current_gdbarch) - 1); - unsigned_type = builtin_type_unsigned_long; - signed_type = builtin_type_long; + high_bit = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch) - 1); + unsigned_type = parse_type->builtin_unsigned_long; + signed_type = parse_type->builtin_long; } else { int shift; if (sizeof (ULONGEST) * HOST_CHAR_BIT - < gdbarch_long_long_bit (current_gdbarch)) + < gdbarch_long_long_bit (parse_gdbarch)) /* A long long does not fit in a LONGEST. */ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); else - shift = (gdbarch_long_long_bit (current_gdbarch) - 1); + shift = (gdbarch_long_long_bit (parse_gdbarch) - 1); high_bit = (ULONGEST) 1 << shift; - unsigned_type = builtin_type_unsigned_long_long; - signed_type = builtin_type_long_long; + unsigned_type = parse_type->builtin_unsigned_long_long; + signed_type = parse_type->builtin_long_long; } putithere->typed_val_int.val = n; @@ -995,7 +1001,7 @@ pop_current_type (void) { current_type = tp->stored; tp_top = tp->next; - xfree (tp); + free (tp); } } @@ -1058,7 +1064,6 @@ yylex () char *tokstart; char *uptokstart; char *tokptr; - char *p; int explen, tempbufindex; static char *tempbuf; static int tempbufsize; @@ -1111,12 +1116,12 @@ yylex () lexptr++; c = *lexptr++; if (c == '\\') - c = parse_escape (&lexptr); + c = parse_escape (parse_gdbarch, &lexptr); else if (c == '\'') error ("Empty character constant."); yylval.typed_val_int.val = c; - yylval.typed_val_int.type = builtin_type_char; + yylval.typed_val_int.type = parse_type->builtin_char; c = *lexptr++; if (c != '\'') @@ -1276,7 +1281,7 @@ yylex () break; case '\\': tokptr++; - c = parse_escape (&tokptr); + c = parse_escape (parse_gdbarch, &tokptr); if (c == -1) { continue; @@ -1354,29 +1359,29 @@ yylex () switch (namelen) { case 6: - if (DEPRECATED_STREQ (uptokstart, "OBJECT")) + if (strcmp (uptokstart, "OBJECT") == 0) { free (uptokstart); return CLASS; } - if (DEPRECATED_STREQ (uptokstart, "RECORD")) + if (strcmp (uptokstart, "RECORD") == 0) { free (uptokstart); return STRUCT; } - if (DEPRECATED_STREQ (uptokstart, "SIZEOF")) + if (strcmp (uptokstart, "SIZEOF") == 0) { free (uptokstart); return SIZEOF; } break; case 5: - if (DEPRECATED_STREQ (uptokstart, "CLASS")) + if (strcmp (uptokstart, "CLASS") == 0) { free (uptokstart); return CLASS; } - if (DEPRECATED_STREQ (uptokstart, "FALSE")) + if (strcmp (uptokstart, "FALSE") == 0) { yylval.lval = 0; free (uptokstart); @@ -1384,21 +1389,20 @@ yylex () } break; case 4: - if (DEPRECATED_STREQ (uptokstart, "TRUE")) + if (strcmp (uptokstart, "TRUE") == 0) { yylval.lval = 1; free (uptokstart); return TRUEKEYWORD; } - if (DEPRECATED_STREQ (uptokstart, "SELF")) + if (strcmp (uptokstart, "SELF") == 0) { /* here we search for 'this' like inserted in FPC stabs debug info */ static const char this_name[] = "this"; if (lookup_symbol (this_name, expression_context_block, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL)) + VAR_DOMAIN, (int *) NULL)) { free (uptokstart); return THIS; @@ -1442,9 +1446,7 @@ yylex () sym = NULL; else sym = lookup_symbol (tmp, expression_context_block, - VAR_DOMAIN, - &is_a_field_of_this, - (struct symtab **) NULL); + VAR_DOMAIN, &is_a_field_of_this); /* second chance uppercased (as Free Pascal does). */ if (!sym && !is_a_field_of_this && !is_a_field) { @@ -1459,9 +1461,7 @@ yylex () sym = NULL; else sym = lookup_symbol (tmp, expression_context_block, - VAR_DOMAIN, - &is_a_field_of_this, - (struct symtab **) NULL); + VAR_DOMAIN, &is_a_field_of_this); if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { @@ -1489,9 +1489,7 @@ yylex () sym = NULL; else sym = lookup_symbol (tmp, expression_context_block, - VAR_DOMAIN, - &is_a_field_of_this, - (struct symtab **) NULL); + VAR_DOMAIN, &is_a_field_of_this); if (sym || is_a_field_of_this || is_a_field) for (i = 0; i <= namelen; i++) { @@ -1518,8 +1516,8 @@ yylex () /* Call lookup_symtab, not lookup_partial_symtab, in case there are no psymtabs (coff, xcoff, or some future change to blow away the psymtabs once once symbols are read). */ - if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || - lookup_symtab (tmp)) + if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + || lookup_symtab (tmp)) { yylval.ssym.sym = sym; yylval.ssym.is_a_field_of_this = is_a_field_of_this; @@ -1588,8 +1586,7 @@ yylex () memcpy (tmp1, namestart, p - namestart); tmp1[p - namestart] = '\0'; cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (cur_sym) { if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) @@ -1618,8 +1615,8 @@ yylex () return TYPENAME; } yylval.tsym.type - = language_lookup_primitive_type_by_name (current_language, - current_gdbarch, tmp); + = language_lookup_primitive_type_by_name (parse_language, + parse_gdbarch, tmp); if (yylval.tsym.type != NULL) { free (uptokstart); @@ -1629,9 +1626,9 @@ yylex () /* Input names that aren't symbols but ARE valid hex numbers, when the input radix permits them, can be names or numbers depending on the parse. Note we support radixes > 16 here. */ - if (!sym && - ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || - (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) + if (!sym + && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) + || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) { YYSTYPE newlval; /* Its value is ignored. */ hextype = parse_number (tokstart, namelen, 0, &newlval);