/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994
- Free Software Foundation, Inc.
-This file is part of GDB.
+ Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 2002, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 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. */
/* Parse a C expression from text in a string, and return the result
as a struct expression pointer. That structure contains arithmetic
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols. */
#include "top.h"
#include "completer.h" /* For skip_quoted(). */
+#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
#endif
int
-yyparse PARAMS ((void));
+yyparse (void);
static int
-yylex PARAMS ((void));
+yylex (void);
void
-yyerror PARAMS ((char *));
+yyerror (char *);
%}
%{
/* YYSTYPE gets defined by %union. */
static int
-parse_number PARAMS ((char *, int, int, YYSTYPE *));
+parse_number (char *, int, int, YYSTYPE *);
%}
%type <voidval> exp exp1 type_exp start variable qualified_name lcurly
%token <opcode> ASSIGN_MODIFY
-/* C++ */
-%token THIS
-
%left ','
%left ABOVE_COMMA
%right '=' ASSIGN_MODIFY
/* 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); }
error ("%s is not an ObjC Class",
copy_name ($2.stoken));
write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
+ write_exp_elt_type (parse_type->builtin_int);
write_exp_elt_longcst ((LONGEST) class);
write_exp_elt_opcode (OP_LONG);
start_msglist();
}
msglist ']'
- { write_exp_elt_opcode (OP_MSGCALL);
+ { write_exp_elt_opcode (OP_OBJC_MSGCALL);
end_msglist();
- write_exp_elt_opcode (OP_MSGCALL);
+ write_exp_elt_opcode (OP_OBJC_MSGCALL);
}
;
exp : '[' CLASSNAME
{
write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
+ write_exp_elt_type (parse_type->builtin_int);
write_exp_elt_longcst ((LONGEST) $2.class);
write_exp_elt_opcode (OP_LONG);
start_msglist();
}
msglist ']'
- { write_exp_elt_opcode (OP_MSGCALL);
+ { write_exp_elt_opcode (OP_OBJC_MSGCALL);
end_msglist();
- write_exp_elt_opcode (OP_MSGCALL);
+ write_exp_elt_opcode (OP_OBJC_MSGCALL);
}
;
exp : '[' exp
{ start_msglist(); }
msglist ']'
- { write_exp_elt_opcode (OP_MSGCALL);
+ { write_exp_elt_opcode (OP_OBJC_MSGCALL);
end_msglist();
- write_exp_elt_opcode (OP_MSGCALL);
+ write_exp_elt_opcode (OP_OBJC_MSGCALL);
}
;
exp : SELECTOR
{
- write_exp_elt_opcode (OP_SELECTOR);
+ write_exp_elt_opcode (OP_OBJC_SELECTOR);
write_exp_string ($1);
- write_exp_elt_opcode (OP_SELECTOR); }
+ write_exp_elt_opcode (OP_OBJC_SELECTOR); }
+ ;
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); }
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);
exp : NSSTRING /* ObjC NextStep NSString constant
* of the form '@' '"' string '"'.
*/
- { write_exp_elt_opcode (OP_NSSTRING);
+ { write_exp_elt_opcode (OP_OBJC_NSSTRING);
write_exp_string ($1);
- write_exp_elt_opcode (OP_NSSTRING); }
+ write_exp_elt_opcode (OP_OBJC_NSSTRING); }
;
-/* C++. */
-exp : THIS
- { write_exp_elt_opcode (OP_THIS);
- write_exp_elt_opcode (OP_THIS); }
- ;
-
-/* end of C++. */
-
block : BLOCKNAME
{
if ($1.sym != 0)
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));
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));
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- if (!STREQ (type_name_no_tag (type), $4.ptr))
+ if (strcmp (type_name_no_tag (type), $4.ptr) != 0)
error ("invalid destructor `%s::~%s'",
type_name_no_tag (type), $4.ptr);
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);
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);
}
;
if (innermost_block == 0 ||
contained_in (block_found, innermost_block))
innermost_block = block_found;
- write_exp_elt_opcode (OP_SELF);
- write_exp_elt_opcode (OP_SELF);
+ write_exp_elt_opcode (OP_OBJC_SELF);
+ write_exp_elt_opcode (OP_OBJC_SELF);
write_exp_elt_opcode (STRUCTOP_PTR);
write_exp_string ($1.stoken);
write_exp_elt_opcode (STRUCTOP_PTR);
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.");
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
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. */
$$ = $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; }
| UNSIGNED LONG INT_KEYWORD
- { $$ = 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; }
| 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; }
| SHORT INT_KEYWORD
- { $$ = builtin_type_short; }
+ { $$ = parse_type->builtin_short; }
| UNSIGNED SHORT 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); }
| 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; }
| TEMPLATE name '<' type '>'
{ $$ = lookup_template_type(copy_name($2), $4,
expression_context_block);
{
$$.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;
}
;
name_not_typename (=variable, =exp) or just an exp. If
name_not_typename was ever used in an lvalue context where only a
name could occur, this might be useful. */
- | NAME_OR_INT */
+/* | NAME_OR_INT */
;
%%
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;
unsigned LONGEST 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. */
/* It's a float since it contains a point or an exponent. */
- if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
- sscanf (p, "%g", &putithere->typed_val_float.dval);
- else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
- sscanf (p, "%lg", &putithere->typed_val_float.dval);
- else
- {
-#ifdef PRINTF_HAS_LONG_DOUBLE
- sscanf (p, "%Lg", &putithere->typed_val_float.dval);
-#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;
- sscanf (p, "%lg", &temp);
- putithere->typed_val_float.dval = temp;
-#endif
- }
+ sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
+ &putithere->typed_val_float.dval, &c);
/* 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;
+ putithere->typed_val_float.type = parse_type->builtin_float;
else if (c == 'l')
- putithere->typed_val_float.type = builtin_type_long_double;
+ putithere->typed_val_float.type = parse_type->builtin_long_double;
else if (isdigit (c) || c == '.')
- putithere->typed_val_float.type = builtin_type_double;
+ putithere->typed_val_float.type = parse_type->builtin_double;
else
return ERROR;
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_int 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 = (unsigned LONGEST)n >> 2;
if (long_p == 0
- && (un >> (TARGET_INT_BIT - 2)) == 0)
+ && (un >> (gdbarch_int_bit (parse_gdbarch) - 2)) == 0)
{
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+ high_bit = ((unsigned LONGEST)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,
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 = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
- unsigned_type = builtin_type_unsigned_long;
- signed_type = builtin_type_long;
+ high_bit = ((unsigned LONGEST)1) << (gdbarch_long_bit (parse_gdbarch) - 1);
+ unsigned_type = parse_type->builtin_unsigned_long;
+ signed_type = parse_type->builtin_long;
}
else
{
high_bit = (((unsigned LONGEST)1)
- << (TARGET_LONG_LONG_BIT - 32 - 1)
+ << (gdbarch_long_long_bit (parse_gdbarch) - 32 - 1)
<< 16
<< 16);
if (high_bit == 0)
/* A long long does not fit in a LONGEST. */
high_bit =
(unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1);
- 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;
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;
/* 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;
return tokentab2[i].token;
}
+ c = 0;
switch (tokchr = *tokstart)
{
case 0:
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 != '\'')
{
- namelen = skip_quoted (tokstart,
- get_gdb_completer_word_break_characters())
- - tokstart;
+ namelen = skip_quoted (tokstart) - tokstart;
if (namelen > 2)
{
lexptr = tokstart + namelen;
/* It's a number. */
int got_dot = 0, got_e = 0, toktype = FLOAT;
/* Initialize toktype to anything other than ERROR. */
- register char *p = tokstart;
+ char *p = tokstart;
int hex = input_radix > 10;
int local_radix = input_radix;
if (tokchr == '0' && (p[1] == 'x' || p[1] == 'X'))
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)
- && STREQN (tokstart, "class", 5))
+ if ((parse_language->la_language == language_cplus)
+ && 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
- && 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:
int is_a_field_of_this = 0, *need_this;
int hextype;
- if (current_language->la_language == language_cplus ||
- current_language->la_language == language_objc)
+ if (parse_language->la_language == language_cplus ||
+ parse_language->la_language == language_objc)
need_this = &is_a_field_of_this;
else
need_this = (int *) NULL;
sym = lookup_symbol (tmp, expression_context_block,
- VAR_NAMESPACE,
- need_this,
- (struct symtab **) NULL);
+ VAR_DOMAIN,
+ need_this);
/* 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 symbols are read). */
tmp1[p - namestart] = '\0';
cur_sym = lookup_symbol (ncopy,
expression_context_block,
- VAR_NAMESPACE, (int *) NULL,
- (struct symtab **) NULL);
+ VAR_DOMAIN, (int *) NULL);
if (cur_sym)
{
if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
#endif /* not 0 */
return TYPENAME;
}
- if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
- return TYPENAME;
+ yylval.tsym.type
+ = language_lookup_primitive_type_by_name (parse_language,
+ parse_gdbarch, tmp);
+ if (yylval.tsym.type != NULL)
+ return TYPENAME;
/* See if it's an ObjC classname. */
if (!sym)
CORE_ADDR Class = lookup_objc_class(tmp);
if (Class)
{
- extern struct symbol *lookup_struct_typedef();
yylval.class.class = Class;
if ((sym = lookup_struct_typedef (tmp,
expression_context_block,