/* YACC parser for D expressions, for GDB.
- Copyright (C) 2014-2019 Free Software Foundation, Inc.
+ Copyright (C) 2014-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "charset.h"
#include "block.h"
+#include "type-stack.h"
#define parse_type(ps) builtin_type (ps->gdbarch ())
#define parse_d_type(ps) builtin_d_type (ps->gdbarch ())
static struct parser_state *pstate = NULL;
+/* The current type stack. */
+static struct type_stack *type_stack;
+
int yyparse (void);
static int yylex (void);
PrimaryExpression
| PostfixExpression '.' COMPLETE
{ struct stoken s;
- mark_struct_expression (pstate);
+ pstate->mark_struct_expression ();
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
s.ptr = "";
s.length = 0;
write_exp_string (pstate, $3);
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
| PostfixExpression '.' IDENTIFIER COMPLETE
- { mark_struct_expression (pstate);
+ { pstate->mark_struct_expression ();
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
write_exp_string (pstate, $3);
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
ArgumentList:
AssignExpression
- { arglist_len = 1; }
+ { pstate->arglist_len = 1; }
| ArgumentList ',' AssignExpression
- { arglist_len++; }
+ { pstate->arglist_len++; }
;
ArgumentList_opt:
/* EMPTY */
- { arglist_len = 0; }
+ { pstate->arglist_len = 0; }
| ArgumentList
;
CallExpression:
PostfixExpression '('
- { start_arglist (); }
+ { pstate->start_arglist (); }
ArgumentList_opt ')'
{ write_exp_elt_opcode (pstate, OP_FUNCALL);
- write_exp_elt_longcst (pstate, (LONGEST) end_arglist ());
+ write_exp_elt_longcst (pstate, pstate->end_arglist ());
write_exp_elt_opcode (pstate, OP_FUNCALL); }
;
IndexExpression:
PostfixExpression '[' ArgumentList ']'
- { if (arglist_len > 0)
+ { if (pstate->arglist_len > 0)
{
write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT);
- write_exp_elt_longcst (pstate, (LONGEST) arglist_len);
+ write_exp_elt_longcst (pstate, pstate->arglist_len);
write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT);
}
else
{ /* Do nothing. */ }
| IdentifierExp
{ struct bound_minimal_symbol msymbol;
- char *copy = copy_name ($1);
+ std::string copy = copy_name ($1);
struct field_of_this_result is_a_field_of_this;
struct block_symbol sym;
/* Handle VAR, which could be local or global. */
- sym = lookup_symbol (copy, pstate->expression_context_block,
+ sym = lookup_symbol (copy.c_str (),
+ pstate->expression_context_block,
VAR_DOMAIN, &is_a_field_of_this);
if (sym.symbol && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF)
{
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);
write_exp_elt_sym (pstate, sym.symbol);
{
/* It hangs off of `this'. Must not inadvertently convert from a
method call to data ref. */
- innermost_block.update (sym);
+ pstate->block_tracker->update (sym);
write_exp_elt_opcode (pstate, OP_THIS);
write_exp_elt_opcode (pstate, OP_THIS);
write_exp_elt_opcode (pstate, STRUCTOP_PTR);
else
{
/* Lookup foreign name in global static symbols. */
- msymbol = lookup_bound_minimal_symbol (copy);
+ msymbol = lookup_bound_minimal_symbol (copy.c_str ());
if (msymbol.minsym != NULL)
write_exp_msymbol (pstate, msymbol);
else if (!have_full_symbols () && !have_partial_symbols ())
error (_("No symbol table is loaded. Use the \"file\" command"));
else
- error (_("No symbol \"%s\" in current context."), copy);
+ error (_("No symbol \"%s\" in current context."),
+ copy.c_str ());
}
}
| TypeExp '.' IdentifierExp
/* Check if the qualified name is in the global
context. However if the symbol has not already
been resolved, it's not likely to be found. */
- if (TYPE_CODE (type) == TYPE_CODE_MODULE)
+ if (type->code () == TYPE_CODE_MODULE)
{
struct bound_minimal_symbol msymbol;
struct block_symbol sym;
ArrayLiteral:
'[' ArgumentList_opt ']'
- { $$ = arglist_len; }
+ { $$ = pstate->arglist_len; }
;
IdentifierExp:
write_exp_elt_type (pstate, $1);
write_exp_elt_opcode (pstate, OP_TYPE); }
| BasicType BasicType2
- { $$ = follow_types ($1);
+ { $$ = type_stack->follow_types ($1);
write_exp_elt_opcode (pstate, OP_TYPE);
write_exp_elt_type (pstate, $$);
write_exp_elt_opcode (pstate, OP_TYPE);
BasicType2:
'*'
- { push_type (tp_pointer); }
+ { type_stack->push (tp_pointer); }
| '*' BasicType2
- { push_type (tp_pointer); }
+ { type_stack->push (tp_pointer); }
| '[' INTEGER_LITERAL ']'
- { push_type_int ($2.val);
- push_type (tp_array); }
+ { type_stack->push ($2.val);
+ type_stack->push (tp_array); }
| '[' INTEGER_LITERAL ']' BasicType2
- { push_type_int ($2.val);
- push_type (tp_array); }
+ { type_stack->push ($2.val);
+ type_stack->push (tp_array); }
;
BasicType:
static int
type_aggregate_p (struct type *type)
{
- return (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION
- || TYPE_CODE (type) == TYPE_CODE_MODULE
- || (TYPE_CODE (type) == TYPE_CODE_ENUM
+ return (type->code () == TYPE_CODE_STRUCT
+ || type->code () == TYPE_CODE_UNION
+ || type->code () == TYPE_CODE_MODULE
+ || (type->code () == TYPE_CODE_ENUM
&& TYPE_DECLARED_CLASS (type)));
}
unsigned int i;
const char *tokstart;
int saw_structop = last_was_structop;
- char *copy;
last_was_structop = 0;
/* Might be a floating point number. */
if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
{
- if (parse_completion)
+ if (pstate->parse_completion)
last_was_structop = 1;
goto symbol; /* Nope, must be a symbol. */
}
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. */
yylval.tsym.type
= language_lookup_primitive_type (par_state->language (),
- par_state->gdbarch (), copy);
+ par_state->gdbarch (), copy.c_str ());
if (yylval.tsym.type != NULL)
return TYPENAME;
return NAME_OR_INT;
}
- if (parse_completion && *pstate->lexptr == '\0')
+ if (pstate->parse_completion && *pstate->lexptr == '\0')
saw_name_at_eof = 1;
return IDENTIFIER;
classify_name (struct parser_state *par_state, const struct block *block)
{
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);
- 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 && SYMBOL_CLASS (sym.symbol) == LOC_TYPEDEF)
{
yylval.tsym.type = SYMBOL_TYPE (sym.symbol);
else if (sym.symbol == NULL)
{
/* Look-up first for a module name, then a type. */
- sym = lookup_symbol (copy, block, MODULE_DOMAIN, NULL);
+ sym = lookup_symbol (copy.c_str (), block, MODULE_DOMAIN, NULL);
if (sym.symbol == NULL)
- sym = lookup_symbol (copy, block, STRUCT_DOMAIN, NULL);
+ sym = lookup_symbol (copy.c_str (), block, STRUCT_DOMAIN, NULL);
if (sym.symbol != NULL)
{
const struct block *block, struct type *context)
{
struct type *type;
- char *copy;
if (context == NULL)
return classify_name (par_state, block);
if (!type_aggregate_p (type))
return ERROR;
- copy = copy_name (yylval.ssym.stoken);
- yylval.ssym.sym = d_lookup_nested_symbol (type, copy, block);
+ std::string copy = copy_name (yylval.ssym.stoken);
+ yylval.ssym.sym = d_lookup_nested_symbol (type, copy.c_str (), block);
if (yylval.ssym.sym.symbol == NULL)
return ERROR;
scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
parser_debug);
+ struct type_stack stack;
+ scoped_restore restore_type_stack = make_scoped_restore (&type_stack,
+ &stack);
+
/* Initialize some state used by the lexer. */
last_was_structop = 0;
saw_name_at_eof = 0;