/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994
+ Free Software Foundation, Inc.
This file is part of GDB.
%{
#include "defs.h"
+#include <string.h>
#include "expression.h"
-#include "parser-defs.h"
#include "value.h"
+#include "parser-defs.h"
#include "language.h"
#include "c-lang.h"
+#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 */
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple
(struct objfile *) NULL);
if (msymbol != NULL)
{
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_opcode (UNOP_MEMVAL);
- if (msymbol -> type == mst_data ||
- msymbol -> type == mst_bss)
- write_exp_elt_type (builtin_type_int);
- else if (msymbol -> type == mst_text)
- write_exp_elt_type (lookup_function_type (builtin_type_int));
- else
- write_exp_elt_type (builtin_type_char);
- write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
}
else
if (!have_full_symbols () && !have_partial_symbols ())
if (sym)
{
- switch (SYMBOL_CLASS (sym))
+ if (symbol_read_needs_frame (sym))
{
- case LOC_REGISTER:
- case LOC_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_LOCAL:
- case LOC_LOCAL_ARG:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
if (innermost_block == 0 ||
contained_in (block_found,
innermost_block))
innermost_block = block_found;
- case LOC_UNDEF:
- case LOC_CONST:
- case LOC_STATIC:
- case LOC_TYPEDEF:
- case LOC_LABEL:
- case LOC_BLOCK:
- case LOC_CONST_BYTES:
- case LOC_OPTIMIZED_OUT:
-
- /* In this case the expression can
- be evaluated regardless of what
- frame we are in, so there is no
- need to check for the
- innermost_block. These cases are
- listed so that gcc -Wall will
- report types that may not have
- been considered. */
-
- break;
}
+
write_exp_elt_opcode (OP_VAR_VALUE);
/* We want to use the selected frame, not
another more inner frame which happens to
(struct objfile *) NULL);
if (msymbol != NULL)
{
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_opcode (UNOP_MEMVAL);
- if (msymbol -> type == mst_data ||
- msymbol -> type == mst_bss)
- write_exp_elt_type (builtin_type_int);
- else if (msymbol -> type == mst_text)
- write_exp_elt_type (lookup_function_type (builtin_type_int));
- else
- write_exp_elt_type (builtin_type_char);
- write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
}
else if (!have_full_symbols () && !have_partial_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
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
- {
- /* This is where the interesting stuff happens. */
- int done = 0;
- int array_size;
- struct type *follow_type = $1;
- struct type *range_type;
-
- while (!done)
- switch (pop_type ())
- {
- case tp_end:
- done = 1;
- break;
- case tp_pointer:
- follow_type = lookup_pointer_type (follow_type);
- break;
- case tp_reference:
- follow_type = lookup_reference_type (follow_type);
- break;
- case tp_array:
- array_size = pop_type_int ();
- if (array_size != -1)
- {
- range_type =
- create_range_type ((struct type *) NULL,
- builtin_type_int, 0,
- array_size - 1);
- follow_type =
- create_array_type ((struct type *) NULL,
- follow_type, range_type);
- }
- else
- follow_type = lookup_pointer_type (follow_type);
- break;
- case tp_function:
- follow_type = lookup_function_type (follow_type);
- break;
- }
- $$ = follow_type;
- }
+ { $$ = follow_types ($1); }
+ | typebase CONST_KEYWORD abs_decl
+ { $$ = follow_types ($1); }
+ | typebase VOLATILE_KEYWORD abs_decl
+ { $$ = follow_types ($1); }
;
abs_decl: '*'
push_type (tp_array);
$$ = 0;
}
+
| direct_abs_decl func_mod
{ push_type (tp_function); }
| func_mod
{ free ((PTR)$2); $$ = 0; }
;
+/* We used to try to recognize more 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)
+ is a function type but
+ int (foo::bar::baz::bizzle::*)
+ is a pointer to member type. Stroustrup loses again! */
+
type : ptype
| typebase COLONCOLON '*'
{ $$ = lookup_member_type (builtin_type_int, $1); }
- | type '(' typebase COLONCOLON '*' ')'
- { $$ = lookup_member_type ($1, $3); }
- | type '(' typebase COLONCOLON '*' ')' '(' ')'
- { $$ = lookup_member_type
- (lookup_function_type ($1), $3); }
- | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'
- { $$ = lookup_member_type
- (lookup_function_type ($1), $3);
- free ((PTR)$8); }
;
typebase /* Implements (approximately): (type-qualifier)* type-specifier */
{ $$ = lookup_template_type(copy_name($2), $4,
expression_context_block);
}
- /* "const" and "volatile" are curently ignored. */
+ /* "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; }
;
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;
+ unsigned LONGEST un;
+
register int i = 0;
register int c;
register int base = input_radix;
int unsigned_p = 0;
+
+ /* Number of "L" suffixes encountered. */
int long_p = 0;
+
+ /* We have found a "L" or "U" suffix. */
+ int found_suffix = 0;
+
unsigned LONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
if (c != 'l' && c != 'u')
n *= base;
if (c >= '0' && c <= '9')
- n += i = c - '0';
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - '0';
+ }
else
{
if (base > 10 && c >= 'a' && c <= 'f')
- n += i = c - 'a' + 10;
- else if (len == 0 && c == 'l')
- long_p = 1;
- else if (len == 0 && c == 'u')
- unsigned_p = 1;
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - 'a' + 10;
+ }
+ else if (c == 'l')
+ {
+ ++long_p;
+ found_suffix = 1;
+ }
+ else if (c == 'u')
+ {
+ unsigned_p = 1;
+ found_suffix = 1;
+ }
else
return ERROR; /* Char not a digit */
}
return ERROR; /* Invalid digit in this base */
/* Portably test for overflow (only works for nonzero values, so make
- a second check for zero). */
- if((prevn >= n) && n != 0)
- unsigned_p=1; /* Try something unsigned */
- /* If range checking enabled, portably test for unsigned overflow. */
- if(RANGE_CHECK && n!=0)
- {
- if((unsigned_p && (unsigned)prevn >= (unsigned)n))
- range_error("Overflow on numeric constant.");
- }
- prevn=n;
+ a second check for zero). FIXME: Can't we just make n and prevn
+ unsigned and avoid this? */
+ if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
+ unsigned_p = 1; /* Try something unsigned */
+
+ /* Portably test for unsigned overflow.
+ FIXME: This check is wrong; for example it doesn't find overflow
+ on 0x123456789 when LONGEST is 32 bits. */
+ if (c != 'l' && c != 'u' && n != 0)
+ {
+ if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
+ error ("Numeric constant too large.");
+ }
+ prevn = n;
+ }
+
+ /* An integer constant is an int, a long, or a long long. An L
+ suffix forces it to be long; an LL suffix forces it to be long
+ long. If not forced to a larger size, it gets the first type of
+ the above that it fits in. To figure out whether it fits, we
+ 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
+ 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)
+ {
+ high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+
+ /* A large decimal (not hex or octal) constant (between INT_MAX
+ and UINT_MAX) is a long or unsigned long, according to ANSI,
+ never an unsigned int, but this code treats it as unsigned
+ int. This probably should be fixed. GCC gives a warning on
+ such constants. */
+
+ unsigned_type = builtin_type_unsigned_int;
+ signed_type = builtin_type_int;
+ }
+ else if (long_p <= 1
+ && (un >> (TARGET_LONG_BIT - 2)) == 0)
+ {
+ high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+ unsigned_type = builtin_type_unsigned_long;
+ signed_type = builtin_type_long;
+ }
+ else
+ {
+ high_bit = (((unsigned LONGEST)1)
+ << (TARGET_LONG_LONG_BIT - 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;
}
-
- /* If the number is too big to be an int, or it's got an l suffix
- then it's a long. Work out if this has to be a long by
- shifting right and and seeing if anything remains, and the
- target int size is different to the target long size.
-
- In the expression below, we could have tested
- (n >> TARGET_INT_BIT)
- to see if it was zero,
- but too many compilers warn about that, when ints and longs
- are the same size. So we shift it twice, with fewer bits
- each time, for the same result. */
-
- if ( (TARGET_INT_BIT != TARGET_LONG_BIT
- && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
- || long_p)
- {
- high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
- unsigned_type = builtin_type_unsigned_long;
- signed_type = builtin_type_long;
- }
- else
- {
- high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
- unsigned_type = builtin_type_unsigned_int;
- signed_type = builtin_type_int;
- }
putithere->typed_val.val = n;
if (unsigned_p || (n & high_bit))
{
- putithere->typed_val.type = unsigned_type;
+ putithere->typed_val.type = unsigned_type;
}
else
{
- putithere->typed_val.type = signed_type;
+ putithere->typed_val.type = signed_type;
}
return INT;
current_language->la_language == language_cplus
? &is_a_field_of_this : (int *) NULL,
(struct symtab **) 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). */
if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
- lookup_partial_symtab (tmp))
+ lookup_symtab (tmp))
{
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this;
}
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;
struct symbol *cur_sym;
/* As big as the whole rest of the expression, which is
at least big enough. */
- char *tmp = alloca (strlen (namestart));
+ char *tmp = alloca (strlen (namestart)+1);
memcpy (tmp, namestart, p - namestart);
tmp[p - namestart] = '\0';
}
yylval.tsym.type = SYMBOL_TYPE (best_sym);
+#else /* not 0 */
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+#endif /* not 0 */
return TYPENAME;
}
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
yyerror (msg)
char *msg;
{
- error (msg ? msg : "Invalid syntax in expression.");
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
}