/* 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, 2011
- 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 */
/* %type <bval> block */
/* Fancy type parsing. */
-%type <voidval> func_mod direct_abs_decl abs_decl
+%type <voidval> func_mod direct_abs_decl abs_decl ptr_operator
%type <tval> ptype
%type <lval> array_mod
+%type <tval> conversion_type_id
%token <typed_val_int> INT
%token <typed_val_float> FLOAT
%token <tsval> STRING
%token <tsval> CHAR
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
-%token <ssym> ENTRY
%token <ssym> UNKNOWN_CPP_NAME
%token <voidval> COMPLETE
%token <tsym> TYPENAME
%type <ssym> name_not_typename
%type <tsym> typename
-/* It is UNKNOWN_CPP_NAME or ENTRY, depending on the context. */
-%type <ssym> unknown_cpp_name
-
/* A NAME_OR_INT is a symbol which is not known in the symbol table,
but which would parse as a valid number in the current input radix.
E.g. "c" when input_radix==16. Depending on the parse, it will be
%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 '('
+exp : UNKNOWN_CPP_NAME '('
{
/* This could potentially be a an argument defined
lookup function (Koenig). */
}
;
-unknown_cpp_name : UNKNOWN_CPP_NAME
- | ENTRY
- ;
-
lcurly : '{'
{ start_arglist (); }
;
$$ = SYMBOL_BLOCK_VALUE (tem); }
;
-variable: name_not_typename '@' ENTRY
+variable: name_not_typename ENTRY
{ struct symbol *sym = $1.sym;
if (sym == NULL || !SYMBOL_IS_ARGUMENT (sym)
if (sym == 0)
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. */
;
space_identifier : '@' NAME
- { push_type_address_space (copy_name ($2.stoken));
- push_type (tp_space_identifier);
- }
+ { insert_type_address_space (copy_name ($2.stoken)); }
;
const_or_volatile: const_or_volatile_noopt
|
;
-abs_decl: '*'
- { push_type (tp_pointer); $$ = 0; }
- | '*' abs_decl
- { push_type (tp_pointer); $$ = $2; }
+ptr_operator:
+ ptr_operator '*'
+ { insert_type (tp_pointer); }
+ const_or_volatile_or_space_identifier
+ { $$ = 0; }
+ | '*'
+ { insert_type (tp_pointer); }
+ const_or_volatile_or_space_identifier
+ { $$ = 0; }
| '&'
- { push_type (tp_reference); $$ = 0; }
- | '&' abs_decl
- { push_type (tp_reference); $$ = $2; }
+ { insert_type (tp_reference); $$ = 0; }
+ | '&' ptr_operator
+ { insert_type (tp_reference); $$ = 0; }
+ ;
+
+abs_decl: ptr_operator direct_abs_decl
+ | ptr_operator
| direct_abs_decl
;
;
ptype : typebase
- | ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier
+ | ptype abs_decl
{ $$ = follow_types ($1); }
;
+conversion_type_id: typebase conversion_declarator
+ { $$ = follow_types ($1); }
+ ;
+
+conversion_declarator: /* Nothing. */
+ | ptr_operator conversion_declarator
+ ;
+
const_and_volatile: CONST_KEYWORD VOLATILE_KEYWORD
| VOLATILE_KEYWORD CONST_KEYWORD
;
const_or_volatile_noopt: const_and_volatile
- { push_type (tp_const);
- push_type (tp_volatile);
+ { insert_type (tp_const);
+ insert_type (tp_volatile);
}
| CONST_KEYWORD
- { push_type (tp_const); }
+ { insert_type (tp_const); }
| VOLATILE_KEYWORD
- { push_type (tp_volatile); }
+ { insert_type (tp_volatile); }
;
operator: OPERATOR NEW
{ $$ = operator_stoken ("()"); }
| OPERATOR '[' ']'
{ $$ = operator_stoken ("[]"); }
- | OPERATOR ptype
+ | OPERATOR conversion_type_id
{ char *name;
long length;
struct ui_file *buf = mem_fileopen ();
| TYPENAME { $$ = $1.stoken; }
| NAME_OR_INT { $$ = $1.stoken; }
| UNKNOWN_CPP_NAME { $$ = $1.stoken; }
- | ENTRY { $$ = $1.stoken; }
| operator { $$ = $1; }
;
name_not_typename : NAME
| BLOCKNAME
- | ENTRY
/* These would be useful if name_not_typename was useful, but it is just
a fake for "variable", so these cause reduce/reduce conflicts because
the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
if (parsed_float)
{
- const char *suffix;
- int suffix_len;
-
/* If it ends at "df", "dd" or "dl", take it as type of decimal floating
point. Return DECFLOAT. */
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 '?':
/* Like classify_name, but used by the inner loop of the lexer, when a
name might have already been seen. FIRST_NAME is true if the token
- in `yylval' is the first component of a name, false otherwise. If
- this function returns NAME, it might not have updated `yylval'.
- This is ok because the caller only cares about TYPENAME. */
+ in `yylval' is the first component of a name, false otherwise. */
+
static int
classify_inner_name (struct block *block, int first_name)
{
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION
&& TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
- /* We know the caller won't expect us to update yylval. */
- return NAME;
+ return ERROR;
copy = copy_name (yylval.tsym.stoken);
- new_type = cp_lookup_nested_type (yylval.tsym.type, copy, block);
+ yylval.ssym.sym = cp_lookup_nested_symbol (yylval.tsym.type, copy, block);
+ if (yylval.ssym.sym == NULL)
+ return ERROR;
+
+ switch (SYMBOL_CLASS (yylval.ssym.sym))
+ {
+ case LOC_BLOCK:
+ case LOC_LABEL:
+ return ERROR;
- if (new_type == NULL)
- /* We know the caller won't expect us to update yylval. */
- return NAME;
+ case LOC_TYPEDEF:
+ yylval.tsym.type = SYMBOL_TYPE (yylval.ssym.sym);;
+ return TYPENAME;
- yylval.tsym.type = new_type;
- return TYPENAME;
+ default:
+ yylval.ssym.is_a_field_of_this = 0;
+ return NAME;
+ }
+ internal_error (__FILE__, __LINE__, _("not reached"));
}
/* The outer level of a two-level lexer. This calls the inner lexer
current.token = lex_one_token ();
if (current.token == NAME)
current.token = classify_name (expression_context_block);
- if ((current.token == NAME || current.token == UNKNOWN_CPP_NAME)
- && yylval.sval.length == strlen ("entry")
- && strncmp (yylval.sval.ptr, "entry", strlen ("entry")) == 0)
- current.token = ENTRY;
-
if (parse_language->la_language != language_cplus
|| (current.token != TYPENAME && current.token != COLONCOLON))
return current.token;
first_iter);
/* We keep going until we either run out of names, or until
we have a qualified name which is not a type. */
- if (classification != TYPENAME)
+ if (classification != TYPENAME && classification != NAME)
{
/* Push the final component and leave the loop. */
VEC_safe_push (token_and_value, token_fifo, &next);