don't let bin2hex call strlen
[deliverable/binutils-gdb.git] / gdb / parse.c
index 1f9addf79d9f044ba98b757825cfcb20b9a472d4..11712896c5632652d4aa25000f2301442c484309 100644 (file)
@@ -1,7 +1,6 @@
 /* Parse expressions for GDB.
 
 /* Parse expressions for GDB.
 
-   Copyright (C) 1986, 1989-2001, 2004-2005, 2007-2012 Free Software
-   Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
 
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
@@ -33,7 +32,7 @@
 #include "defs.h"
 #include <ctype.h>
 #include "arch-utils.h"
 #include "defs.h"
 #include <ctype.h>
 #include "arch-utils.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "frame.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "frame.h"
@@ -71,26 +70,32 @@ const struct exp_descriptor exp_descriptor_standard =
 struct expression *expout;
 int expout_size;
 int expout_ptr;
 struct expression *expout;
 int expout_size;
 int expout_ptr;
-struct block *expression_context_block;
+const struct block *expression_context_block;
 CORE_ADDR expression_context_pc;
 CORE_ADDR expression_context_pc;
-struct block *innermost_block;
+const struct block *innermost_block;
 int arglist_len;
 static struct type_stack type_stack;
 int arglist_len;
 static struct type_stack type_stack;
-char *lexptr;
-char *prev_lexptr;
+const char *lexptr;
+const char *prev_lexptr;
 int paren_depth;
 int comma_terminates;
 
 int paren_depth;
 int comma_terminates;
 
-/* True if parsing an expression to find a field reference.  This is
-   only used by completion.  */
-int in_parse_field;
+/* 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;
 
 /* 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 char *expout_completion_name;
+
 \f
 \f
-static int expressiondebug = 0;
+static unsigned int expressiondebug = 0;
 static void
 show_expressiondebug (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 static void
 show_expressiondebug (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
@@ -115,9 +120,12 @@ static void free_funcalls (void *ignore);
 static int prefixify_subexp (struct expression *, struct expression *, int,
                             int);
 
 static int prefixify_subexp (struct expression *, struct expression *, int,
                             int);
 
-static struct expression *parse_exp_in_context (char **, CORE_ADDR,
-                                               struct block *, int, 
+static struct expression *parse_exp_in_context (const char **, CORE_ADDR,
+                                               const struct block *, int, 
                                                int, int *);
                                                int, int *);
+static struct expression *parse_exp_in_context_1 (const char **, CORE_ADDR,
+                                                 const struct block *, int,
+                                                 int, int *);
 
 void _initialize_parse (void);
 
 
 void _initialize_parse (void);
 
@@ -248,7 +256,7 @@ write_exp_elt_sym (struct symbol *expelt)
 }
 
 void
 }
 
 void
-write_exp_elt_block (struct block *b)
+write_exp_elt_block (const struct block *b)
 {
   union exp_element tmp;
 
 {
   union exp_element tmp;
 
@@ -488,13 +496,14 @@ write_exp_bitstring (struct stoken str)
    the expression.  */
 
 void
    the expression.  */
 
 void
-write_exp_msymbol (struct minimal_symbol *msymbol)
+write_exp_msymbol (struct bound_minimal_symbol bound_msym)
 {
 {
-  struct objfile *objfile = msymbol_objfile (msymbol);
+  struct minimal_symbol *msymbol = bound_msym.minsym;
+  struct objfile *objfile = bound_msym.objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
 
   CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (msymbol);
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
 
   CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (msymbol);
-  struct obj_section *section = SYMBOL_OBJ_SECTION (msymbol);
+  struct obj_section *section = SYMBOL_OBJ_SECTION (objfile, msymbol);
   enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);
   CORE_ADDR pc;
 
   enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);
   CORE_ADDR pc;
 
@@ -503,13 +512,14 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
   pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
   if (pc != addr)
     {
   pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
   if (pc != addr)
     {
-      struct minimal_symbol *ifunc_msym = lookup_minimal_symbol_by_pc (pc);
+      struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc);
 
       /* In this case, assume we have a code symbol instead of
         a data symbol.  */
 
 
       /* In this case, assume we have a code symbol instead of
         a data symbol.  */
 
-      if (ifunc_msym != NULL && MSYMBOL_TYPE (ifunc_msym) == mst_text_gnu_ifunc
-         && SYMBOL_VALUE_ADDRESS (ifunc_msym) == pc)
+      if (ifunc_msym.minsym != NULL
+         && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc
+         && SYMBOL_VALUE_ADDRESS (ifunc_msym.minsym) == pc)
        {
          /* A function descriptor has been resolved but PC is still in the
             STT_GNU_IFUNC resolver body (such as because inferior does not
        {
          /* A function descriptor has been resolved but PC is still in the
             STT_GNU_IFUNC resolver body (such as because inferior does not
@@ -579,9 +589,32 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
 void
 mark_struct_expression (void)
 {
 void
 mark_struct_expression (void)
 {
+  gdb_assert (parse_completion
+             && expout_tag_completion_type == TYPE_CODE_UNDEF);
   expout_last_struct = expout_ptr;
 }
 
   expout_last_struct = expout_ptr;
 }
 
+/* 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)
+{
+  gdb_assert (parse_completion
+             && expout_tag_completion_type == TYPE_CODE_UNDEF
+             && expout_completion_name == NULL
+             && expout_last_struct == -1);
+  gdb_assert (tag == TYPE_CODE_UNION
+             || tag == TYPE_CODE_STRUCT
+             || tag == TYPE_CODE_CLASS
+             || tag == TYPE_CODE_ENUM);
+  expout_tag_completion_type = tag;
+  expout_completion_name = xmalloc (length + 1);
+  memcpy (expout_completion_name, ptr, length);
+  expout_completion_name[length] = '\0';
+}
+
 \f
 /* Recognize tokens that start with '$'.  These include:
 
 \f
 /* Recognize tokens that start with '$'.  These include:
 
@@ -608,7 +641,7 @@ void
 write_dollar_variable (struct stoken str)
 {
   struct symbol *sym = NULL;
 write_dollar_variable (struct stoken str)
 {
   struct symbol *sym = NULL;
-  struct minimal_symbol *msym = NULL;
+  struct bound_minimal_symbol msym;
   struct internalvar *isym = NULL;
 
   /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
   struct internalvar *isym = NULL;
 
   /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
@@ -663,7 +696,7 @@ write_dollar_variable (struct stoken str)
      have names beginning with $ or $$.  Check for those, first.  */
 
   sym = lookup_symbol (copy_name (str), (struct block *) NULL,
      have names beginning with $ or $$.  Check for those, first.  */
 
   sym = lookup_symbol (copy_name (str), (struct block *) NULL,
-                      VAR_DOMAIN, (int *) NULL);
+                      VAR_DOMAIN, NULL);
   if (sym)
     {
       write_exp_elt_opcode (OP_VAR_VALUE);
   if (sym)
     {
       write_exp_elt_opcode (OP_VAR_VALUE);
@@ -672,8 +705,8 @@ write_dollar_variable (struct stoken str)
       write_exp_elt_opcode (OP_VAR_VALUE);
       return;
     }
       write_exp_elt_opcode (OP_VAR_VALUE);
       return;
     }
-  msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
-  if (msym)
+  msym = lookup_bound_minimal_symbol (copy_name (str));
+  if (msym.minsym)
     {
       write_exp_msymbol (msym);
       return;
     {
       write_exp_msymbol (msym);
       return;
@@ -700,8 +733,8 @@ handle_register:
 }
 
 
 }
 
 
-char *
-find_template_name_end (char *p)
+const char *
+find_template_name_end (const char *p)
 {
   int depth = 1;
   int just_seen_right = 0;
 {
   int depth = 1;
   int just_seen_right = 0;
@@ -938,6 +971,9 @@ operator_length_standard (const struct expression *expr, int endpos,
     case UNOP_ODD:
     case UNOP_ORD:
     case UNOP_TRUNC:
     case UNOP_ODD:
     case UNOP_ORD:
     case UNOP_TRUNC:
+    case OP_TYPEOF:
+    case OP_DECLTYPE:
+    case OP_TYPEID:
       oplen = 1;
       args = 1;
       break;
       oplen = 1;
       args = 1;
       break;
@@ -949,7 +985,6 @@ operator_length_standard (const struct expression *expr, int endpos,
       oplen++;
       break;
 
       oplen++;
       break;
 
-    case OP_LABELED:
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       args = 1;
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       args = 1;
@@ -965,12 +1000,6 @@ operator_length_standard (const struct expression *expr, int endpos,
       oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
       oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
-    case OP_BITSTRING:
-      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
-      oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
-      oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
-      break;
-
     case OP_ARRAY:
       oplen = 4;
       args = longest_to_int (expr->elts[endpos - 2].longconst);
     case OP_ARRAY:
       oplen = 4;
       args = longest_to_int (expr->elts[endpos - 2].longconst);
@@ -980,7 +1009,6 @@ operator_length_standard (const struct expression *expr, int endpos,
 
     case TERNOP_COND:
     case TERNOP_SLICE:
 
     case TERNOP_COND:
     case TERNOP_SLICE:
-    case TERNOP_SLICE_COUNT:
       args = 3;
       break;
 
       args = 3;
       break;
 
@@ -1103,11 +1131,21 @@ prefixify_subexp (struct expression *inexpr,
    If COMMA is nonzero, stop if a comma is reached.  */
 
 struct expression *
    If COMMA is nonzero, stop if a comma is reached.  */
 
 struct expression *
-parse_exp_1 (char **stringptr, CORE_ADDR pc, struct block *block, int comma)
+parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
+            int comma)
 {
   return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL);
 }
 
 {
   return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL);
 }
 
+static struct expression *
+parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
+                     const struct block *block,
+                     int comma, int void_context_p, int *out_subexp)
+{
+  return parse_exp_in_context_1 (stringptr, pc, block, comma,
+                                void_context_p, out_subexp);
+}
+
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
    no value is expected from the expression.
    OUT_SUBEXP is set when attempting to complete a field name; in this
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
    no value is expected from the expression.
    OUT_SUBEXP is set when attempting to complete a field name; in this
@@ -1116,11 +1154,12 @@ parse_exp_1 (char **stringptr, CORE_ADDR pc, struct block *block, int comma)
    is left untouched.  */
 
 static struct expression *
    is left untouched.  */
 
 static struct expression *
-parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
-                     int comma, int void_context_p, int *out_subexp)
+parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
+                       const struct block *block,
+                       int comma, int void_context_p, int *out_subexp)
 {
   volatile struct gdb_exception except;
 {
   volatile struct gdb_exception except;
-  struct cleanup *old_chain;
+  struct cleanup *old_chain, *inner_chain;
   const struct language_defn *lang = NULL;
   int subexp;
 
   const struct language_defn *lang = NULL;
   int subexp;
 
@@ -1130,6 +1169,9 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
   paren_depth = 0;
   type_stack.depth = 0;
   expout_last_struct = -1;
   paren_depth = 0;
   type_stack.depth = 0;
   expout_last_struct = -1;
+  expout_tag_completion_type = TYPE_CODE_UNDEF;
+  xfree (expout_completion_name);
+  expout_completion_name = NULL;
 
   comma_terminates = comma;
 
 
   comma_terminates = comma;
 
@@ -1187,7 +1229,13 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
   else
     lang = current_language;
 
   else
     lang = current_language;
 
+  /* get_current_arch may reset CURRENT_LANGUAGE via select_frame.
+     While we need CURRENT_LANGUAGE to be set to LANG (for lookup_symbol
+     and others called from *.y) ensure CURRENT_LANGUAGE gets restored
+     to the value matching SELECTED_FRAME as set by get_current_arch.  */
   initialize_expout (10, lang, get_current_arch ());
   initialize_expout (10, lang, get_current_arch ());
+  inner_chain = make_cleanup_restore_current_language ();
+  set_language (lang->la_language);
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
@@ -1196,15 +1244,13 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
     }
   if (except.reason < 0)
     {
     }
   if (except.reason < 0)
     {
-      if (! in_parse_field)
+      if (! parse_completion)
        {
          xfree (expout);
          throw_exception (except);
        }
     }
 
        {
          xfree (expout);
          throw_exception (except);
        }
     }
 
-  discard_cleanups (old_chain);
-
   reallocate_expout ();
 
   /* Convert expression from postfix form as generated by yacc
   reallocate_expout ();
 
   /* Convert expression from postfix form as generated by yacc
@@ -1223,6 +1269,9 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
   if (expressiondebug)
     dump_prefix_expression (expout, gdb_stdlog);
 
   if (expressiondebug)
     dump_prefix_expression (expout, gdb_stdlog);
 
+  do_cleanups (inner_chain);
+  discard_cleanups (old_chain);
+
   *stringptr = lexptr;
   return expout;
 }
   *stringptr = lexptr;
   return expout;
 }
@@ -1231,7 +1280,7 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
    to use up all of the contents of STRING.  */
 
 struct expression *
    to use up all of the contents of STRING.  */
 
 struct expression *
-parse_expression (char *string)
+parse_expression (const char *string)
 {
   struct expression *exp;
 
 {
   struct expression *exp;
 
@@ -1250,7 +1299,8 @@ parse_expression (char *string)
    *NAME must be freed by the caller.  */
 
 struct type *
    *NAME must be freed by the caller.  */
 
 struct type *
-parse_field_expression (char *string, char **name)
+parse_expression_for_completion (const char *string, char **name,
+                                enum type_code *code)
 {
   struct expression *exp = NULL;
   struct value *val;
 {
   struct expression *exp = NULL;
   struct value *val;
@@ -1259,12 +1309,21 @@ parse_field_expression (char *string, char **name)
 
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
 
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
-      in_parse_field = 1;
+      parse_completion = 1;
       exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
     }
       exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
     }
-  in_parse_field = 0;
+  parse_completion = 0;
   if (except.reason < 0 || ! exp)
     return NULL;
   if (except.reason < 0 || ! exp)
     return NULL;
+
+  if (expout_tag_completion_type != TYPE_CODE_UNDEF)
+    {
+      *code = expout_tag_completion_type;
+      *name = expout_completion_name;
+      expout_completion_name = NULL;
+      return NULL;
+    }
+
   if (expout_last_struct == -1)
     {
       xfree (exp);
   if (expout_last_struct == -1)
     {
       xfree (exp);
@@ -1857,15 +1916,15 @@ _initialize_parse (void)
   type_stack.depth = 0;
   type_stack.elements = NULL;
 
   type_stack.depth = 0;
   type_stack.elements = NULL;
 
-  add_setshow_zinteger_cmd ("expression", class_maintenance,
-                           &expressiondebug,
-                           _("Set expression debugging."),
-                           _("Show expression debugging."),
-                           _("When non-zero, the internal representation "
-                             "of expressions will be printed."),
-                           NULL,
-                           show_expressiondebug,
-                           &setdebuglist, &showdebuglist);
+  add_setshow_zuinteger_cmd ("expression", class_maintenance,
+                            &expressiondebug,
+                            _("Set expression debugging."),
+                            _("Show expression debugging."),
+                            _("When non-zero, the internal representation "
+                              "of expressions will be printed."),
+                            NULL,
+                            show_expressiondebug,
+                            &setdebuglist, &showdebuglist);
   add_setshow_boolean_cmd ("parser", class_maintenance,
                            &parser_debug,
                           _("Set parser debugging."),
   add_setshow_boolean_cmd ("parser", class_maintenance,
                            &parser_debug,
                           _("Set parser debugging."),
This page took 0.03429 seconds and 4 git commands to generate.