Convert dprintf to vtable ops
[binutils-gdb.git] / gdb / ada-exp.y
index 16ba336df4aa45b93c8368fa812e4b3e991978dd..8660205809a23a386a8dd39536d10f09a15f53c6 100644 (file)
@@ -68,6 +68,9 @@ struct name_info {
 
 static struct parser_state *pstate = NULL;
 
+/* The original expression string.  */
+static const char *original_expr;
+
 int yyparse (void);
 
 static int yylex (void);
@@ -82,6 +85,9 @@ static void write_object_renaming (struct parser_state *,
 
 static struct type* write_var_or_type (struct parser_state *,
                                       const struct block *, struct stoken);
+static struct type *write_var_or_type_completion (struct parser_state *,
+                                                 const struct block *,
+                                                 struct stoken);
 
 static void write_name_assoc (struct parser_state *, struct stoken);
 
@@ -98,12 +104,14 @@ static struct type *type_long_long (struct parser_state *);
 
 static struct type *type_long_double (struct parser_state *);
 
-static struct type *type_char (struct parser_state *);
+static struct type *type_for_char (struct parser_state *, ULONGEST);
 
 static struct type *type_boolean (struct parser_state *);
 
 static struct type *type_system_address (struct parser_state *);
 
+static std::string find_completion_bounds (struct parser_state *);
+
 using namespace expr;
 
 /* Handle Ada type resolution for OP.  DEPROCEDURE_P and CONTEXT_TYPE
@@ -290,7 +298,7 @@ ada_funcall (int nargs)
   int array_arity = 0;
   struct type *callee_t = nullptr;
   if (vvo == nullptr
-      || SYMBOL_DOMAIN (vvo->get_symbol ()) != UNDEF_DOMAIN)
+      || vvo->get_symbol ()->domain () != UNDEF_DOMAIN)
     {
       struct value *callee_v = callee->evaluate (nullptr,
                                                 pstate->expout.get (),
@@ -393,6 +401,30 @@ pop_associations (int n)
   return result;
 }
 
+/* Expression completer for attributes.  */
+struct ada_tick_completer : public expr_completion_base
+{
+  explicit ada_tick_completer (std::string &&name)
+    : m_name (std::move (name))
+  {
+  }
+
+  bool complete (struct expression *exp,
+                completion_tracker &tracker) override;
+
+private:
+
+  std::string m_name;
+};
+
+/* Make a new ada_tick_completer and wrap it in a unique pointer.  */
+static std::unique_ptr<expr_completion_base>
+make_tick_completer (struct stoken tok)
+{
+  return (std::unique_ptr<expr_completion_base>
+         (new ada_tick_completer (std::string (tok.ptr, tok.length))));
+}
+
 %}
 
 %union
@@ -420,12 +452,10 @@ pop_associations (int n)
 %token <typed_val_float> FLOAT
 %token TRUEKEYWORD FALSEKEYWORD
 %token COLONCOLON
-%token <sval> STRING NAME DOT_ID 
+%token <sval> STRING NAME DOT_ID TICK_COMPLETE DOT_COMPLETE NAME_COMPLETE
 %type <bval> block
 %type <lval> arglist tick_arglist
 
-%token DOT_ALL
-
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
 %token <sval> DOLLAR_VARIABLE
@@ -449,10 +479,11 @@ pop_associations (int n)
 %right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH
 %right TICK_MAX TICK_MIN TICK_MODULUS
 %right TICK_POS TICK_RANGE TICK_SIZE TICK_TAG TICK_VAL
+%right TICK_COMPLETE
  /* The following are right-associative only so that reductions at this
     precedence have lower precedence than '.' and '('.  The syntax still
     forces a.b.c, e.g., to be LEFT-associated.  */
-%right '.' '(' '[' DOT_ID DOT_ALL
+%right '.' '(' '[' DOT_ID DOT_COMPLETE
 
 %token NEW OTHERS
 
@@ -481,15 +512,31 @@ exp1      :       exp
        ;
 
 /* Expressions, not including the sequencing operator.  */
-primary :      primary DOT_ALL
-                       { ada_wrap<ada_unop_ind_operation> (); }
-       ;
 
 primary :      primary DOT_ID
                        {
+                         if (strcmp ($2.ptr, "all") == 0)
+                           ada_wrap<ada_unop_ind_operation> ();
+                         else
+                           {
+                             operation_up arg = ada_pop ();
+                             pstate->push_new<ada_structop_operation>
+                               (std::move (arg), copy_name ($2));
+                           }
+                       }
+       ;
+
+primary :      primary DOT_COMPLETE
+                       {
+                         /* This is done even for ".all", because
+                            that might be a prefix.  */
                          operation_up arg = ada_pop ();
-                         pstate->push_new<ada_structop_operation>
-                           (std::move (arg), copy_name ($2));
+                         ada_structop_operation *str_op
+                           = (new ada_structop_operation
+                              (std::move (arg), copy_name ($2)));
+                         str_op->set_prefix (find_completion_bounds (pstate));
+                         pstate->push (operation_up (str_op));
+                         pstate->mark_struct_expression (str_op);
                        }
        ;
 
@@ -649,7 +696,7 @@ simple_exp  :       simple_exp '+' simple_exp
        ;
 
 simple_exp     :       simple_exp '&' simple_exp
-                       { ada_wrap2<concat_operation> (BINOP_CONCAT); }
+                       { ada_wrap2<ada_concat_operation> (BINOP_CONCAT); }
        ;
 
 simple_exp     :       simple_exp '-' simple_exp
@@ -784,6 +831,10 @@ primary :  primary TICK_ACCESS
                        { ada_addrof (); }
        |       primary TICK_ADDRESS
                        { ada_addrof (type_system_address (pstate)); }
+       |       primary TICK_COMPLETE
+                       {
+                         pstate->mark_completion (make_tick_completer ($2));
+                       }
        |       primary TICK_FIRST tick_arglist
                        {
                          operation_up arg = ada_pop ();
@@ -899,8 +950,20 @@ primary    :       NEW NAME
 
 var_or_type:   NAME        %prec VAR
                                { $$ = write_var_or_type (pstate, NULL, $1); }
+       |       NAME_COMPLETE %prec VAR
+                               {
+                                 $$ = write_var_or_type_completion (pstate,
+                                                                    NULL,
+                                                                    $1);
+                               }
        |       block NAME  %prec VAR
                                { $$ = write_var_or_type (pstate, $1, $2); }
+       |       block NAME_COMPLETE  %prec VAR
+                               {
+                                 $$ = write_var_or_type_completion (pstate,
+                                                                    $1,
+                                                                    $2);
+                               }
        |       NAME TICK_ACCESS 
                        { 
                          $$ = write_var_or_type (pstate, NULL, $1);
@@ -1080,6 +1143,10 @@ ada_parse (struct parser_state *par_state)
   scoped_restore pstate_restore = make_scoped_restore (&pstate);
   gdb_assert (par_state != NULL);
   pstate = par_state;
+  original_expr = par_state->lexptr;
+
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+                                                       parser_debug);
 
   lexer_init (yyin);           /* (Re-)initialize lexer.  */
   obstack_free (&temp_parse_space, NULL);
@@ -1157,7 +1224,7 @@ write_object_renaming (struct parser_state *par_state,
   ada_lookup_encoded_symbol (name, orig_left_context, VAR_DOMAIN, &sym_info);
   if (sym_info.symbol == NULL)
     error (_("Could not find renamed variable: %s"), ada_decode (name).c_str ());
-  else if (SYMBOL_CLASS (sym_info.symbol) == LOC_TYPEDEF)
+  else if (sym_info.symbol->aclass () == LOC_TYPEDEF)
     /* We have a renaming of an old-style renaming symbol.  Don't
        trust the block information.  */
     sym_info.block = orig_left_context;
@@ -1226,7 +1293,7 @@ write_object_renaming (struct parser_state *par_state,
                                       VAR_DOMAIN, &index_sym_info);
            if (index_sym_info.symbol == NULL)
              error (_("Could not find %s"), index_name);
-           else if (SYMBOL_CLASS (index_sym_info.symbol) == LOC_TYPEDEF)
+           else if (index_sym_info.symbol->aclass () == LOC_TYPEDEF)
              /* Index is an old-style renaming symbol.  */
              index_sym_info.block = orig_left_context;
            write_var_from_sym (par_state, index_sym_info);
@@ -1296,14 +1363,14 @@ block_lookup (const struct block *context, const char *raw_name)
     = ada_lookup_symbol_list (name, context, VAR_DOMAIN);
 
   if (context == NULL
-      && (syms.empty () || SYMBOL_CLASS (syms[0].symbol) != LOC_BLOCK))
+      && (syms.empty () || syms[0].symbol->aclass () != LOC_BLOCK))
     symtab = lookup_symtab (name);
   else
     symtab = NULL;
 
   if (symtab != NULL)
-    result = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), STATIC_BLOCK);
-  else if (syms.empty () || SYMBOL_CLASS (syms[0].symbol) != LOC_BLOCK)
+    result = symtab->compunit ()->blockvector ()->static_block ();
+  else if (syms.empty () || syms[0].symbol->aclass () != LOC_BLOCK)
     {
       if (context == NULL)
        error (_("No file or function \"%s\"."), raw_name);
@@ -1314,7 +1381,7 @@ block_lookup (const struct block *context, const char *raw_name)
     {
       if (syms.size () > 1)
        warning (_("Function name \"%s\" ambiguous here"), raw_name);
-      result = SYMBOL_BLOCK_VALUE (syms[0].symbol);
+      result = syms[0].symbol->value_block ();
     }
 
   return result;
@@ -1329,13 +1396,13 @@ select_possible_type_sym (const std::vector<struct block_symbol> &syms)
          
   preferred_index = -1; preferred_type = NULL;
   for (i = 0; i < syms.size (); i += 1)
-    switch (SYMBOL_CLASS (syms[i].symbol))
+    switch (syms[i].symbol->aclass ())
       {
       case LOC_TYPEDEF:
-       if (ada_prefer_type (SYMBOL_TYPE (syms[i].symbol), preferred_type))
+       if (ada_prefer_type (syms[i].symbol->type (), preferred_type))
          {
            preferred_index = i;
-           preferred_type = SYMBOL_TYPE (syms[i].symbol);
+           preferred_type = syms[i].symbol->type ();
          }
        break;
       case LOC_REGISTER:
@@ -1373,8 +1440,8 @@ find_primitive_type (struct parser_state *par_state, const char *name)
       strcpy (expanded_name, "standard__");
       strcat (expanded_name, name);
       sym = ada_lookup_symbol (expanded_name, NULL, VAR_DOMAIN).symbol;
-      if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
-       type = SYMBOL_TYPE (sym);
+      if (sym != NULL && sym->aclass () == LOC_TYPEDEF)
+       type = sym->type ();
     }
 
   return type;
@@ -1408,10 +1475,12 @@ chop_separator (const char *name)
 
 /* Given that SELS is a string of the form (<sep><identifier>)*, where
    <sep> is '__' or '.', write the indicated sequence of
-   STRUCTOP_STRUCT expression operators. */
-static void
+   STRUCTOP_STRUCT expression operators.  Returns a pointer to the
+   last operation that was pushed.  */
+static ada_structop_operation *
 write_selectors (struct parser_state *par_state, const char *sels)
 {
+  ada_structop_operation *result = nullptr;
   while (*sels != '\0')
     {
       const char *p = chop_separator (sels);
@@ -1420,9 +1489,11 @@ write_selectors (struct parser_state *par_state, const char *sels)
             && (sels[0] != '_' || sels[1] != '_'))
        sels += 1;
       operation_up arg = ada_pop ();
-      pstate->push_new<ada_structop_operation>
-       (std::move (arg), std::string (p, sels - p));
+      result = new ada_structop_operation (std::move (arg),
+                                          std::string (p, sels - p));
+      pstate->push (operation_up (result));
     }
+  return result;
 }
 
 /* Write a variable access (OP_VAR_VALUE) to ambiguous encoded name
@@ -1435,7 +1506,7 @@ write_ambiguous_var (struct parser_state *par_state,
 {
   struct symbol *sym = new (&temp_parse_space) symbol ();
 
-  SYMBOL_DOMAIN (sym) = UNDEF_DOMAIN;
+  sym->set_domain (UNDEF_DOMAIN);
   sym->set_linkage_name (obstack_strndup (&temp_parse_space, name, len));
   sym->set_language (language_ada, nullptr);
 
@@ -1474,7 +1545,7 @@ get_symbol_field_type (struct symbol *sym, const char *encoded_field_name)
 {
   const char *field_name = encoded_field_name;
   const char *subfield_name;
-  struct type *type = SYMBOL_TYPE (sym);
+  struct type *type = sym->type ();
   int fieldno;
 
   if (type == NULL || field_name == NULL)
@@ -1549,10 +1620,14 @@ write_var_or_type (struct parser_state *par_state,
          int terminator = encoded_name[tail_index];
 
          encoded_name[tail_index] = '\0';
-         std::vector<struct block_symbol> syms
-           = ada_lookup_symbol_list (encoded_name, block, VAR_DOMAIN);
+         /* In order to avoid double-encoding, we want to only pass
+            the decoded form to lookup functions.  */
+         std::string decoded_name = ada_decode (encoded_name);
          encoded_name[tail_index] = terminator;
 
+         std::vector<struct block_symbol> syms
+           = ada_lookup_symbol_list (decoded_name.c_str (), block, VAR_DOMAIN);
+
          type_sym = select_possible_type_sym (syms);
 
          if (type_sym != NULL)
@@ -1595,7 +1670,7 @@ write_var_or_type (struct parser_state *par_state,
              struct type *field_type;
              
              if (tail_index == name_len)
-               return SYMBOL_TYPE (type_sym);
+               return type_sym->type ();
 
              /* We have some extraneous characters after the type name.
                 If this is an expression "TYPE_NAME.FIELD0.[...].FIELDN",
@@ -1626,7 +1701,7 @@ write_var_or_type (struct parser_state *par_state,
          else if (syms.empty ())
            {
              struct bound_minimal_symbol msym
-               = ada_lookup_simple_minsym (encoded_name);
+               = ada_lookup_simple_minsym (decoded_name.c_str ());
              if (msym.minsym != NULL)
                {
                  par_state->push_new<ada_var_msym_value_operation> (msym);
@@ -1665,6 +1740,72 @@ write_var_or_type (struct parser_state *par_state,
 
 }
 
+/* Because ada_completer_word_break_characters does not contain '.' --
+   and it cannot easily be added, this breaks other completions -- we
+   have to recreate the completion word-splitting here, so that we can
+   provide a prefix that is then used when completing field names.
+   Without this, an attempt like "complete print abc.d" will give a
+   result like "print def" rather than "print abc.def".  */
+
+static std::string
+find_completion_bounds (struct parser_state *par_state)
+{
+  const char *end = pstate->lexptr;
+  /* First the end of the prefix.  Here we stop at the token start or
+     at '.' or space.  */
+  for (; end > original_expr && end[-1] != '.' && !isspace (end[-1]); --end)
+    {
+      /* Nothing.  */
+    }
+  /* Now find the start of the prefix.  */
+  const char *ptr = end;
+  /* Here we allow '.'.  */
+  for (;
+       ptr > original_expr && (ptr[-1] == '.'
+                              || ptr[-1] == '_'
+                              || (ptr[-1] >= 'a' && ptr[-1] <= 'z')
+                              || (ptr[-1] >= 'A' && ptr[-1] <= 'Z')
+                              || (ptr[-1] & 0xff) >= 0x80);
+       --ptr)
+    {
+      /* Nothing.  */
+    }
+  /* ... except, skip leading spaces.  */
+  ptr = skip_spaces (ptr);
+
+  return std::string (ptr, end);
+}
+
+/* A wrapper for write_var_or_type that is used specifically when
+   completion is requested for the last of a sequence of
+   identifiers.  */
+
+static struct type *
+write_var_or_type_completion (struct parser_state *par_state,
+                             const struct block *block, struct stoken name0)
+{
+  int tail_index = chop_selector (name0.ptr, name0.length);
+  /* If there's no separator, just defer to ordinary symbol
+     completion.  */
+  if (tail_index == -1)
+    return write_var_or_type (par_state, block, name0);
+
+  std::string copy (name0.ptr, tail_index);
+  struct type *type = write_var_or_type (par_state, block,
+                                        { copy.c_str (),
+                                          (int) copy.length () });
+  /* For completion purposes, it's enough that we return a type
+     here.  */
+  if (type != nullptr)
+    return type;
+
+  ada_structop_operation *op = write_selectors (par_state,
+                                               name0.ptr + tail_index);
+  op->set_prefix (find_completion_bounds (par_state));
+  par_state->mark_struct_expression (op);
+  return nullptr;
+}
+
 /* Write a left side of a component association (e.g., NAME in NAME =>
    exp).  If NAME has the form of a selected component, write it as an
    ordinary expression.  If it is a simple variable that unambiguously
@@ -1690,7 +1831,7 @@ write_name_assoc (struct parser_state *par_state, struct stoken name)
                                  par_state->expression_context_block,
                                  VAR_DOMAIN);
 
-      if (syms.size () != 1 || SYMBOL_CLASS (syms[0].symbol) == LOC_TYPEDEF)
+      if (syms.size () != 1 || syms[0].symbol->aclass () == LOC_TYPEDEF)
        pstate->push_new<ada_string_operation> (copy_name (name));
       else
        write_var_from_sym (par_state, syms[0]);
@@ -1727,10 +1868,18 @@ type_long_double (struct parser_state *par_state)
 }
 
 static struct type *
-type_char (struct parser_state *par_state)
+type_for_char (struct parser_state *par_state, ULONGEST value)
 {
-  return language_string_char_type (par_state->language (),
-                                   par_state->gdbarch ());
+  if (value <= 0xff)
+    return language_string_char_type (par_state->language (),
+                                     par_state->gdbarch ());
+  else if (value <= 0xffff)
+    return language_lookup_primitive_type (par_state->language (),
+                                          par_state->gdbarch (),
+                                          "wide_character");
+  return language_lookup_primitive_type (par_state->language (),
+                                        par_state->gdbarch (),
+                                        "wide_wide_character");
 }
 
 static struct type *