/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1986, 1989-2000, 2003-2004, 2006-2012 Free Software
+ Foundation, Inc.
This file is part of GDB.
#define yygindex c_yygindex
#define yytable c_yytable
#define yycheck c_yycheck
+#define yyss c_yyss
+#define yysslim c_yysslim
+#define yyssp c_yyssp
+#define yystacksize c_yystacksize
+#define yyvs c_yyvs
+#define yyvsp c_yyvsp
#ifndef YYDEBUG
#define YYDEBUG 1 /* Default to yydebug support */
%token <tsval> STRING
%token <tsval> CHAR
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <ssym> UNKNOWN_CPP_NAME
%token <voidval> COMPLETE
%token <tsym> TYPENAME
%type <sval> name
%token NEW DELETE
%type <sval> operator
%token REINTERPRET_CAST DYNAMIC_CAST STATIC_CAST CONST_CAST
+%token ENTRY
/* Special type cases, put in to allow the parser to distinguish different
legal basetypes. */
write_exp_elt_opcode (OP_FUNCALL); }
;
+exp : UNKNOWN_CPP_NAME '('
+ {
+ /* This could potentially be a an argument defined
+ lookup function (Koenig). */
+ write_exp_elt_opcode (OP_ADL_FUNC);
+ write_exp_elt_block (expression_context_block);
+ write_exp_elt_sym (NULL); /* Placeholder. */
+ write_exp_string ($1.stoken);
+ write_exp_elt_opcode (OP_ADL_FUNC);
+
+ /* This is to save the value of arglist_len
+ being accumulated by an outer function call. */
+
+ start_arglist ();
+ }
+ arglist ')' %prec ARROW
+ {
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ ;
+
lcurly : '{'
{ start_arglist (); }
;
exp : SIZEOF '(' type ')' %prec UNARY
{ write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (parse_type->builtin_int);
+ write_exp_elt_type (lookup_signed_typename
+ (parse_language, parse_gdbarch,
+ "int"));
CHECK_TYPEDEF ($3);
write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
write_exp_elt_opcode (OP_LONG); }
case C_STRING_32:
if (type != C_STRING
&& type != $1.tokens[i].type)
- error ("Undefined string concatenation.");
+ error (_("Undefined string concatenation."));
type = $1.tokens[i].type;
break;
default:
if ($1.sym)
$$ = SYMBOL_BLOCK_VALUE ($1.sym);
else
- error ("No file or function \"%s\".",
+ error (_("No file or function \"%s\"."),
copy_name ($1.stoken));
}
| FILENAME
= lookup_symbol (copy_name ($3), $1,
VAR_DOMAIN, (int *) NULL);
if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
- error ("No function \"%s\" in specified context.",
+ error (_("No function \"%s\" in specified context."),
copy_name ($3));
$$ = SYMBOL_BLOCK_VALUE (tem); }
;
+variable: name_not_typename ENTRY
+ { struct symbol *sym = $1.sym;
+
+ if (sym == NULL || !SYMBOL_IS_ARGUMENT (sym)
+ || !symbol_read_needs_frame (sym))
+ error (_("@entry can be used only for function "
+ "parameters, not for \"%s\""),
+ copy_name ($1.stoken));
+
+ write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
+ }
+ ;
+
variable: block COLONCOLON name
{ struct symbol *sym;
sym = lookup_symbol (copy_name ($3), $1,
VAR_DOMAIN, (int *) NULL);
if (sym == 0)
- error ("No symbol \"%s\" in specified context.",
+ error (_("No symbol \"%s\" in specified context."),
copy_name ($3));
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0
+ || contained_in (block_found,
+ innermost_block))
+ innermost_block = block_found;
+ }
write_exp_elt_opcode (OP_VAR_VALUE);
/* block_found is set by lookup_symbol. */
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.",
+ error (_("`%s' is not defined as an aggregate type."),
TYPE_NAME (type));
write_exp_elt_opcode (OP_SCOPE);
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.",
+ error (_("`%s' is not defined as an aggregate type."),
TYPE_NAME (type));
tmp_token.ptr = (char*) alloca ($4.length + 2);
tmp_token.ptr[tmp_token.length] = 0;
/* Check for valid destructor name. */
- destructor_name_p (tmp_token.ptr, type);
+ destructor_name_p (tmp_token.ptr, $1.type);
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
write_exp_string (tmp_token);
if (msymbol != NULL)
write_exp_msymbol (msymbol);
else if (!have_full_symbols () && !have_partial_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
+ 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 (msymbol != NULL)
write_exp_msymbol (msymbol);
else if (!have_full_symbols () && !have_partial_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
else
- error ("No symbol \"%s\" in current context.",
+ error (_("No symbol \"%s\" in current context."),
copy_name ($1.stoken));
}
}
: TYPENAME
{ $$ = $1.type; }
| INT_KEYWORD
- { $$ = parse_type->builtin_int; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "int"); }
| LONG
- { $$ = parse_type->builtin_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| SHORT
- { $$ = parse_type->builtin_short; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| LONG INT_KEYWORD
- { $$ = parse_type->builtin_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| LONG SIGNED_KEYWORD INT_KEYWORD
- { $$ = parse_type->builtin_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| LONG SIGNED_KEYWORD
- { $$ = parse_type->builtin_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| SIGNED_KEYWORD LONG INT_KEYWORD
- { $$ = parse_type->builtin_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| UNSIGNED LONG INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| LONG UNSIGNED INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| LONG UNSIGNED
- { $$ = parse_type->builtin_unsigned_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long"); }
| LONG LONG
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| LONG LONG INT_KEYWORD
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| LONG LONG SIGNED_KEYWORD INT_KEYWORD
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| LONG LONG SIGNED_KEYWORD
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| SIGNED_KEYWORD LONG LONG
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| SIGNED_KEYWORD LONG LONG INT_KEYWORD
- { $$ = parse_type->builtin_long_long; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| UNSIGNED LONG LONG
- { $$ = parse_type->builtin_unsigned_long_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| UNSIGNED LONG LONG INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_long_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| LONG LONG UNSIGNED
- { $$ = parse_type->builtin_unsigned_long_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| LONG LONG UNSIGNED INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_long_long; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "long long"); }
| SHORT INT_KEYWORD
- { $$ = parse_type->builtin_short; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| SHORT SIGNED_KEYWORD INT_KEYWORD
- { $$ = parse_type->builtin_short; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| SHORT SIGNED_KEYWORD
- { $$ = parse_type->builtin_short; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| UNSIGNED SHORT INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_short; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| SHORT UNSIGNED
- { $$ = parse_type->builtin_unsigned_short; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| SHORT UNSIGNED INT_KEYWORD
- { $$ = parse_type->builtin_unsigned_short; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "short"); }
| DOUBLE_KEYWORD
- { $$ = parse_type->builtin_double; }
+ { $$ = lookup_typename (parse_language, parse_gdbarch,
+ "double", (struct block *) NULL,
+ 0); }
| LONG DOUBLE_KEYWORD
- { $$ = parse_type->builtin_long_double; }
+ { $$ = lookup_typename (parse_language, parse_gdbarch,
+ "long double",
+ (struct block *) NULL, 0); }
| STRUCT name
{ $$ = lookup_struct (copy_name ($2),
expression_context_block); }
parse_gdbarch,
TYPE_NAME($2.type)); }
| UNSIGNED
- { $$ = parse_type->builtin_unsigned_int; }
+ { $$ = lookup_unsigned_typename (parse_language,
+ parse_gdbarch,
+ "int"); }
| SIGNED_KEYWORD typename
{ $$ = lookup_signed_typename (parse_language,
parse_gdbarch,
TYPE_NAME($2.type)); }
| SIGNED_KEYWORD
- { $$ = parse_type->builtin_int; }
+ { $$ = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "int"); }
/* It appears that this rule for templates is never
reduced; template recognition happens by lookahead
in the token processing code in yylex. */
{
$$.stoken.ptr = "int";
$$.stoken.length = 3;
- $$.type = parse_type->builtin_int;
+ $$.type = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "int");
}
| LONG
{
$$.stoken.ptr = "long";
$$.stoken.length = 4;
- $$.type = parse_type->builtin_long;
+ $$.type = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "long");
}
| SHORT
{
$$.stoken.ptr = "short";
$$.stoken.length = 5;
- $$.type = parse_type->builtin_short;
+ $$.type = lookup_signed_typename (parse_language,
+ parse_gdbarch,
+ "short");
}
;
operator: OPERATOR NEW
{ $$ = operator_stoken (" new"); }
| OPERATOR DELETE
- { $$ = operator_stoken (" delete"); }
+ { $$ = operator_stoken (" delete "); }
| OPERATOR NEW '[' ']'
{ $$ = operator_stoken (" new[]"); }
| OPERATOR DELETE '[' ']'
- { $$ = operator_stoken (" delete[]"); }
+ { $$ = operator_stoken (" delete[] "); }
| OPERATOR '+'
{ $$ = operator_stoken ("+"); }
| OPERATOR '-'
| BLOCKNAME { $$ = $1.stoken; }
| TYPENAME { $$ = $1.stoken; }
| NAME_OR_INT { $$ = $1.stoken; }
+ | UNKNOWN_CPP_NAME { $$ = $1.stoken; }
| operator { $$ = $1; }
;
VAR_DOMAIN,
&$$.is_a_field_of_this);
}
+ | UNKNOWN_CPP_NAME
;
%%
if (parsed_float)
{
- /* It's a float since it contains a point or an exponent. */
- char *s;
- int num; /* number of tokens scanned by scanf */
- char saved_char;
-
/* If it ends at "df", "dd" or "dl", take it as type of decimal floating
point. Return DECFLOAT. */
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)
- 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);
+ if (! parse_c_float (parse_gdbarch, p, len,
+ &putithere->typed_val_float.dval,
+ &putithere->typed_val_float.type))
+ return ERROR;
return FLOAT;
}
if (c != 'l' && c != 'u' && n != 0)
{
if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
- error ("Numeric constant too large.");
+ error (_("Numeric constant too large."));
}
prevn = n;
}
if (*tokptr != quote)
{
if (quote == '"')
- error ("Unterminated string in expression.");
+ error (_("Unterminated string in expression."));
else
- error ("Unmatched single quote.");
+ error (_("Unmatched single quote."));
}
++tokptr;
memcpy (err_copy, tokstart, p - tokstart);
err_copy[p - tokstart] = 0;
- error ("Invalid number \"%s\".", err_copy);
+ error (_("Invalid number \"%s\"."), err_copy);
}
lexptr = p;
return toktype;
}
+ case '@':
+ {
+ char *p = &tokstart[1];
+ size_t len = strlen ("entry");
+
+ while (isspace (*p))
+ p++;
+ if (strncmp (p, "entry", len) == 0 && !isalnum (p[len])
+ && p[len] != '_')
+ {
+ lexptr = &p[len];
+ return ENTRY;
+ }
+ }
+ /* FALLTHRU */
case '+':
case '-':
case '*':
case '^':
case '~':
case '!':
- case '@':
case '<':
case '>':
case '?':
if (result == CHAR)
{
if (host_len == 0)
- error ("Empty character constant.");
+ error (_("Empty character constant."));
else if (host_len > 2 && c == '\'')
{
++tokstart;
goto tryname;
}
else if (host_len > 1)
- error ("Invalid character constant.");
+ error (_("Invalid character constant."));
}
return result;
}
if (!(c == '_' || c == '$'
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
/* We must have come across a bad character (e.g. ';'). */
- error ("Invalid character '%c' in expression.", c);
+ error (_("Invalid character '%c' in expression."), c);
/* It's a name. See how long it is. */
namelen = 0;
/* Any other kind of symbol */
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+
+ if (sym == NULL
+ && parse_language->la_language == language_cplus
+ && !is_a_field_of_this
+ && !lookup_minimal_symbol (copy, NULL, NULL))
+ return UNKNOWN_CPP_NAME;
+
return NAME;
}
return NAME;
copy = copy_name (yylval.tsym.stoken);
- new_type = cp_lookup_nested_type (type, copy, block);
+ new_type = cp_lookup_nested_type (yylval.tsym.type, copy, block);
if (new_type == NULL)
/* We know the caller won't expect us to update yylval. */
{
token_and_value cc;
memset (&cc, 0, sizeof (token_and_value));
- if (first_was_coloncolon)
+ if (first_was_coloncolon && first_iter)
{
yylval = cc.value;
return COLONCOLON;
if (prev_lexptr)
lexptr = prev_lexptr;
- error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+ error (_("A %s in expression, near `%s'."), (msg ? msg : "error"), lexptr);
}