X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fc-exp.y;h=153e2be3cf8a188549d81c65452d8e2270209c66;hb=c567841d5a717ca202d7eca27ebe45ee515b71ae;hp=c6fc52c63a54150a16037cce3552a43363680b17;hpb=06891d83421e10e9d29301527a4ff5297d8744a3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/c-exp.y b/gdb/c-exp.y index c6fc52c63a..153e2be3cf 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1,6 +1,6 @@ /* YACC parser for C expressions, for GDB. - Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 + Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GDB. @@ -17,7 +17,8 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* Parse a C expression from text in a string, and return the result as a struct expression pointer. @@ -49,9 +50,12 @@ 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" +#include "block.h" +#include "cp-support.h" +#include "dfp.h" -/* Flag indicating we're dealing with HP-compiled objects */ -extern int hp_som_som_object_present; +#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 @@ -61,7 +65,7 @@ extern int hp_som_som_object_present; generators need to be fixed instead of adding those names to this list. */ #define yymaxdepth c_maxdepth -#define yyparse c_parse +#define yyparse c_parse_internal #define yylex c_lex #define yyerror c_error #define yylval c_lval @@ -130,6 +134,10 @@ void yyerror (char *); DOUBLEST dval; struct type *type; } typed_val_float; + struct { + gdb_byte val[16]; + struct type *type; + } typed_val_decfloat; struct symbol *sym; struct type *tval; struct stoken sval; @@ -151,7 +159,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %type exp exp1 type_exp start variable qualified_name lcurly %type rcurly -%type type typebase +%type type typebase qualified_type %type nonempty_typelist /* %type block */ @@ -162,6 +170,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %token INT %token FLOAT +%token DECFLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -173,8 +182,9 @@ static int parse_number (char *, int, int, YYSTYPE *); %token STRING %token NAME /* BLOCKNAME defined below to give it higher precedence. */ +%token COMPLETE %token TYPENAME -%type name +%type name string_exp %type name_not_typename %type typename @@ -198,7 +208,6 @@ static int parse_number (char *, int, int, YYSTYPE *); %token ASSIGN_MODIFY /* C++ */ -%token THIS %token TRUEKEYWORD %token FALSEKEYWORD @@ -247,14 +256,20 @@ 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); } ; +exp : '+' exp %prec UNARY + { write_exp_elt_opcode (UNOP_PLUS); } + ; + exp : '!' exp %prec UNARY { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } ; @@ -289,6 +304,23 @@ exp : exp ARROW name write_exp_elt_opcode (STRUCTOP_PTR); } ; +exp : exp ARROW name COMPLETE + { mark_struct_expression (); + write_exp_elt_opcode (STRUCTOP_PTR); + write_exp_string ($3); + write_exp_elt_opcode (STRUCTOP_PTR); } + ; + +exp : exp ARROW COMPLETE + { struct stoken s; + mark_struct_expression (); + write_exp_elt_opcode (STRUCTOP_PTR); + s.ptr = ""; + s.length = 0; + write_exp_string (s); + write_exp_elt_opcode (STRUCTOP_PTR); } + ; + exp : exp ARROW qualified_name { /* exp->type::name becomes exp->*(&type::name) */ /* Note: this doesn't work if name is a @@ -307,6 +339,23 @@ exp : exp '.' name write_exp_elt_opcode (STRUCTOP_STRUCT); } ; +exp : exp '.' name COMPLETE + { mark_struct_expression (); + write_exp_elt_opcode (STRUCTOP_STRUCT); + write_exp_string ($3); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + ; + +exp : exp '.' COMPLETE + { struct stoken s; + mark_struct_expression (); + write_exp_elt_opcode (STRUCTOP_STRUCT); + s.ptr = ""; + s.length = 0; + write_exp_string (s); + write_exp_elt_opcode (STRUCTOP_STRUCT); } + ; + exp : exp '.' qualified_name { /* exp.type::name becomes exp.*(&type::name) */ /* Note: this doesn't work if name is a @@ -491,6 +540,13 @@ exp : FLOAT write_exp_elt_opcode (OP_DOUBLE); } ; +exp : DECFLOAT + { write_exp_elt_opcode (OP_DECFLOAT); + write_exp_elt_type ($1.type); + write_exp_elt_decfloatcst ($1.val); + write_exp_elt_opcode (OP_DECFLOAT); } + ; + exp : variable ; @@ -500,13 +556,40 @@ 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 : STRING +string_exp: + STRING + { + /* We copy the string here, and not in the + lexer, to guarantee that we do not leak a + string. Note that we follow the + NUL-termination convention of the + lexer. */ + $$.length = $1.length; + $$.ptr = malloc ($1.length + 1); + memcpy ($$.ptr, $1.ptr, $1.length + 1); + } + + | string_exp STRING + { + /* Note that we NUL-terminate here, but just + for convenience. */ + struct stoken t; + t.length = $1.length + $2.length; + t.ptr = malloc (t.length + 1); + memcpy (t.ptr, $1.ptr, $1.length); + memcpy (t.ptr + $1.length, $2.ptr, $2.length + 1); + free ($1.ptr); + $$ = t; + } + ; + +exp : string_exp { /* 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. @@ -516,36 +599,33 @@ 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); write_exp_elt_longcst ((LONGEST) 0); write_exp_elt_longcst ((LONGEST) ($1.length)); - write_exp_elt_opcode (OP_ARRAY); } + write_exp_elt_opcode (OP_ARRAY); + free ($1.ptr); + } ; /* 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); + write_exp_elt_type (parse_type->builtin_bool); write_exp_elt_longcst ((LONGEST) 1); write_exp_elt_opcode (OP_LONG); } ; exp : FALSEKEYWORD { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_bool); + write_exp_elt_type (parse_type->builtin_bool); write_exp_elt_longcst ((LONGEST) 0); write_exp_elt_opcode (OP_LONG); } ; @@ -569,8 +649,7 @@ block : BLOCKNAME block : block COLONCOLON name { struct symbol *tem = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (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)); @@ -580,8 +659,7 @@ block : block COLONCOLON name variable: block COLONCOLON name { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (sym == 0) error ("No symbol \"%s\" in specified context.", copy_name ($3)); @@ -597,7 +675,8 @@ qualified_name: typebase COLONCOLON name { struct type *type = $1; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -611,7 +690,8 @@ qualified_name: typebase COLONCOLON name struct type *type = $1; struct stoken tmp_token; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -639,8 +719,7 @@ variable: qualified_name sym = lookup_symbol (name, (const struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, (int *) NULL); if (sym) { write_exp_elt_opcode (OP_VAR_VALUE); @@ -652,16 +731,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); } ; @@ -703,16 +777,12 @@ variable: name_not_typename else { struct minimal_symbol *msymbol; - register char *arg = copy_name ($1.stoken); + char *arg = copy_name ($1.stoken); 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 @@ -784,10 +854,10 @@ array_mod: '[' ']' func_mod: '(' ')' { $$ = 0; } | '(' nonempty_typelist ')' - { free ((PTR)$2); $$ = 0; } + { free ($2); $$ = 0; } ; -/* We used to try to recognize more pointer to member types here, but +/* We used to try to recognize pointer to member types here, but that didn't work (shift/reduce conflicts meant that these rules never got executed). The problem is that int (foo::bar::baz::bizzle) @@ -796,71 +866,67 @@ func_mod: '(' ')' is a pointer to member type. Stroustrup loses again! */ type : ptype - | typebase COLONCOLON '*' - { $$ = lookup_member_type (builtin_type_int, $1); } ; typebase /* Implements (approximately): (type-qualifier)* type-specifier */ : TYPENAME { $$ = $1.type; } | INT_KEYWORD - { $$ = builtin_type_int; } + { $$ = parse_type->builtin_int; } | LONG - { $$ = builtin_type_long; } + { $$ = parse_type->builtin_long; } | SHORT - { $$ = builtin_type_short; } + { $$ = parse_type->builtin_short; } | LONG INT_KEYWORD - { $$ = builtin_type_long; } + { $$ = parse_type->builtin_long; } | LONG SIGNED_KEYWORD INT_KEYWORD - { $$ = builtin_type_long; } + { $$ = parse_type->builtin_long; } | LONG SIGNED_KEYWORD - { $$ = builtin_type_long; } + { $$ = parse_type->builtin_long; } | SIGNED_KEYWORD LONG INT_KEYWORD - { $$ = builtin_type_long; } + { $$ = parse_type->builtin_long; } | UNSIGNED LONG INT_KEYWORD - { $$ = builtin_type_unsigned_long; } + { $$ = parse_type->builtin_unsigned_long; } | LONG UNSIGNED INT_KEYWORD - { $$ = builtin_type_unsigned_long; } + { $$ = parse_type->builtin_unsigned_long; } | LONG UNSIGNED - { $$ = builtin_type_unsigned_long; } + { $$ = parse_type->builtin_unsigned_long; } | LONG LONG - { $$ = builtin_type_long_long; } + { $$ = parse_type->builtin_long_long; } | LONG LONG INT_KEYWORD - { $$ = builtin_type_long_long; } + { $$ = parse_type->builtin_long_long; } | LONG LONG SIGNED_KEYWORD INT_KEYWORD - { $$ = builtin_type_long_long; } + { $$ = parse_type->builtin_long_long; } | LONG LONG SIGNED_KEYWORD - { $$ = builtin_type_long_long; } + { $$ = parse_type->builtin_long_long; } | SIGNED_KEYWORD LONG LONG - { $$ = builtin_type_long_long; } + { $$ = parse_type->builtin_long_long; } + | SIGNED_KEYWORD LONG LONG INT_KEYWORD + { $$ = parse_type->builtin_long_long; } | UNSIGNED LONG LONG - { $$ = builtin_type_unsigned_long_long; } + { $$ = parse_type->builtin_unsigned_long_long; } | UNSIGNED LONG LONG INT_KEYWORD - { $$ = builtin_type_unsigned_long_long; } + { $$ = parse_type->builtin_unsigned_long_long; } | LONG LONG UNSIGNED - { $$ = builtin_type_unsigned_long_long; } + { $$ = parse_type->builtin_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"); } + { $$ = parse_type->builtin_unsigned_long_long; } | SHORT INT_KEYWORD - { $$ = builtin_type_short; } + { $$ = parse_type->builtin_short; } | SHORT SIGNED_KEYWORD INT_KEYWORD - { $$ = builtin_type_short; } + { $$ = parse_type->builtin_short; } | SHORT SIGNED_KEYWORD - { $$ = builtin_type_short; } + { $$ = parse_type->builtin_short; } | UNSIGNED SHORT INT_KEYWORD - { $$ = builtin_type_unsigned_short; } + { $$ = parse_type->builtin_unsigned_short; } | SHORT UNSIGNED - { $$ = builtin_type_unsigned_short; } + { $$ = parse_type->builtin_unsigned_short; } | SHORT UNSIGNED INT_KEYWORD - { $$ = builtin_type_unsigned_short; } + { $$ = parse_type->builtin_unsigned_short; } | DOUBLE_KEYWORD - { $$ = builtin_type_double; } + { $$ = parse_type->builtin_double; } | LONG DOUBLE_KEYWORD - { $$ = builtin_type_long_double; } + { $$ = parse_type->builtin_long_double; } | STRUCT name { $$ = lookup_struct (copy_name ($2), expression_context_block); } @@ -876,11 +942,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ | UNSIGNED typename { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); } | UNSIGNED - { $$ = builtin_type_unsigned_int; } + { $$ = parse_type->builtin_unsigned_int; } | SIGNED_KEYWORD typename { $$ = lookup_signed_typename (TYPE_NAME($2.type)); } | SIGNED_KEYWORD - { $$ = builtin_type_int; } + { $$ = parse_type->builtin_int; } /* It appears that this rule for templates is never reduced; template recognition happens by lookahead in the token processing code in yylex. */ @@ -892,6 +958,77 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = follow_types ($2); } | typebase const_or_volatile_or_space_identifier_noopt { $$ = follow_types ($1); } + | qualified_type + ; + +/* FIXME: carlton/2003-09-25: This next bit leads to lots of + reduce-reduce conflicts, because the parser doesn't know whether or + not to use qualified_name or qualified_type: the rules are + identical. If the parser is parsing 'A::B::x', then, when it sees + the second '::', it knows that the expression to the left of it has + to be a type, so it uses qualified_type. But if it is parsing just + 'A::B', then it doesn't have any way of knowing which rule to use, + so there's a reduce-reduce conflict; it picks qualified_name, since + that occurs earlier in this file than qualified_type. + + There's no good way to fix this with the grammar as it stands; as + far as I can tell, some of the problems arise from ambiguities that + GDB introduces ('start' can be either an expression or a type), but + some of it is inherent to the nature of C++ (you want to treat the + input "(FOO)" fairly differently depending on whether FOO is an + expression or a type, and if FOO is a complex expression, this can + be hard to determine at the right time). Fortunately, it works + pretty well in most cases. For example, if you do 'ptype A::B', + where A::B is a nested type, then the parser will mistakenly + misidentify it as an expression; but evaluate_subexp will get + called with 'noside' set to EVAL_AVOID_SIDE_EFFECTS, and everything + will work out anyways. But there are situations where the parser + will get confused: the most common one that I've run into is when + you want to do + + print *((A::B *) x)" + + where the parser doesn't realize that A::B has to be a type until + it hits the first right paren, at which point it's too late. (The + workaround is to type "print *(('A::B' *) x)" instead.) (And + another solution is to fix our symbol-handling code so that the + user never wants to type something like that in the first place, + because we get all the types right without the user's help!) + + Perhaps we could fix this by making the lexer smarter. Some of + this functionality used to be in the lexer, but in a way that + worked even less well than the current solution: that attempt + involved having the parser sometimes handle '::' and having the + lexer sometimes handle it, and without a clear division of + responsibility, it quickly degenerated into a big mess. Probably + the eventual correct solution will give more of a role to the lexer + (ideally via code that is shared between the lexer and + decode_line_1), but I'm not holding my breath waiting for somebody + to get around to cleaning this up... */ + +qualified_type: typebase COLONCOLON name + { + struct type *type = $1; + struct type *new_type; + char *ncopy = alloca ($3.length + 1); + + memcpy (ncopy, $3.ptr, $3.length); + ncopy[$3.length] = '\0'; + + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + new_type = cp_lookup_nested_type (type, ncopy, + expression_context_block); + if (new_type == NULL) + error ("No type \"%s\" within class or namespace \"%s\".", + ncopy, TYPE_NAME (type)); + + $$ = new_type; + } ; typename: TYPENAME @@ -899,19 +1036,19 @@ typename: TYPENAME { $$.stoken.ptr = "int"; $$.stoken.length = 3; - $$.type = builtin_type_int; + $$.type = parse_type->builtin_int; } | LONG { $$.stoken.ptr = "long"; $$.stoken.length = 4; - $$.type = builtin_type_long; + $$.type = parse_type->builtin_long; } | SHORT { $$.stoken.ptr = "short"; $$.stoken.length = 5; - $$.type = builtin_type_short; + $$.type = parse_type->builtin_short; } ; @@ -974,20 +1111,20 @@ name_not_typename : NAME static int parse_number (p, len, parsed_float, putithere) - register char *p; - register int len; + 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. */ - register LONGEST n = 0; - register LONGEST prevn = 0; + LONGEST n = 0; + LONGEST prevn = 0; ULONGEST un; - register int i = 0; - register int c; - register int base = input_radix; + int i = 0; + int c; + int base = input_radix; int unsigned_p = 0; /* Number of "L" suffixes encountered. */ @@ -1003,44 +1140,72 @@ 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]; + char *s; + int num; /* number of tokens scanned by scanf */ + char saved_char; - p[len] = 0; /* null-terminate the token */ - if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) - num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c); - else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) - num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c); - else + /* If it ends at "df", "dd" or "dl", take it as type of decimal floating + point. Return DECFLOAT. */ + + if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'f') { -#ifdef SCANF_HAS_LONG_DOUBLE - num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c); -#else - /* Scan it into a double, then assign it to the long double. - This at least wins with values representable in the range - of doubles. */ - double temp; - num = sscanf (p, "%lg%c", &temp,&c); - putithere->typed_val_float.dval = temp; -#endif + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type + = parse_type->builtin_decfloat; + decimal_from_string (putithere->typed_val_decfloat.val, 4, p); + p[len - 2] = 'd'; + return DECFLOAT; } + + if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'd') + { + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type + = parse_type->builtin_decdouble; + decimal_from_string (putithere->typed_val_decfloat.val, 8, p); + p[len - 2] = 'd'; + return DECFLOAT; + } + + if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'l') + { + p[len - 2] = '\0'; + putithere->typed_val_decfloat.type + = parse_type->builtin_declong; + decimal_from_string (putithere->typed_val_decfloat.val, 16, p); + p[len - 2] = 'd'; + return DECFLOAT; + } + + s = malloc (len); + saved_char = p[len]; + p[len] = 0; /* null-terminate the token */ + num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%s", + &putithere->typed_val_float.dval, s); 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 - return ERROR; + if (num == 1) + putithere->typed_val_float.type = + parse_type->builtin_double; + + if (num == 2 ) + { + /* See if it has any float suffix: 'f' for float, 'l' for long + double. */ + if (!strcasecmp (s, "f")) + putithere->typed_val_float.type = + parse_type->builtin_float; + else if (!strcasecmp (s, "l")) + putithere->typed_val_float.type = + parse_type->builtin_long_double; + else + { + free (s); + return ERROR; + } + } + + free (s); return FLOAT; } @@ -1136,16 +1301,16 @@ parse_number (p, len, parsed_float, putithere) shift it right and see whether anything remains. Note that we can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one operation, because many compilers will warn about such a shift - (which always produces a zero result). Sometimes TARGET_INT_BIT - or TARGET_LONG_BIT will be that big, sometimes not. To deal with + (which always produces a zero result). Sometimes gdbarch_int_bit + or gdbarch_long_bit will be that big, sometimes not. To deal with the case where it is we just always shift the value more than once, with fewer bits each time. */ un = (ULONGEST)n >> 2; if (long_p == 0 - && (un >> (TARGET_INT_BIT - 2)) == 0) + && (un >> (gdbarch_int_bit (parse_gdbarch) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-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, @@ -1153,27 +1318,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 >> (TARGET_LONG_BIT - 2)) == 0) + && (un >> (gdbarch_long_bit (parse_gdbarch) - 2)) == 0) { - high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-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 < TARGET_LONG_LONG_BIT) + if (sizeof (ULONGEST) * HOST_CHAR_BIT + < gdbarch_long_long_bit (parse_gdbarch)) /* A long long does not fit in a LONGEST. */ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1); else - shift = (TARGET_LONG_LONG_BIT - 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; @@ -1230,6 +1396,16 @@ static const struct token tokentab2[] = {">=", GEQ, BINOP_END} }; +/* This is set if a NAME token appeared at the very end of the input + string, with no whitespace separating the name from the EOF. This + is used only when parsing to do field name completion. */ +static int saw_name_at_eof; + +/* This is set if the previously-returned token was a structure + operator -- either '.' or ARROW. This is used only when parsing to + do field name completion. */ +static int last_was_structop; + /* Read one token, getting characters through lexptr. */ static int @@ -1243,11 +1419,12 @@ yylex () int tempbufindex; static char *tempbuf; static int tempbufsize; - struct symbol * sym_class = NULL; char * token_string = NULL; int class_prefix = 0; - int unquoted_expr; - + int saw_structop = last_was_structop; + + last_was_structop = 0; + retry: /* Check if this is a macro invocation that we need to expand. */ @@ -1262,12 +1439,11 @@ yylex () } prev_lexptr = lexptr; - unquoted_expr = 1; tokstart = lexptr; /* See if it is a special token of length 3. */ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (STREQN (tokstart, tokentab3[i].operator, 3)) + if (strncmp (tokstart, tokentab3[i].operator, 3) == 0) { lexptr += 3; yylval.opcode = tokentab3[i].opcode; @@ -1276,10 +1452,12 @@ yylex () /* See if it is a special token of length 2. */ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (STREQN (tokstart, tokentab2[i].operator, 2)) + if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) { lexptr += 2; yylval.opcode = tokentab2[i].opcode; + if (in_parse_field && tokentab2[i].token == ARROW) + last_was_structop = 1; return tokentab2[i].token; } @@ -1288,6 +1466,8 @@ yylex () case 0: /* If we were just scanning the result of a macro expansion, then we need to resume scanning the original text. + If we're parsing for field name completion, and the previous + token allows such completion, return a COMPLETE token. Otherwise, we were already scanning the original text, and we're really done. */ if (scanning_macro_expansion ()) @@ -1295,6 +1475,13 @@ yylex () finished_macro_expansion (); goto retry; } + else if (saw_name_at_eof) + { + saw_name_at_eof = 0; + return COMPLETE; + } + else if (saw_structop) + return COMPLETE; else return 0; @@ -1314,9 +1501,18 @@ 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; + yylval.typed_val_int.type = parse_type->builtin_char; c = *lexptr++; if (c != '\'') @@ -1325,7 +1521,6 @@ yylex () if (namelen > 2) { lexptr = tokstart + namelen; - unquoted_expr = 0; if (lexptr[-1] != '\'') error ("Unmatched single quote."); namelen -= 2; @@ -1359,7 +1554,11 @@ yylex () case '.': /* Might be a floating point number. */ if (lexptr[1] < '0' || lexptr[1] > '9') - goto symbol; /* Nope, must be a symbol. */ + { + if (in_parse_field) + last_was_structop = 1; + goto symbol; /* Nope, must be a symbol. */ + } /* FALL THRU into number case. */ case '0': @@ -1375,7 +1574,7 @@ yylex () { /* It's a number. */ int got_dot = 0, got_e = 0, toktype; - register char *p = tokstart; + char *p = tokstart; int hex = input_radix > 10; if (c == '0' && (p[1] == 'x' || p[1] == 'X')) @@ -1464,6 +1663,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) @@ -1486,7 +1687,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')); @@ -1549,63 +1762,52 @@ yylex () switch (namelen) { case 8: - if (STREQN (tokstart, "unsigned", 8)) + if (strncmp (tokstart, "unsigned", 8) == 0) return UNSIGNED; - if (current_language->la_language == language_cplus - && STREQN (tokstart, "template", 8)) + if (parse_language->la_language == language_cplus + && strncmp (tokstart, "template", 8) == 0) return TEMPLATE; - if (STREQN (tokstart, "volatile", 8)) + if (strncmp (tokstart, "volatile", 8) == 0) return VOLATILE_KEYWORD; break; case 6: - if (STREQN (tokstart, "struct", 6)) + if (strncmp (tokstart, "struct", 6) == 0) return STRUCT; - if (STREQN (tokstart, "signed", 6)) + if (strncmp (tokstart, "signed", 6) == 0) return SIGNED_KEYWORD; - if (STREQN (tokstart, "sizeof", 6)) + if (strncmp (tokstart, "sizeof", 6) == 0) return SIZEOF; - if (STREQN (tokstart, "double", 6)) + if (strncmp (tokstart, "double", 6) == 0) return DOUBLE_KEYWORD; break; case 5: - if (current_language->la_language == language_cplus) + if (parse_language->la_language == language_cplus) { - if (STREQN (tokstart, "false", 5)) + if (strncmp (tokstart, "false", 5) == 0) return FALSEKEYWORD; - if (STREQN (tokstart, "class", 5)) + if (strncmp (tokstart, "class", 5) == 0) return CLASS; } - if (STREQN (tokstart, "union", 5)) + if (strncmp (tokstart, "union", 5) == 0) return UNION; - if (STREQN (tokstart, "short", 5)) + if (strncmp (tokstart, "short", 5) == 0) return SHORT; - if (STREQN (tokstart, "const", 5)) + if (strncmp (tokstart, "const", 5) == 0) return CONST_KEYWORD; break; case 4: - if (STREQN (tokstart, "enum", 4)) + if (strncmp (tokstart, "enum", 4) == 0) return ENUM; - if (STREQN (tokstart, "long", 4)) + if (strncmp (tokstart, "long", 4) == 0) return LONG; - if (current_language->la_language == language_cplus) + if (parse_language->la_language == language_cplus) { - if (STREQN (tokstart, "true", 4)) + if (strncmp (tokstart, "true", 4) == 0) 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: - if (STREQN (tokstart, "int", 3)) + if (strncmp (tokstart, "int", 3) == 0) return INT_KEYWORD; break; default: @@ -1621,24 +1823,6 @@ yylex () return VARIABLE; } - /* Look ahead and see if we can consume more of the input - string to get a reasonable class/namespace spec or a - fully-qualified name. This is a kludge to get around the - HP aCC compiler's generation of symbol names with embedded - colons for namespace and nested classes. */ - if (unquoted_expr) - { - /* Only do it if not inside single quotes */ - sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length, - &token_string, &class_prefix, &lexptr); - if (sym_class) - { - /* Replace the current token with the bigger one we found */ - yylval.sval.ptr = token_string; - yylval.sval.length = strlen (token_string); - } - } - /* Use token-type BLOCKNAME for symbols that happen to be defined as functions or symtabs. If this is not so, then ... Use token-type TYPENAME for symbols that happen to be defined @@ -1651,10 +1835,9 @@ yylex () int hextype; sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - current_language->la_language == language_cplus - ? &is_a_field_of_this : (int *) NULL, - (struct symtab **) NULL); + VAR_DOMAIN, + parse_language->la_language == language_cplus + ? &is_a_field_of_this : (int *) NULL); /* 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). */ @@ -1679,95 +1862,16 @@ yylex () if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) { -#if 1 - /* Despite the following flaw, we need to keep this code enabled. - Because we can get called from check_stub_method, if we don't - handle nested types then it screws many operations in any - program which uses nested types. */ - /* In "A::x", if x is a member function of A and there happens - to be a type (nested or not, since the stabs don't make that - distinction) named x, then this code incorrectly thinks we - are dealing with nested types rather than a member function. */ - - char *p; - char *namestart; - struct symbol *best_sym; - - /* Look ahead to detect nested types. This probably should be - done in the grammar, but trying seemed to introduce a lot - of shift/reduce and reduce/reduce conflicts. It's possible - that it could be done, though. Or perhaps a non-grammar, but - less ad hoc, approach would work well. */ - - /* Since we do not currently have any way of distinguishing - a nested type from a non-nested one (the stabs don't tell - us whether a type is nested), we just ignore the - containing type. */ - - p = lexptr; - best_sym = sym; - while (1) - { - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - if (*p == ':' && p[1] == ':') - { - /* Skip the `::'. */ - p += 2; - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - namestart = p; - while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'z') - || (*p >= 'A' && *p <= 'Z')) - ++p; - if (p != namestart) - { - struct symbol *cur_sym; - /* As big as the whole rest of the expression, which is - at least big enough. */ - char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); - char *tmp1; - - tmp1 = ncopy; - memcpy (tmp1, tmp, strlen (tmp)); - tmp1 += strlen (tmp); - memcpy (tmp1, "::", 2); - tmp1 += 2; - memcpy (tmp1, namestart, p - namestart); - tmp1[p - namestart] = '\0'; - cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (cur_sym) - { - if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) - { - best_sym = cur_sym; - lexptr = p; - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - - yylval.tsym.type = SYMBOL_TYPE (best_sym); -#else /* not 0 */ + /* NOTE: carlton/2003-09-25: There used to be code here to + handle nested types. It didn't work very well. See the + comment before qualified_type for more info. */ yylval.tsym.type = SYMBOL_TYPE (sym); -#endif /* not 0 */ return TYPENAME; } - if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) + yylval.tsym.type + = language_lookup_primitive_type_by_name (parse_language, + parse_gdbarch, tmp); + if (yylval.tsym.type != NULL) return TYPENAME; /* Input names that aren't symbols but ARE valid hex numbers, @@ -1790,10 +1894,20 @@ yylex () /* Any other kind of symbol */ yylval.ssym.sym = sym; yylval.ssym.is_a_field_of_this = is_a_field_of_this; + if (in_parse_field && *lexptr == '\0') + saw_name_at_eof = 1; return NAME; } } +int +c_parse (void) +{ + last_was_structop = 0; + saw_name_at_eof = 0; + return yyparse (); +} + void yyerror (msg) char *msg;