mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
Move completion parsing to parser_state
This moves the globals and functions related to parsing for completion to parser_state. A new structure is introduced in order to return completion results from the parse back to parse_expression_for_completion. gdb/ChangeLog 2019-04-04 Tom Tromey <tom@tromey.com> * rust-exp.y (rust_parser::lex_identifier, rustyylex) (rust_parser::convert_ast_to_expression, rust_parse) (rust_lex_test_completion, rust_lex_tests): Update. * parser-defs.h (struct expr_completion_state): New. (struct parser_state) <parser_state>: Add completion parameter. <mark_struct_expression, mark_completion_tag>: New methods. <parse_completion, m_completion_state>: New members. (prefixify_expression, null_post_parser): Update. (mark_struct_expression, mark_completion_tag): Don't declare. * parse.c (parse_completion, expout_last_struct) (expout_tag_completion_type, expout_completion_name): Remove globals. (parser_state::mark_struct_expression) (parser_state::mark_completion_tag): Now methods. (prefixify_expression): Add last_struct parameter. (prefixify_subexp): Likewise. (parse_exp_1): Update. (parse_exp_in_context): Add cstate parameter. Update. (parse_expression_for_completion): Create an expr_completion_state. (null_post_parser): Add "completion" parameter. * p-exp.y: Update rules. (yylex): Update. * language.h (struct language_defn) <la_post_parser>: Add "completing" parameter. * go-exp.y: Update rules. (lex_one_token): Update. * expression.h (parse_completion): Don't declare. * d-exp.y: Update rules. (lex_one_token): Update rules. * c-exp.y: Update rules. (lex_one_token): Update. * ada-lang.c (resolve): Add "parse_completion" parameter. (resolve_subexp): Likewise. (ada_resolve_function): Likewise.
This commit is contained in:
parent
43476f0b1b
commit
2a61252965
@ -1,3 +1,41 @@
|
||||
2019-04-04 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* rust-exp.y (rust_parser::lex_identifier, rustyylex)
|
||||
(rust_parser::convert_ast_to_expression, rust_parse)
|
||||
(rust_lex_test_completion, rust_lex_tests): Update.
|
||||
* parser-defs.h (struct expr_completion_state): New.
|
||||
(struct parser_state) <parser_state>: Add completion parameter.
|
||||
<mark_struct_expression, mark_completion_tag>: New methods.
|
||||
<parse_completion, m_completion_state>: New members.
|
||||
(prefixify_expression, null_post_parser): Update.
|
||||
(mark_struct_expression, mark_completion_tag): Don't declare.
|
||||
* parse.c (parse_completion, expout_last_struct)
|
||||
(expout_tag_completion_type, expout_completion_name): Remove
|
||||
globals.
|
||||
(parser_state::mark_struct_expression)
|
||||
(parser_state::mark_completion_tag): Now methods.
|
||||
(prefixify_expression): Add last_struct parameter.
|
||||
(prefixify_subexp): Likewise.
|
||||
(parse_exp_1): Update.
|
||||
(parse_exp_in_context): Add cstate parameter. Update.
|
||||
(parse_expression_for_completion): Create an
|
||||
expr_completion_state.
|
||||
(null_post_parser): Add "completion" parameter.
|
||||
* p-exp.y: Update rules.
|
||||
(yylex): Update.
|
||||
* language.h (struct language_defn) <la_post_parser>: Add
|
||||
"completing" parameter.
|
||||
* go-exp.y: Update rules.
|
||||
(lex_one_token): Update.
|
||||
* expression.h (parse_completion): Don't declare.
|
||||
* d-exp.y: Update rules.
|
||||
(lex_one_token): Update rules.
|
||||
* c-exp.y: Update rules.
|
||||
(lex_one_token): Update.
|
||||
* ada-lang.c (resolve): Add "parse_completion" parameter.
|
||||
(resolve_subexp): Likewise.
|
||||
(ada_resolve_function): Likewise.
|
||||
|
||||
2019-04-04 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* parser-defs.h (struct parser_state) <start_arglist,
|
||||
|
@ -125,7 +125,7 @@ static int num_defns_collected (struct obstack *);
|
||||
static struct block_symbol *defns_collected (struct obstack *, int);
|
||||
|
||||
static struct value *resolve_subexp (expression_up *, int *, int,
|
||||
struct type *);
|
||||
struct type *, int);
|
||||
|
||||
static void replace_operator_with_call (expression_up *, int, int, int,
|
||||
struct symbol *, const struct block *);
|
||||
@ -225,7 +225,7 @@ static int find_struct_field (const char *, struct type *, int,
|
||||
|
||||
static int ada_resolve_function (struct block_symbol *, int,
|
||||
struct value **, int, const char *,
|
||||
struct type *);
|
||||
struct type *, int);
|
||||
|
||||
static int ada_is_direct_array_type (struct type *);
|
||||
|
||||
@ -3220,7 +3220,7 @@ ada_decoded_op_name (enum exp_opcode op)
|
||||
return type is preferred. May change (expand) *EXP. */
|
||||
|
||||
static void
|
||||
resolve (expression_up *expp, int void_context_p)
|
||||
resolve (expression_up *expp, int void_context_p, int parse_completion)
|
||||
{
|
||||
struct type *context_type = NULL;
|
||||
int pc = 0;
|
||||
@ -3228,7 +3228,7 @@ resolve (expression_up *expp, int void_context_p)
|
||||
if (void_context_p)
|
||||
context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
|
||||
|
||||
resolve_subexp (expp, &pc, 1, context_type);
|
||||
resolve_subexp (expp, &pc, 1, context_type, parse_completion);
|
||||
}
|
||||
|
||||
/* Resolve the operator of the subexpression beginning at
|
||||
@ -3242,7 +3242,7 @@ resolve (expression_up *expp, int void_context_p)
|
||||
|
||||
static struct value *
|
||||
resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
struct type *context_type)
|
||||
struct type *context_type, int parse_completion)
|
||||
{
|
||||
int pc = *pos;
|
||||
int i;
|
||||
@ -3267,19 +3267,20 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
else
|
||||
{
|
||||
*pos += 3;
|
||||
resolve_subexp (expp, pos, 0, NULL);
|
||||
resolve_subexp (expp, pos, 0, NULL, parse_completion);
|
||||
}
|
||||
nargs = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
break;
|
||||
|
||||
case UNOP_ADDR:
|
||||
*pos += 1;
|
||||
resolve_subexp (expp, pos, 0, NULL);
|
||||
resolve_subexp (expp, pos, 0, NULL, parse_completion);
|
||||
break;
|
||||
|
||||
case UNOP_QUAL:
|
||||
*pos += 3;
|
||||
resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type));
|
||||
resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type),
|
||||
parse_completion);
|
||||
break;
|
||||
|
||||
case OP_ATR_MODULUS:
|
||||
@ -3310,11 +3311,11 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
struct value *arg1;
|
||||
|
||||
*pos += 1;
|
||||
arg1 = resolve_subexp (expp, pos, 0, NULL);
|
||||
arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion);
|
||||
if (arg1 == NULL)
|
||||
resolve_subexp (expp, pos, 1, NULL);
|
||||
resolve_subexp (expp, pos, 1, NULL, parse_completion);
|
||||
else
|
||||
resolve_subexp (expp, pos, 1, value_type (arg1));
|
||||
resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3402,7 +3403,7 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
|
||||
argvec = XALLOCAVEC (struct value *, nargs + 1);
|
||||
for (i = 0; i < nargs; i += 1)
|
||||
argvec[i] = resolve_subexp (expp, pos, 1, NULL);
|
||||
argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion);
|
||||
argvec[i] = NULL;
|
||||
exp = expp->get ();
|
||||
|
||||
@ -3471,7 +3472,7 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
i = ada_resolve_function
|
||||
(candidates.data (), n_candidates, NULL, 0,
|
||||
SYMBOL_LINKAGE_NAME (exp->elts[pc + 2].symbol),
|
||||
context_type);
|
||||
context_type, parse_completion);
|
||||
if (i < 0)
|
||||
error (_("Could not find a match for %s"),
|
||||
SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
|
||||
@ -3522,7 +3523,7 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
(candidates.data (), n_candidates,
|
||||
argvec, nargs,
|
||||
SYMBOL_LINKAGE_NAME (exp->elts[pc + 5].symbol),
|
||||
context_type);
|
||||
context_type, parse_completion);
|
||||
if (i < 0)
|
||||
error (_("Could not find a match for %s"),
|
||||
SYMBOL_PRINT_NAME (exp->elts[pc + 5].symbol));
|
||||
@ -3566,7 +3567,8 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
|
||||
&candidates);
|
||||
|
||||
i = ada_resolve_function (candidates.data (), n_candidates, argvec,
|
||||
nargs, ada_decoded_op_name (op), NULL);
|
||||
nargs, ada_decoded_op_name (op), NULL,
|
||||
parse_completion);
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
@ -3733,7 +3735,8 @@ return_match (struct type *func_type, struct type *context_type)
|
||||
static int
|
||||
ada_resolve_function (struct block_symbol syms[],
|
||||
int nsyms, struct value **args, int nargs,
|
||||
const char *name, struct type *context_type)
|
||||
const char *name, struct type *context_type,
|
||||
int parse_completion)
|
||||
{
|
||||
int fallback;
|
||||
int k;
|
||||
|
43
gdb/c-exp.y
43
gdb/c-exp.y
@ -364,7 +364,7 @@ exp : exp ARROW field_name
|
||||
;
|
||||
|
||||
exp : exp ARROW field_name COMPLETE
|
||||
{ mark_struct_expression (pstate);
|
||||
{ pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_PTR);
|
||||
write_exp_string (pstate, $3);
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
|
||||
@ -372,7 +372,7 @@ exp : exp ARROW field_name COMPLETE
|
||||
|
||||
exp : exp ARROW COMPLETE
|
||||
{ struct stoken s;
|
||||
mark_struct_expression (pstate);
|
||||
pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_PTR);
|
||||
s.ptr = "";
|
||||
s.length = 0;
|
||||
@ -387,7 +387,7 @@ exp : exp ARROW '~' name
|
||||
;
|
||||
|
||||
exp : exp ARROW '~' name COMPLETE
|
||||
{ mark_struct_expression (pstate);
|
||||
{ pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_PTR);
|
||||
write_destructor_name (pstate, $4);
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
|
||||
@ -412,7 +412,7 @@ exp : exp '.' field_name
|
||||
;
|
||||
|
||||
exp : exp '.' field_name 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); }
|
||||
@ -420,7 +420,7 @@ exp : exp '.' field_name COMPLETE
|
||||
|
||||
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;
|
||||
@ -435,7 +435,7 @@ exp : exp '.' '~' name
|
||||
;
|
||||
|
||||
exp : exp '.' '~' name COMPLETE
|
||||
{ mark_struct_expression (pstate);
|
||||
{ pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
|
||||
write_destructor_name (pstate, $4);
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
|
||||
@ -1406,13 +1406,14 @@ typebase
|
||||
}
|
||||
| STRUCT COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
|
||||
pstate->mark_completion_tag (TYPE_CODE_STRUCT,
|
||||
"", 0);
|
||||
$$ = NULL;
|
||||
}
|
||||
| STRUCT name COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr,
|
||||
$2.length);
|
||||
pstate->mark_completion_tag (TYPE_CODE_STRUCT,
|
||||
$2.ptr, $2.length);
|
||||
$$ = NULL;
|
||||
}
|
||||
| CLASS name
|
||||
@ -1421,13 +1422,14 @@ typebase
|
||||
}
|
||||
| CLASS COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
|
||||
pstate->mark_completion_tag (TYPE_CODE_STRUCT,
|
||||
"", 0);
|
||||
$$ = NULL;
|
||||
}
|
||||
| CLASS name COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr,
|
||||
$2.length);
|
||||
pstate->mark_completion_tag (TYPE_CODE_STRUCT,
|
||||
$2.ptr, $2.length);
|
||||
$$ = NULL;
|
||||
}
|
||||
| UNION name
|
||||
@ -1437,13 +1439,14 @@ typebase
|
||||
}
|
||||
| UNION COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_UNION, "", 0);
|
||||
pstate->mark_completion_tag (TYPE_CODE_UNION,
|
||||
"", 0);
|
||||
$$ = NULL;
|
||||
}
|
||||
| UNION name COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_UNION, $2.ptr,
|
||||
$2.length);
|
||||
pstate->mark_completion_tag (TYPE_CODE_UNION,
|
||||
$2.ptr, $2.length);
|
||||
$$ = NULL;
|
||||
}
|
||||
| ENUM name
|
||||
@ -1452,13 +1455,13 @@ typebase
|
||||
}
|
||||
| ENUM COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_ENUM, "", 0);
|
||||
pstate->mark_completion_tag (TYPE_CODE_ENUM, "", 0);
|
||||
$$ = NULL;
|
||||
}
|
||||
| ENUM name COMPLETE
|
||||
{
|
||||
mark_completion_tag (TYPE_CODE_ENUM, $2.ptr,
|
||||
$2.length);
|
||||
pstate->mark_completion_tag (TYPE_CODE_ENUM, $2.ptr,
|
||||
$2.length);
|
||||
$$ = NULL;
|
||||
}
|
||||
| UNSIGNED type_name
|
||||
@ -2608,7 +2611,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
|
||||
saw_name_at_eof = 0;
|
||||
return COMPLETE;
|
||||
}
|
||||
else if (parse_completion && saw_structop)
|
||||
else if (par_state->parse_completion && saw_structop)
|
||||
return COMPLETE;
|
||||
else
|
||||
return 0;
|
||||
@ -2902,7 +2905,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name)
|
||||
if (*tokstart == '$')
|
||||
return DOLLAR_VARIABLE;
|
||||
|
||||
if (parse_completion && *pstate->lexptr == '\0')
|
||||
if (pstate->parse_completion && *pstate->lexptr == '\0')
|
||||
saw_name_at_eof = 1;
|
||||
|
||||
yylval.ssym.stoken = yylval.sval;
|
||||
|
@ -338,7 +338,7 @@ PostfixExpression:
|
||||
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;
|
||||
@ -349,7 +349,7 @@ PostfixExpression:
|
||||
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); }
|
||||
@ -1107,7 +1107,7 @@ lex_one_token (struct parser_state *par_state)
|
||||
/* 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. */
|
||||
}
|
||||
@ -1308,7 +1308,7 @@ lex_one_token (struct parser_state *par_state)
|
||||
return NAME_OR_INT;
|
||||
}
|
||||
|
||||
if (parse_completion && *pstate->lexptr == '\0')
|
||||
if (pstate->parse_completion && *pstate->lexptr == '\0')
|
||||
saw_name_at_eof = 1;
|
||||
|
||||
return IDENTIFIER;
|
||||
|
@ -123,10 +123,6 @@ extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
|
||||
innermost_block_tracker_types
|
||||
= INNERMOST_BLOCK_FOR_SYMBOLS);
|
||||
|
||||
/* For use by parsers; set if we want to parse an expression and
|
||||
attempt completion. */
|
||||
extern int parse_completion;
|
||||
|
||||
/* From eval.c */
|
||||
|
||||
/* Values of NOSIDE argument to eval_subexp. */
|
||||
|
@ -246,7 +246,7 @@ exp : exp '.' name_not_typename
|
||||
;
|
||||
|
||||
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); }
|
||||
@ -254,7 +254,7 @@ exp : exp '.' name_not_typename COMPLETE
|
||||
|
||||
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;
|
||||
@ -1087,7 +1087,7 @@ lex_one_token (struct parser_state *par_state)
|
||||
/* Might be a floating point number. */
|
||||
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. */
|
||||
}
|
||||
@ -1276,7 +1276,7 @@ lex_one_token (struct parser_state *par_state)
|
||||
if (*tokstart == '$')
|
||||
return DOLLAR_VARIABLE;
|
||||
|
||||
if (parse_completion && *par_state->lexptr == '\0')
|
||||
if (pstate->parse_completion && *par_state->lexptr == '\0')
|
||||
saw_name_at_eof = 1;
|
||||
return NAME;
|
||||
}
|
||||
|
@ -176,9 +176,12 @@ struct language_defn
|
||||
la_parser, perform any remaining processing necessary to complete
|
||||
its translation. *EXPP may change; la_post_parser is responsible
|
||||
for releasing its previous contents, if necessary. If
|
||||
VOID_CONTEXT_P, then no value is expected from the expression. */
|
||||
VOID_CONTEXT_P, then no value is expected from the expression.
|
||||
If COMPLETING is non-zero, then the expression has been parsed
|
||||
for completion, not evaluation. */
|
||||
|
||||
void (*la_post_parser) (expression_up *expp, int void_context_p);
|
||||
void (*la_post_parser) (expression_up *expp, int void_context_p,
|
||||
int completing);
|
||||
|
||||
void (*la_printchar) (int ch, struct type *chtype,
|
||||
struct ui_file * stream);
|
||||
|
@ -285,14 +285,14 @@ exp : field_exp name
|
||||
}
|
||||
;
|
||||
exp : field_exp name COMPLETE
|
||||
{ mark_struct_expression (pstate);
|
||||
{ pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
|
||||
write_exp_string (pstate, $2);
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
|
||||
;
|
||||
exp : field_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;
|
||||
@ -1162,7 +1162,7 @@ yylex (void)
|
||||
switch (c = *tokstart)
|
||||
{
|
||||
case 0:
|
||||
if (search_field && parse_completion)
|
||||
if (search_field && pstate->parse_completion)
|
||||
return COMPLETE;
|
||||
else
|
||||
return 0;
|
||||
|
93
gdb/parse.c
93
gdb/parse.c
@ -69,20 +69,6 @@ const struct exp_descriptor exp_descriptor_standard =
|
||||
innermost_block_tracker innermost_block;
|
||||
static struct type_stack type_stack;
|
||||
|
||||
/* True if parsing an expression to attempt completion. */
|
||||
int parse_completion;
|
||||
|
||||
/* The index of the last struct expression directly before a '.' or
|
||||
'->'. This is set when parsing and is only used when completing a
|
||||
field name. It is -1 if no dereference operation was found. */
|
||||
static int expout_last_struct = -1;
|
||||
|
||||
/* If we are completing a tagged type name, this will be nonzero. */
|
||||
static enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
|
||||
|
||||
/* The token for tagged type name completion. */
|
||||
static gdb::unique_xmalloc_ptr<char> expout_completion_name;
|
||||
|
||||
|
||||
static unsigned int expressiondebug = 0;
|
||||
static void
|
||||
@ -105,12 +91,13 @@ show_parserdebug (struct ui_file *file, int from_tty,
|
||||
|
||||
|
||||
static int prefixify_subexp (struct expression *, struct expression *, int,
|
||||
int);
|
||||
int, int);
|
||||
|
||||
static expression_up parse_exp_in_context (const char **, CORE_ADDR,
|
||||
const struct block *, int,
|
||||
int, int *,
|
||||
innermost_block_tracker_types);
|
||||
innermost_block_tracker_types,
|
||||
expr_completion_state *);
|
||||
|
||||
static void increase_expout_size (struct expr_builder *ps, size_t lenelt);
|
||||
|
||||
@ -507,15 +494,15 @@ write_exp_msymbol (struct expr_builder *ps,
|
||||
write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
|
||||
}
|
||||
|
||||
/* Mark the current index as the starting location of a structure
|
||||
expression. This is used when completing on field names. */
|
||||
/* See parser-defs.h. */
|
||||
|
||||
void
|
||||
mark_struct_expression (struct expr_builder *ps)
|
||||
parser_state::mark_struct_expression ()
|
||||
{
|
||||
gdb_assert (parse_completion
|
||||
&& expout_tag_completion_type == TYPE_CODE_UNDEF);
|
||||
expout_last_struct = ps->expout_ptr;
|
||||
&& (m_completion_state.expout_tag_completion_type
|
||||
== TYPE_CODE_UNDEF));
|
||||
m_completion_state.expout_last_struct = expout_ptr;
|
||||
}
|
||||
|
||||
/* Indicate that the current parser invocation is completing a tag.
|
||||
@ -523,17 +510,19 @@ mark_struct_expression (struct expr_builder *ps)
|
||||
start of the tag name. */
|
||||
|
||||
void
|
||||
mark_completion_tag (enum type_code tag, const char *ptr, int length)
|
||||
parser_state::mark_completion_tag (enum type_code tag, const char *ptr,
|
||||
int length)
|
||||
{
|
||||
gdb_assert (parse_completion
|
||||
&& expout_tag_completion_type == TYPE_CODE_UNDEF
|
||||
&& expout_completion_name == NULL
|
||||
&& expout_last_struct == -1);
|
||||
&& (m_completion_state.expout_tag_completion_type
|
||||
== TYPE_CODE_UNDEF)
|
||||
&& m_completion_state.expout_completion_name == NULL
|
||||
&& m_completion_state.expout_last_struct == -1);
|
||||
gdb_assert (tag == TYPE_CODE_UNION
|
||||
|| tag == TYPE_CODE_STRUCT
|
||||
|| tag == TYPE_CODE_ENUM);
|
||||
expout_tag_completion_type = tag;
|
||||
expout_completion_name.reset (xstrndup (ptr, length));
|
||||
m_completion_state.expout_tag_completion_type = tag;
|
||||
m_completion_state.expout_completion_name.reset (xstrndup (ptr, length));
|
||||
}
|
||||
|
||||
|
||||
@ -755,7 +744,7 @@ copy_name (struct stoken token)
|
||||
/* See comments on parser-defs.h. */
|
||||
|
||||
int
|
||||
prefixify_expression (struct expression *expr)
|
||||
prefixify_expression (struct expression *expr, int last_struct)
|
||||
{
|
||||
gdb_assert (expr->nelts > 0);
|
||||
int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
|
||||
@ -767,7 +756,7 @@ prefixify_expression (struct expression *expr)
|
||||
/* Copy the original expression into temp. */
|
||||
memcpy (temp, expr, len);
|
||||
|
||||
return prefixify_subexp (temp, expr, inpos, outpos);
|
||||
return prefixify_subexp (temp, expr, inpos, outpos, last_struct);
|
||||
}
|
||||
|
||||
/* Return the number of exp_elements in the postfix subexpression
|
||||
@ -987,13 +976,14 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
/* Copy the subexpression ending just before index INEND in INEXPR
|
||||
into OUTEXPR, starting at index OUTBEG.
|
||||
In the process, convert it from suffix to prefix form.
|
||||
If EXPOUT_LAST_STRUCT is -1, then this function always returns -1.
|
||||
If LAST_STRUCT is -1, then this function always returns -1.
|
||||
Otherwise, it returns the index of the subexpression which is the
|
||||
left-hand-side of the expression at EXPOUT_LAST_STRUCT. */
|
||||
left-hand-side of the expression at LAST_STRUCT. */
|
||||
|
||||
static int
|
||||
prefixify_subexp (struct expression *inexpr,
|
||||
struct expression *outexpr, int inend, int outbeg)
|
||||
struct expression *outexpr, int inend, int outbeg,
|
||||
int last_struct)
|
||||
{
|
||||
int oplen;
|
||||
int args;
|
||||
@ -1010,7 +1000,7 @@ prefixify_subexp (struct expression *inexpr,
|
||||
EXP_ELEM_TO_BYTES (oplen));
|
||||
outbeg += oplen;
|
||||
|
||||
if (expout_last_struct == inend)
|
||||
if (last_struct == inend)
|
||||
result = outbeg - oplen;
|
||||
|
||||
/* Find the lengths of the arg subexpressions. */
|
||||
@ -1034,7 +1024,7 @@ prefixify_subexp (struct expression *inexpr,
|
||||
|
||||
oplen = arglens[i];
|
||||
inend += oplen;
|
||||
r = prefixify_subexp (inexpr, outexpr, inend, outbeg);
|
||||
r = prefixify_subexp (inexpr, outexpr, inend, outbeg, last_struct);
|
||||
if (r != -1)
|
||||
{
|
||||
/* Return immediately. We probably have only parsed a
|
||||
@ -1063,7 +1053,7 @@ parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
|
||||
int comma, innermost_block_tracker_types tracker_types)
|
||||
{
|
||||
return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL,
|
||||
tracker_types);
|
||||
tracker_types, nullptr);
|
||||
}
|
||||
|
||||
/* As for parse_exp_1, except that if VOID_CONTEXT_P, then
|
||||
@ -1077,15 +1067,13 @@ static expression_up
|
||||
parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
|
||||
const struct block *block,
|
||||
int comma, int void_context_p, int *out_subexp,
|
||||
innermost_block_tracker_types tracker_types)
|
||||
innermost_block_tracker_types tracker_types,
|
||||
expr_completion_state *cstate)
|
||||
{
|
||||
const struct language_defn *lang = NULL;
|
||||
int subexp;
|
||||
|
||||
type_stack.elements.clear ();
|
||||
expout_last_struct = -1;
|
||||
expout_tag_completion_type = TYPE_CODE_UNDEF;
|
||||
expout_completion_name.reset ();
|
||||
innermost_block.reset (tracker_types);
|
||||
|
||||
if (*stringptr == 0 || **stringptr == 0)
|
||||
@ -1147,7 +1135,8 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
|
||||
to the value matching SELECTED_FRAME as set by get_current_arch. */
|
||||
|
||||
parser_state ps (lang, get_current_arch (), expression_context_block,
|
||||
expression_context_pc, comma, *stringptr);
|
||||
expression_context_pc, comma, *stringptr,
|
||||
cstate != nullptr);
|
||||
|
||||
scoped_restore_current_language lang_saver;
|
||||
set_language (lang->la_language);
|
||||
@ -1161,7 +1150,7 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
|
||||
/* If parsing for completion, allow this to succeed; but if no
|
||||
expression elements have been written, then there's nothing
|
||||
to do, so fail. */
|
||||
if (! parse_completion || ps.expout_ptr == 0)
|
||||
if (! ps.parse_completion || ps.expout_ptr == 0)
|
||||
throw_exception (except);
|
||||
}
|
||||
END_CATCH
|
||||
@ -1177,15 +1166,18 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
|
||||
dump_raw_expression (result.get (), gdb_stdlog,
|
||||
"before conversion to prefix form");
|
||||
|
||||
subexp = prefixify_expression (result.get ());
|
||||
subexp = prefixify_expression (result.get (),
|
||||
ps.m_completion_state.expout_last_struct);
|
||||
if (out_subexp)
|
||||
*out_subexp = subexp;
|
||||
|
||||
lang->la_post_parser (&result, void_context_p);
|
||||
lang->la_post_parser (&result, void_context_p, ps.parse_completion);
|
||||
|
||||
if (expressiondebug)
|
||||
dump_prefix_expression (result.get (), gdb_stdlog);
|
||||
|
||||
if (cstate != nullptr)
|
||||
*cstate = std::move (ps.m_completion_state);
|
||||
*stringptr = ps.lexptr;
|
||||
return result;
|
||||
}
|
||||
@ -1233,12 +1225,12 @@ parse_expression_for_completion (const char *string,
|
||||
expression_up exp;
|
||||
struct value *val;
|
||||
int subexp;
|
||||
expr_completion_state cstate;
|
||||
|
||||
TRY
|
||||
{
|
||||
parse_completion = 1;
|
||||
exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp,
|
||||
INNERMOST_BLOCK_FOR_SYMBOLS);
|
||||
INNERMOST_BLOCK_FOR_SYMBOLS, &cstate);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
@ -1246,18 +1238,17 @@ parse_expression_for_completion (const char *string,
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
parse_completion = 0;
|
||||
if (exp == NULL)
|
||||
return NULL;
|
||||
|
||||
if (expout_tag_completion_type != TYPE_CODE_UNDEF)
|
||||
if (cstate.expout_tag_completion_type != TYPE_CODE_UNDEF)
|
||||
{
|
||||
*code = expout_tag_completion_type;
|
||||
*name = std::move (expout_completion_name);
|
||||
*code = cstate.expout_tag_completion_type;
|
||||
*name = std::move (cstate.expout_completion_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (expout_last_struct == -1)
|
||||
if (cstate.expout_last_struct == -1)
|
||||
return NULL;
|
||||
|
||||
const char *fieldname = extract_field_op (exp.get (), &subexp);
|
||||
@ -1278,7 +1269,7 @@ parse_expression_for_completion (const char *string,
|
||||
/* A post-parser that does nothing. */
|
||||
|
||||
void
|
||||
null_post_parser (expression_up *exp, int void_context_p)
|
||||
null_post_parser (expression_up *exp, int void_context_p, int completin)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,22 @@ struct expr_builder
|
||||
size_t expout_ptr;
|
||||
};
|
||||
|
||||
/* This is used for expression completion. */
|
||||
|
||||
struct expr_completion_state
|
||||
{
|
||||
/* The index of the last struct expression directly before a '.' or
|
||||
'->'. This is set when parsing and is only used when completing a
|
||||
field name. It is -1 if no dereference operation was found. */
|
||||
int expout_last_struct = -1;
|
||||
|
||||
/* If we are completing a tagged type name, this will be nonzero. */
|
||||
enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
|
||||
|
||||
/* The token for tagged type name completion. */
|
||||
gdb::unique_xmalloc_ptr<char> expout_completion_name;
|
||||
};
|
||||
|
||||
/* An instance of this type is instantiated during expression parsing,
|
||||
and passed to the appropriate parser. It holds both inputs to the
|
||||
parser, and result. */
|
||||
@ -90,12 +106,14 @@ struct parser_state : public expr_builder
|
||||
const struct block *context_block,
|
||||
CORE_ADDR context_pc,
|
||||
int comma,
|
||||
const char *input)
|
||||
const char *input,
|
||||
int completion)
|
||||
: expr_builder (lang, gdbarch),
|
||||
expression_context_block (context_block),
|
||||
expression_context_pc (context_pc),
|
||||
comma_terminates (comma),
|
||||
lexptr (input)
|
||||
lexptr (input),
|
||||
parse_completion (completion)
|
||||
{
|
||||
}
|
||||
|
||||
@ -121,6 +139,17 @@ struct parser_state : public expr_builder
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Mark the current index as the starting location of a structure
|
||||
expression. This is used when completing on field names. */
|
||||
|
||||
void mark_struct_expression ();
|
||||
|
||||
/* Indicate that the current parser invocation is completing a tag.
|
||||
TAG is the type code of the tag, and PTR and LENGTH represent the
|
||||
start of the tag name. */
|
||||
|
||||
void mark_completion_tag (enum type_code tag, const char *ptr, int length);
|
||||
|
||||
|
||||
/* If this is nonzero, this block is used as the lexical context for
|
||||
symbol names. */
|
||||
@ -151,6 +180,12 @@ struct parser_state : public expr_builder
|
||||
|
||||
int arglist_len = 0;
|
||||
|
||||
/* True if parsing an expression to attempt completion. */
|
||||
int parse_completion;
|
||||
|
||||
/* Completion state is updated here. */
|
||||
expr_completion_state m_completion_state;
|
||||
|
||||
private:
|
||||
|
||||
/* Data structure for saving values of arglist_len for function calls whose
|
||||
@ -300,12 +335,13 @@ struct type_stack
|
||||
|
||||
/* Reverse an expression from suffix form (in which it is constructed)
|
||||
to prefix form (in which we can conveniently print or execute it).
|
||||
Ordinarily this always returns -1. However, if EXPOUT_LAST_STRUCT
|
||||
Ordinarily this always returns -1. However, if LAST_STRUCT
|
||||
is not -1 (i.e., we are trying to complete a field name), it will
|
||||
return the index of the subexpression which is the left-hand-side
|
||||
of the struct operation at EXPOUT_LAST_STRUCT. */
|
||||
of the struct operation at LAST_STRUCT. */
|
||||
|
||||
extern int prefixify_expression (struct expression *expr);
|
||||
extern int prefixify_expression (struct expression *expr,
|
||||
int last_struct = -1);
|
||||
|
||||
extern void write_exp_elt_opcode (struct expr_builder *, enum exp_opcode);
|
||||
|
||||
@ -336,8 +372,6 @@ extern void write_exp_msymbol (struct expr_builder *,
|
||||
|
||||
extern void write_dollar_variable (struct parser_state *, struct stoken str);
|
||||
|
||||
extern void mark_struct_expression (struct expr_builder *);
|
||||
|
||||
extern const char *find_template_name_end (const char *);
|
||||
|
||||
extern char *copy_name (struct stoken);
|
||||
@ -384,7 +418,7 @@ extern struct type *follow_types (struct type *);
|
||||
|
||||
extern type_instance_flags follow_type_instance_flags ();
|
||||
|
||||
extern void null_post_parser (expression_up *, int);
|
||||
extern void null_post_parser (expression_up *, int, int);
|
||||
|
||||
extern bool parse_float (const char *p, int len,
|
||||
const struct type *type, gdb_byte *data);
|
||||
@ -483,8 +517,5 @@ extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3);
|
||||
|
||||
extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
|
||||
|
||||
extern void mark_completion_tag (enum type_code, const char *ptr,
|
||||
int length);
|
||||
|
||||
#endif /* PARSER_DEFS_H */
|
||||
|
||||
|
@ -1438,10 +1438,10 @@ rust_parser::lex_identifier (YYSTYPE *lvalp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (token == NULL || (parse_completion && pstate->lexptr[0] == '\0'))
|
||||
if (token == NULL || (pstate->parse_completion && pstate->lexptr[0] == '\0'))
|
||||
lvalp->sval = make_stoken (copy_name (start, length));
|
||||
|
||||
if (parse_completion && pstate->lexptr[0] == '\0')
|
||||
if (pstate->parse_completion && pstate->lexptr[0] == '\0')
|
||||
{
|
||||
/* Prevent rustyylex from returning two COMPLETE tokens. */
|
||||
pstate->prev_lexptr = pstate->lexptr;
|
||||
@ -1650,7 +1650,7 @@ rustyylex (YYSTYPE *lvalp, rust_parser *parser)
|
||||
pstate->prev_lexptr = pstate->lexptr;
|
||||
if (pstate->lexptr[0] == '\0')
|
||||
{
|
||||
if (parse_completion)
|
||||
if (pstate->parse_completion)
|
||||
{
|
||||
lvalp->sval = make_stoken ("");
|
||||
return COMPLETE;
|
||||
@ -2225,7 +2225,7 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation,
|
||||
convert_ast_to_expression (operation->left.op, top);
|
||||
|
||||
if (operation->completing)
|
||||
mark_struct_expression (pstate);
|
||||
pstate->mark_struct_expression ();
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
|
||||
write_exp_string (pstate, operation->right.sval);
|
||||
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
|
||||
@ -2544,7 +2544,7 @@ rust_parse (struct parser_state *state)
|
||||
|
||||
result = rustyyparse (&parser);
|
||||
|
||||
if (!result || (parse_completion && parser.rust_ast != NULL))
|
||||
if (!result || (state->parse_completion && parser.rust_ast != NULL))
|
||||
parser.convert_ast_to_expression (parser.rust_ast, parser.rust_ast);
|
||||
|
||||
return result;
|
||||
@ -2684,14 +2684,14 @@ rust_lex_test_completion (rust_parser *parser)
|
||||
{
|
||||
const int expected[] = { IDENT, '.', COMPLETE, 0 };
|
||||
|
||||
parse_completion = 1;
|
||||
parser->pstate->parse_completion = 1;
|
||||
|
||||
rust_lex_test_sequence (parser, "something.wha", ARRAY_SIZE (expected),
|
||||
expected);
|
||||
rust_lex_test_sequence (parser, "something.", ARRAY_SIZE (expected),
|
||||
expected);
|
||||
|
||||
parse_completion = 0;
|
||||
parser->pstate->parse_completion = 0;
|
||||
}
|
||||
|
||||
/* Test pushback. */
|
||||
@ -2726,7 +2726,7 @@ rust_lex_tests (void)
|
||||
|
||||
// Set up dummy "parser", so that rust_type works.
|
||||
struct parser_state ps (&rust_language_defn, target_gdbarch (),
|
||||
nullptr, 0, 0, nullptr);
|
||||
nullptr, 0, 0, nullptr, 0);
|
||||
rust_parser parser (&ps);
|
||||
|
||||
rust_lex_test_one (&parser, "", 0);
|
||||
|
Loading…
Reference in New Issue
Block a user