aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/parse.c26
-rw-r--r--gdb/parser-defs.h11
3 files changed, 45 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5fd0967..3436e4e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
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>
+
* ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;
now in superclass.
* value.h (fetch_subexp_value): Add "op" parameter.
diff --git a/gdb/parse.c b/gdb/parse.c
index 68386f1..79b1ca1 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -507,10 +507,23 @@ parser_state::mark_struct_expression ()
{
gdb_assert (parse_completion
&& (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;
}
+/* 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.
TAG is the type code of the tag, and PTR and LENGTH represent the
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
== TYPE_CODE_UNDEF)
&& 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
|| tag == TYPE_CODE_STRUCT
|| tag == TYPE_CODE_ENUM);
@@ -1262,6 +1276,14 @@ parse_expression_for_completion (const char *string,
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)
return NULL;
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index a9ae198..9f70ff9 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -25,6 +25,7 @@
#include "expression.h"
#include "symtab.h"
+#include "expop.h"
struct block;
struct language_defn;
@@ -93,6 +94,11 @@ struct expr_completion_state
field name. It is -1 if no dereference operation was found. */
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. */
enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
@@ -156,6 +162,11 @@ struct parser_state : public expr_builder
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.
TAG is the type code of the tag, and PTR and LENGTH represent the
start of the tag name. */