/* YACC parser for Go expressions, for GDB.
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of GDB.
#define parse_type(ps) builtin_type (parse_gdbarch (ps))
-/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
- as well as gratuitiously global symbol names, so we can have multiple
- yacc generated parsers in gdb. Note that these are only the variables
- produced by yacc. If other parser generators (bison, byacc, etc) produce
- additional global names that conflict at link time, then those parser
- generators need to be fixed instead of adding those names to this list. */
-
-#define yymaxdepth go_maxdepth
-#define yyparse go_parse_internal
-#define yylex go_lex
-#define yyerror go_error
-#define yylval go_lval
-#define yychar go_char
-#define yydebug go_debug
-#define yypact go_pact
-#define yyr1 go_r1
-#define yyr2 go_r2
-#define yydef go_def
-#define yychk go_chk
-#define yypgo go_pgo
-#define yyact go_act
-#define yyexca go_exca
-#define yyerrflag go_errflag
-#define yynerrs go_nerrs
-#define yyps go_ps
-#define yypv go_pv
-#define yys go_s
-#define yy_yys go_yys
-#define yystate go_state
-#define yytmp go_tmp
-#define yyv go_v
-#define yy_yyv go_yyv
-#define yyval go_val
-#define yylloc go_lloc
-#define yyreds go_reds /* With YYDEBUG defined */
-#define yytoks go_toks /* With YYDEBUG defined */
-#define yyname go_name /* With YYDEBUG defined */
-#define yyrule go_rule /* With YYDEBUG defined */
-#define yylhs go_yylhs
-#define yylen go_yylen
-#define yydefred go_yydefred
-#define yydgoto go_yydgoto
-#define yysindex go_yysindex
-#define yyrindex go_yyrindex
-#define yygindex go_yygindex
-#define yytable go_yytable
-#define yycheck go_yycheck
-
-#ifndef YYDEBUG
-#define YYDEBUG 1 /* Default to yydebug support */
-#endif
-
-#define YYFPRINTF parser_fprintf
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
+ etc). */
+#define GDB_YY_REMAP_PREFIX go_
+#include "yy-remap.h"
/* The state of the parser, used internally when we are parsing the
expression. */
static int yylex (void);
-void yyerror (char *);
+void yyerror (const char *);
%}
struct type *type;
} typed_val_int;
struct {
- DOUBLEST dval;
+ gdb_byte val[16];
struct type *type;
} typed_val_float;
struct stoken sval;
/* YYSTYPE gets defined by %union. */
static int parse_number (struct parser_state *,
const char *, int, int, YYSTYPE *);
-static int parse_go_float (struct gdbarch *gdbarch, const char *p, int len,
- DOUBLEST *d, struct type **t);
%}
%type <voidval> exp exp1 type_exp start variable lcurly
exp : FLOAT
- { write_exp_elt_opcode (pstate, OP_DOUBLE);
+ { write_exp_elt_opcode (pstate, OP_FLOAT);
write_exp_elt_type (pstate, $1.type);
- write_exp_elt_dblcst (pstate, $1.dval);
- write_exp_elt_opcode (pstate, OP_DOUBLE); }
+ write_exp_elt_floatcst (pstate, $1.val);
+ write_exp_elt_opcode (pstate, OP_FLOAT); }
;
exp : variable
write_exp_elt_type
(pstate,
parse_type (pstate)->builtin_unsigned_int);
- CHECK_TYPEDEF ($3);
+ $3 = check_typedef ($3);
write_exp_elt_longcst (pstate,
(LONGEST) TYPE_LENGTH ($3));
write_exp_elt_opcode (pstate, OP_LONG);
vec->type = $1.type;
vec->length = $1.length;
- vec->ptr = malloc ($1.length + 1);
+ vec->ptr = (char *) malloc ($1.length + 1);
memcpy (vec->ptr, $1.ptr, $1.length + 1);
}
for convenience. */
char *p;
++$$.len;
- $$.tokens = realloc ($$.tokens,
- $$.len * sizeof (struct typed_stoken));
+ $$.tokens = XRESIZEVEC (struct typed_stoken,
+ $$.tokens, $$.len);
- p = malloc ($3.length + 1);
+ p = (char *) malloc ($3.length + 1);
memcpy (p, $3.ptr, $3.length + 1);
$$.tokens[$$.len - 1].type = $3.type;
;
variable: name_not_typename ENTRY
- { struct symbol *sym = $1.sym;
+ { struct symbol *sym = $1.sym.symbol;
if (sym == NULL
|| !SYMBOL_IS_ARGUMENT (sym)
;
variable: name_not_typename
- { struct symbol *sym = $1.sym;
+ { struct block_symbol sym = $1.sym;
- if (sym)
+ if (sym.symbol)
{
- if (symbol_read_needs_frame (sym))
- {
- if (innermost_block == 0
- || contained_in (block_found,
- innermost_block))
- innermost_block = block_found;
- }
+ if (symbol_read_needs_frame (sym.symbol))
+ innermost_block.update (sym);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
- /* We want to use the selected frame, not
- another more inner frame which happens to
- be in the same block. */
- write_exp_elt_block (pstate, NULL);
- write_exp_elt_sym (pstate, sym);
+ write_exp_elt_block (pstate, sym.block);
+ write_exp_elt_sym (pstate, sym.symbol);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
}
else if ($1.is_a_field_of_this)
%%
-/* Wrapper on parse_c_float to get the type right for Go. */
-
-static int
-parse_go_float (struct gdbarch *gdbarch, const char *p, int len,
- DOUBLEST *d, struct type **t)
-{
- int result = parse_c_float (gdbarch, p, len, d, t);
- const struct builtin_type *builtin_types = builtin_type (gdbarch);
- const struct builtin_go_type *builtin_go_types = builtin_go_type (gdbarch);
-
- if (*t == builtin_types->builtin_float)
- *t = builtin_go_types->builtin_float32;
- else if (*t == builtin_types->builtin_double)
- *t = builtin_go_types->builtin_float64;
-
- return result;
-}
-
/* Take care of parsing a number (anything that starts with a digit).
Set yylval and return the token type; update lexptr.
LEN is the number of characters in it. */
if (parsed_float)
{
- if (! parse_go_float (parse_gdbarch (par_state), p, len,
- &putithere->typed_val_float.dval,
- &putithere->typed_val_float.type))
- return ERROR;
+ const struct builtin_go_type *builtin_go_types
+ = builtin_go_type (parse_gdbarch (par_state));
+
+ /* Handle suffixes: 'f' for float32, 'l' for long double.
+ FIXME: This appears to be an extension -- do we want this? */
+ if (len >= 1 && tolower (p[len - 1]) == 'f')
+ {
+ putithere->typed_val_float.type
+ = builtin_go_types->builtin_float32;
+ len--;
+ }
+ else if (len >= 1 && tolower (p[len - 1]) == 'l')
+ {
+ putithere->typed_val_float.type
+ = parse_type (par_state)->builtin_long_double;
+ len--;
+ }
+ /* Default type for floating-point literals is float64. */
+ else
+ {
+ putithere->typed_val_float.type
+ = builtin_go_types->builtin_float64;
+ }
+
+ if (!parse_float (p, len,
+ putithere->typed_val_float.type,
+ putithere->typed_val_float.val))
+ return ERROR;
return FLOAT;
}
++tokptr;
value->type = C_STRING | (quote == '\'' ? C_CHAR : 0); /*FIXME*/
- value->ptr = obstack_base (&tempbuf);
+ value->ptr = (char *) obstack_base (&tempbuf);
value->length = obstack_object_size (&tempbuf);
*outptr = tokptr;
struct token
{
- char *operator;
+ const char *oper;
int token;
enum exp_opcode opcode;
};
tokstart = lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
- if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
+ if (strncmp (tokstart, tokentab3[i].oper, 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 (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
+ if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
{
lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
/* Catch specific keywords. */
copy = copy_name (yylval.sval);
for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++)
- if (strcmp (copy, ident_tokens[i].operator) == 0)
+ if (strcmp (copy, ident_tokens[i].oper) == 0)
{
/* It is ok to always set this, even though we don't always
strictly need to. */
/* Temporary storage for yylex; this holds symbol names as they are
built up. */
-static struct obstack name_obstack;
+static auto_obstack name_obstack;
/* Build "package.name" in name_obstack.
For convenience of the caller, the name is NUL-terminated,
{
struct stoken result;
- obstack_free (&name_obstack, obstack_base (&name_obstack));
+ name_obstack.clear ();
obstack_grow (&name_obstack, package, package_len);
obstack_grow_str (&name_obstack, ".");
obstack_grow (&name_obstack, name, name_len);
obstack_grow (&name_obstack, "", 1);
- result.ptr = obstack_base (&name_obstack);
+ result.ptr = (char *) obstack_base (&name_obstack);
result.length = obstack_object_size (&name_obstack) - 1;
return result;
struct symbol *sym;
struct field_of_this_result is_a_field_of_this;
- sym = lookup_symbol (name, block, STRUCT_DOMAIN, &is_a_field_of_this);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, &is_a_field_of_this).symbol;
if (sym
&& SYMBOL_CLASS (sym) == LOC_TYPEDEF
classify_packaged_name (const struct block *block)
{
char *copy;
- struct symbol *sym;
+ struct block_symbol sym;
struct field_of_this_result is_a_field_of_this;
copy = copy_name (yylval.sval);
sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this);
- if (sym)
+ if (sym.symbol)
{
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
classify_name (struct parser_state *par_state, const struct block *block)
{
struct type *type;
- struct symbol *sym;
+ struct block_symbol sym;
char *copy;
struct field_of_this_result is_a_field_of_this;
sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this);
- if (sym)
+ if (sym.symbol)
{
yylval.ssym.sym = sym;
yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
xfree (current_package_name);
sym = lookup_symbol (sval.ptr, block, VAR_DOMAIN,
&is_a_field_of_this);
- if (sym)
+ if (sym.symbol)
{
yylval.ssym.stoken = sval;
yylval.ssym.sym = sym;
0, &newlval);
if (hextype == INT)
{
- yylval.ssym.sym = NULL;
+ yylval.ssym.sym.symbol = NULL;
+ yylval.ssym.sym.block = NULL;
yylval.ssym.is_a_field_of_this = 0;
return NAME_OR_INT;
}
}
- yylval.ssym.sym = NULL;
+ yylval.ssym.sym.symbol = NULL;
+ yylval.ssym.sym.block = NULL;
yylval.ssym.is_a_field_of_this = 0;
return NAME;
}
int
go_parse (struct parser_state *par_state)
{
- int result;
- struct cleanup *back_to;
-
/* Setting up the parser state. */
+ scoped_restore pstate_restore = make_scoped_restore (&pstate);
gdb_assert (par_state != NULL);
pstate = par_state;
- back_to = make_cleanup (null_cleanup, NULL);
-
- make_cleanup_restore_integer (&yydebug);
- make_cleanup_clear_parser_state (&pstate);
- yydebug = parser_debug;
+ scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+ parser_debug);
/* Initialize some state used by the lexer. */
last_was_structop = 0;
VEC_free (token_and_value, token_fifo);
popping = 0;
- obstack_init (&name_obstack);
- make_cleanup_obstack_free (&name_obstack);
+ name_obstack.clear ();
- result = yyparse ();
- do_cleanups (back_to);
- return result;
+ return yyparse ();
}
void
-yyerror (char *msg)
+yyerror (const char *msg)
{
if (prev_lexptr)
lexptr = prev_lexptr;