/* YACC parser for Go expressions, for GDB.
- Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "charset.h"
#include "block.h"
-#define parse_type(ps) builtin_type (parse_gdbarch (ps))
+#define parse_type(ps) builtin_type (ps->gdbarch ())
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
etc). */
;
exp : exp '.' name_not_typename COMPLETE
- { mark_struct_expression (pstate);
+ { pstate->mark_struct_expression ();
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
write_exp_string (pstate, $3.stoken);
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
exp : exp '.' COMPLETE
{ struct stoken s;
- mark_struct_expression (pstate);
+ pstate->mark_struct_expression ();
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
s.ptr = "";
s.length = 0;
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
- { start_arglist (); }
+ { pstate->start_arglist (); }
arglist ')' %prec LEFT_ARROW
{ write_exp_elt_opcode (pstate, OP_FUNCALL);
write_exp_elt_longcst (pstate,
- (LONGEST) end_arglist ());
+ pstate->end_arglist ());
write_exp_elt_opcode (pstate, OP_FUNCALL); }
;
lcurly : '{'
- { start_arglist (); }
+ { pstate->start_arglist (); }
;
arglist :
;
arglist : exp
- { arglist_len = 1; }
+ { pstate->arglist_len = 1; }
;
arglist : arglist ',' exp %prec ABOVE_COMMA
- { arglist_len++; }
+ { pstate->arglist_len++; }
;
rcurly : '}'
- { $$ = end_arglist () - 1; }
+ { $$ = pstate->end_arglist () - 1; }
;
exp : lcurly type rcurly exp %prec UNARY
|| !symbol_read_needs_frame (sym))
error (_("@entry can be used only for function "
"parameters, not for \"%s\""),
- copy_name ($1.stoken));
+ copy_name ($1.stoken).c_str ());
write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE);
write_exp_elt_sym (pstate, sym);
if (sym.symbol)
{
if (symbol_read_needs_frame (sym.symbol))
- innermost_block.update (sym);
+ pstate->block_tracker->update (sym);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
write_exp_elt_block (pstate, sym.block);
else
{
struct bound_minimal_symbol msymbol;
- char *arg = copy_name ($1.stoken);
+ std::string arg = copy_name ($1.stoken);
msymbol =
- lookup_bound_minimal_symbol (arg);
+ lookup_bound_minimal_symbol (arg.c_str ());
if (msymbol.minsym != NULL)
write_exp_msymbol (pstate, msymbol);
else if (!have_full_symbols ()
"Use the \"file\" command."));
else
error (_("No symbol \"%s\" in current context."),
- copy_name ($1.stoken));
+ arg.c_str ());
}
}
;
expression_context_block); }
*/
| BYTE_KEYWORD
- { $$ = builtin_go_type (parse_gdbarch (pstate))
+ { $$ = builtin_go_type (pstate->gdbarch ())
->builtin_uint8; }
;
if (parsed_float)
{
const struct builtin_go_type *builtin_go_types
- = builtin_go_type (parse_gdbarch (par_state));
+ = builtin_go_type (par_state->gdbarch ());
/* Handle suffixes: 'f' for float32, 'l' for long double.
FIXME: This appears to be an extension -- do we want this? */
un = (ULONGEST)n >> 2;
if (long_p == 0
- && (un >> (gdbarch_int_bit (parse_gdbarch (par_state)) - 2)) == 0)
+ && (un >> (gdbarch_int_bit (par_state->gdbarch ()) - 2)) == 0)
{
high_bit
- = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch (par_state)) - 1);
+ = ((ULONGEST)1) << (gdbarch_int_bit (par_state->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,
signed_type = parse_type (par_state)->builtin_int;
}
else if (long_p <= 1
- && (un >> (gdbarch_long_bit (parse_gdbarch (par_state)) - 2)) == 0)
+ && (un >> (gdbarch_long_bit (par_state->gdbarch ()) - 2)) == 0)
{
high_bit
- = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch (par_state)) - 1);
+ = ((ULONGEST)1) << (gdbarch_long_bit (par_state->gdbarch ()) - 1);
unsigned_type = parse_type (par_state)->builtin_unsigned_long;
signed_type = parse_type (par_state)->builtin_long;
}
{
int shift;
if (sizeof (ULONGEST) * HOST_CHAR_BIT
- < gdbarch_long_long_bit (parse_gdbarch (par_state)))
+ < gdbarch_long_long_bit (par_state->gdbarch ()))
/* A long long does not fit in a LONGEST. */
shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
else
- shift = (gdbarch_long_long_bit (parse_gdbarch (par_state)) - 1);
+ shift = (gdbarch_long_long_bit (par_state->gdbarch ()) - 1);
high_bit = (ULONGEST) 1 << shift;
unsigned_type = parse_type (par_state)->builtin_unsigned_long_long;
signed_type = parse_type (par_state)->builtin_long_long;
do field name completion. */
static int last_was_structop;
+/* Depth of parentheses. */
+static int paren_depth;
+
/* Read one token, getting characters through lexptr. */
static int
unsigned int i;
const char *tokstart;
int saw_structop = last_was_structop;
- char *copy;
last_was_structop = 0;
retry:
- prev_lexptr = lexptr;
+ par_state->prev_lexptr = par_state->lexptr;
- tokstart = lexptr;
+ tokstart = par_state->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].oper, 3) == 0)
{
- lexptr += 3;
+ par_state->lexptr += 3;
yylval.opcode = tokentab3[i].opcode;
return tokentab3[i].token;
}
for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
{
- lexptr += 2;
+ par_state->lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
/* NOTE: -> doesn't exist in Go, so we don't need to watch for
setting last_was_structop here. */
case ' ':
case '\t':
case '\n':
- lexptr++;
+ par_state->lexptr++;
goto retry;
case '[':
case '(':
paren_depth++;
- lexptr++;
+ par_state->lexptr++;
return c;
case ']':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ par_state->lexptr++;
return c;
case ',':
- if (comma_terminates
+ if (pstate->comma_terminates
&& paren_depth == 0)
return 0;
- lexptr++;
+ par_state->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (par_state->lexptr[1] < '0' || par_state->lexptr[1] > '9')
{
- if (parse_completion)
+ if (pstate->parse_completion)
last_was_structop = 1;
goto symbol; /* Nope, must be a symbol. */
}
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ par_state->lexptr = p;
return toktype;
}
if (strncmp (p, "entry", len) == 0 && !isalnum (p[len])
&& p[len] != '_')
{
- lexptr = &p[len];
+ par_state->lexptr = &p[len];
return ENTRY;
}
}
case '{':
case '}':
symbol:
- lexptr++;
+ par_state->lexptr++;
return c;
case '\'':
case '`':
{
int host_len;
- int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval,
- &host_len);
+ int result = parse_string_or_char (tokstart, &par_state->lexptr,
+ &yylval.tsval, &host_len);
if (result == CHAR)
{
if (host_len == 0)
else if (host_len > 2 && c == '\'')
{
++tokstart;
- namelen = lexptr - tokstart - 1;
+ namelen = par_state->lexptr - tokstart - 1;
goto tryname;
}
else if (host_len > 1)
return 0;
}
- lexptr += namelen;
+ par_state->lexptr += namelen;
tryname:
yylval.sval.length = namelen;
/* Catch specific keywords. */
- copy = copy_name (yylval.sval);
+ std::string copy = copy_name (yylval.sval);
for (i = 0; i < sizeof (ident_tokens) / sizeof (ident_tokens[0]); i++)
- if (strcmp (copy, ident_tokens[i].oper) == 0)
+ if (copy == ident_tokens[i].oper)
{
/* It is ok to always set this, even though we don't always
strictly need to. */
if (*tokstart == '$')
return DOLLAR_VARIABLE;
- if (parse_completion && *lexptr == '\0')
+ if (pstate->parse_completion && *par_state->lexptr == '\0')
saw_name_at_eof = 1;
return NAME;
}
/* An object of this type is pushed on a FIFO by the "outer" lexer. */
-typedef struct
+struct token_and_value
{
int token;
YYSTYPE value;
-} token_and_value;
-
-DEF_VEC_O (token_and_value);
+};
/* A FIFO of tokens that have been read but not yet returned to the
parser. */
-static VEC (token_and_value) *token_fifo;
+static std::vector<token_and_value> token_fifo;
/* Non-zero if the lexer should return tokens from the FIFO. */
static int popping;
static int
classify_unsafe_function (struct stoken function_name)
{
- char *copy = copy_name (function_name);
+ std::string copy = copy_name (function_name);
- if (strcmp (copy, "Sizeof") == 0)
+ if (copy == "Sizeof")
{
yylval.sval = function_name;
return SIZEOF_KEYWORD;
}
- error (_("Unknown function in `unsafe' package: %s"), copy);
+ error (_("Unknown function in `unsafe' package: %s"), copy.c_str ());
}
/* Classify token(s) "name1.name2" where name1 is known to be a package.
static int
classify_packaged_name (const struct block *block)
{
- char *copy;
struct block_symbol sym;
struct field_of_this_result is_a_field_of_this;
- copy = copy_name (yylval.sval);
+ std::string copy = copy_name (yylval.sval);
- sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this);
+ sym = lookup_symbol (copy.c_str (), block, VAR_DOMAIN, &is_a_field_of_this);
if (sym.symbol)
{
{
struct type *type;
struct block_symbol sym;
- char *copy;
struct field_of_this_result is_a_field_of_this;
- copy = copy_name (yylval.sval);
+ std::string copy = copy_name (yylval.sval);
/* Try primitive types first so they win over bad/weird debug info. */
- type = language_lookup_primitive_type (parse_language (par_state),
- parse_gdbarch (par_state),
- copy);
+ type = language_lookup_primitive_type (par_state->language (),
+ par_state->gdbarch (),
+ copy.c_str ());
if (type != NULL)
{
/* NOTE: We take advantage of the fact that yylval coming in was a
/* TODO: What about other types? */
- sym = lookup_symbol (copy, block, VAR_DOMAIN, &is_a_field_of_this);
+ sym = lookup_symbol (copy.c_str (), block, VAR_DOMAIN, &is_a_field_of_this);
if (sym.symbol)
{
struct stoken sval =
build_packaged_name (current_package_name,
strlen (current_package_name),
- copy, strlen (copy));
+ copy.c_str (), copy.size ());
xfree (current_package_name);
sym = lookup_symbol (sval.ptr, block, VAR_DOMAIN,
|| (copy[0] >= 'A' && copy[0] < 'A' + input_radix - 10))
{
YYSTYPE newlval; /* Its value is ignored. */
- int hextype = parse_number (par_state, copy, yylval.sval.length,
- 0, &newlval);
+ int hextype = parse_number (par_state, copy.c_str (),
+ yylval.sval.length, 0, &newlval);
if (hextype == INT)
{
yylval.ssym.sym.symbol = NULL;
{
token_and_value current, next;
- if (popping && !VEC_empty (token_and_value, token_fifo))
+ if (popping && !token_fifo.empty ())
{
- token_and_value tv = *VEC_index (token_and_value, token_fifo, 0);
- VEC_ordered_remove (token_and_value, token_fifo, 0);
+ token_and_value tv = token_fifo[0];
+ token_fifo.erase (token_fifo.begin ());
yylval = tv.value;
/* There's no need to fall through to handle package.name
as that can never happen here. In theory. */
if (name2.token == NAME)
{
/* Ok, we have "name1 . name2". */
- char *copy;
+ std::string copy = copy_name (current.value.sval);
- copy = copy_name (current.value.sval);
-
- if (strcmp (copy, "unsafe") == 0)
+ if (copy == "unsafe")
{
popping = 1;
return classify_unsafe_function (name2.value.sval);
}
- if (package_name_p (copy, expression_context_block))
+ if (package_name_p (copy.c_str (), pstate->expression_context_block))
{
popping = 1;
yylval.sval = build_packaged_name (current.value.sval.ptr,
current.value.sval.length,
name2.value.sval.ptr,
name2.value.sval.length);
- return classify_packaged_name (expression_context_block);
+ return classify_packaged_name (pstate->expression_context_block);
}
}
- VEC_safe_push (token_and_value, token_fifo, &next);
- VEC_safe_push (token_and_value, token_fifo, &name2);
+ token_fifo.push_back (next);
+ token_fifo.push_back (name2);
}
else
- {
- VEC_safe_push (token_and_value, token_fifo, &next);
- }
+ token_fifo.push_back (next);
/* If we arrive here we don't have a package-qualified name. */
popping = 1;
yylval = current.value;
- return classify_name (pstate, expression_context_block);
+ return classify_name (pstate, pstate->expression_context_block);
}
int
/* Initialize some state used by the lexer. */
last_was_structop = 0;
saw_name_at_eof = 0;
+ paren_depth = 0;
- VEC_free (token_and_value, token_fifo);
+ token_fifo.clear ();
popping = 0;
name_obstack.clear ();
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}