Add completion for operations

This patch adds the necessary support for field name completion for
expressions using class operation.

This patch takes an approach similar to what is done today.  It might
be good, in the future, to change completion to be a method on the
base class, to enable context-sensitive completion in more areas.

gdb/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

	* parser-defs.h (struct expr_completion_state) <expout_last_op>:
	New member.
	(struct parser_state) <mark_struct_expression>: New method.
	* parse.c (parser_state::mark_struct_expression): Update assert.
	(parser_state::mark_struct_expression): New method.
	(parser_state::mark_completion_tag): Update assert.
	(parse_expression_for_completion): Handle expout_last_op.
This commit is contained in:
Tom Tromey 2021-03-08 07:27:57 -07:00
parent 413403fc34
commit 4933522da0
3 changed files with 45 additions and 2 deletions

View file

@ -1,3 +1,13 @@
2021-03-08 Tom Tromey <tom@tromey.com>
* parser-defs.h (struct expr_completion_state) <expout_last_op>:
New member.
(struct parser_state) <mark_struct_expression>: New method.
* parse.c (parser_state::mark_struct_expression): Update assert.
(parser_state::mark_struct_expression): New method.
(parser_state::mark_completion_tag): Update assert.
(parse_expression_for_completion): Handle expout_last_op.
2021-03-08 Tom Tromey <tom@tromey.com> 2021-03-08 Tom Tromey <tom@tromey.com>
* ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove; * ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;

View file

@ -507,10 +507,23 @@ parser_state::mark_struct_expression ()
{ {
gdb_assert (parse_completion gdb_assert (parse_completion
&& (m_completion_state.expout_tag_completion_type && (m_completion_state.expout_tag_completion_type
== TYPE_CODE_UNDEF)); == TYPE_CODE_UNDEF)
&& m_completion_state.expout_last_op == nullptr);
m_completion_state.expout_last_struct = expout_ptr; m_completion_state.expout_last_struct = expout_ptr;
} }
/* See parser-defs.h. */
void
parser_state::mark_struct_expression (expr::structop_base_operation *op)
{
gdb_assert (parse_completion
&& (m_completion_state.expout_tag_completion_type
== TYPE_CODE_UNDEF)
&& m_completion_state.expout_last_struct == -1);
m_completion_state.expout_last_op = op;
}
/* Indicate that the current parser invocation is completing a tag. /* Indicate that the current parser invocation is completing a tag.
TAG is the type code of the tag, and PTR and LENGTH represent the TAG is the type code of the tag, and PTR and LENGTH represent the
start of the tag name. */ start of the tag name. */
@ -523,7 +536,8 @@ parser_state::mark_completion_tag (enum type_code tag, const char *ptr,
&& (m_completion_state.expout_tag_completion_type && (m_completion_state.expout_tag_completion_type
== TYPE_CODE_UNDEF) == TYPE_CODE_UNDEF)
&& m_completion_state.expout_completion_name == NULL && m_completion_state.expout_completion_name == NULL
&& m_completion_state.expout_last_struct == -1); && m_completion_state.expout_last_struct == -1
&& m_completion_state.expout_last_op == nullptr);
gdb_assert (tag == TYPE_CODE_UNION gdb_assert (tag == TYPE_CODE_UNION
|| tag == TYPE_CODE_STRUCT || tag == TYPE_CODE_STRUCT
|| tag == TYPE_CODE_ENUM); || tag == TYPE_CODE_ENUM);
@ -1262,6 +1276,14 @@ parse_expression_for_completion (const char *string,
return NULL; return NULL;
} }
if (cstate.expout_last_op != nullptr)
{
expr::structop_base_operation *op = cstate.expout_last_op;
const std::string &fld = op->get_string ();
*name = make_unique_xstrdup (fld.c_str ());
return value_type (op->evaluate_lhs (exp.get ()));
}
if (cstate.expout_last_struct == -1) if (cstate.expout_last_struct == -1)
return NULL; return NULL;

View file

@ -25,6 +25,7 @@
#include "expression.h" #include "expression.h"
#include "symtab.h" #include "symtab.h"
#include "expop.h"
struct block; struct block;
struct language_defn; struct language_defn;
@ -93,6 +94,11 @@ struct expr_completion_state
field name. It is -1 if no dereference operation was found. */ field name. It is -1 if no dereference operation was found. */
int expout_last_struct = -1; int expout_last_struct = -1;
/* The last struct expression directly before a '.' or '->'. This
is set when parsing and is only used when completing a field
name. It is nullptr if no dereference operation was found. */
expr::structop_base_operation *expout_last_op = nullptr;
/* If we are completing a tagged type name, this will be nonzero. */ /* If we are completing a tagged type name, this will be nonzero. */
enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF; enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
@ -156,6 +162,11 @@ struct parser_state : public expr_builder
void mark_struct_expression (); void mark_struct_expression ();
/* Mark the given operation as the starting location of a structure
expression. This is used when completing on field names. */
void mark_struct_expression (expr::structop_base_operation *op);
/* Indicate that the current parser invocation is completing a tag. /* Indicate that the current parser invocation is completing a tag.
TAG is the type code of the tag, and PTR and LENGTH represent the TAG is the type code of the tag, and PTR and LENGTH represent the
start of the tag name. */ start of the tag name. */