Add completion for operations
authorTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:27:57 +0000 (07:27 -0700)
committerTom Tromey <tom@tromey.com>
Mon, 8 Mar 2021 14:28:37 +0000 (07:28 -0700)
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.

gdb/ChangeLog
gdb/parse.c
gdb/parser-defs.h

index 5fd0967d3d5579f024e975fb22f1d2b19d954be5..3436e4e83fc2bc56f1743f6c86a1ad2370dc5054 100644 (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>
 
        * ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;
index 68386f17bc5e026a3cc578593e4cc2113b0d8842..79b1ca1612127beb485d7efaca299be368dc40c4 100644 (file)
@@ -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;
 
index a9ae198fab22e4500e37f36dd16e8ff87277d534..9f70ff9dca7aa3a005dd9125df65e0f36b723ed8 100644 (file)
@@ -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.  */