Index: gdb/parse.c |
diff --git a/gdb/parse.c b/gdb/parse.c |
index 529c517c25e612486575390ba4da5b113095f214..4b9ca5de05a225b1e7d8842bae5613d07471154c 100644 |
--- a/gdb/parse.c |
+++ b/gdb/parse.c |
@@ -1,7 +1,6 @@ |
/* Parse expressions for GDB. |
- Copyright (C) 1986, 1989-2001, 2004-2005, 2007-2012 Free Software |
- Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
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 "gdb_string.h" |
+#include <string.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 block *expression_context_block; |
+const struct block *expression_context_block; |
CORE_ADDR expression_context_pc; |
-struct block *innermost_block; |
+const struct block *innermost_block; |
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; |
-/* 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; |
+ |
+/* 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; |
+ |
-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) |
@@ -115,9 +120,12 @@ static void free_funcalls (void *ignore); |
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 *); |
+static struct expression *parse_exp_in_context_1 (const char **, CORE_ADDR, |
+ const struct block *, int, |
+ int, int *); |
void _initialize_parse (void); |
@@ -248,7 +256,7 @@ write_exp_elt_sym (struct symbol *expelt) |
} |
void |
-write_exp_elt_block (struct block *b) |
+write_exp_elt_block (const struct block *b) |
{ |
union exp_element tmp; |
@@ -488,13 +496,14 @@ write_exp_bitstring (struct stoken str) |
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 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; |
@@ -503,13 +512,14 @@ write_exp_msymbol (struct minimal_symbol *msymbol) |
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_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. */ |
- 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 |
@@ -579,9 +589,32 @@ write_exp_msymbol (struct minimal_symbol *msymbol) |
void |
mark_struct_expression (void) |
{ |
+ gdb_assert (parse_completion |
+ && expout_tag_completion_type == TYPE_CODE_UNDEF); |
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'; |
+} |
+ |
/* Recognize tokens that start with '$'. These include: |
@@ -608,7 +641,7 @@ void |
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) |
@@ -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, |
- VAR_DOMAIN, (int *) NULL); |
+ VAR_DOMAIN, NULL); |
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; |
} |
- 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; |
@@ -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; |
@@ -910,10 +943,16 @@ operator_length_standard (const struct expression *expr, int endpos, |
oplen = 3; |
break; |
- case BINOP_VAL: |
- case UNOP_CAST: |
+ case UNOP_CAST_TYPE: |
case UNOP_DYNAMIC_CAST: |
case UNOP_REINTERPRET_CAST: |
+ case UNOP_MEMVAL_TYPE: |
+ oplen = 1; |
+ args = 2; |
+ break; |
+ |
+ case BINOP_VAL: |
+ case UNOP_CAST: |
case UNOP_MEMVAL: |
oplen = 3; |
args = 1; |
@@ -932,6 +971,9 @@ operator_length_standard (const struct expression *expr, int endpos, |
case UNOP_ODD: |
case UNOP_ORD: |
case UNOP_TRUNC: |
+ case OP_TYPEOF: |
+ case OP_DECLTYPE: |
+ case OP_TYPEID: |
oplen = 1; |
args = 1; |
break; |
@@ -943,7 +985,6 @@ operator_length_standard (const struct expression *expr, int endpos, |
oplen++; |
break; |
- case OP_LABELED: |
case STRUCTOP_STRUCT: |
case STRUCTOP_PTR: |
args = 1; |
@@ -959,12 +1000,6 @@ operator_length_standard (const struct expression *expr, int endpos, |
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); |
@@ -974,7 +1009,6 @@ operator_length_standard (const struct expression *expr, int endpos, |
case TERNOP_COND: |
case TERNOP_SLICE: |
- case TERNOP_SLICE_COUNT: |
args = 3; |
break; |
@@ -1097,11 +1131,21 @@ prefixify_subexp (struct expression *inexpr, |
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); |
} |
+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 |
@@ -1110,11 +1154,12 @@ parse_exp_1 (char **stringptr, CORE_ADDR pc, struct block *block, int comma) |
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; |
- struct cleanup *old_chain; |
+ struct cleanup *old_chain, *inner_chain; |
const struct language_defn *lang = NULL; |
int subexp; |
@@ -1124,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; |
+ expout_tag_completion_type = TYPE_CODE_UNDEF; |
+ xfree (expout_completion_name); |
+ expout_completion_name = NULL; |
comma_terminates = comma; |
@@ -1181,7 +1229,13 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block, |
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 ()); |
+ inner_chain = make_cleanup_restore_current_language (); |
+ set_language (lang->la_language); |
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
@@ -1190,15 +1244,13 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block, |
} |
if (except.reason < 0) |
{ |
- if (! in_parse_field) |
+ if (! parse_completion) |
{ |
xfree (expout); |
throw_exception (except); |
} |
} |
- discard_cleanups (old_chain); |
- |
reallocate_expout (); |
/* Convert expression from postfix form as generated by yacc |
@@ -1217,6 +1269,9 @@ parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block, |
if (expressiondebug) |
dump_prefix_expression (expout, gdb_stdlog); |
+ do_cleanups (inner_chain); |
+ discard_cleanups (old_chain); |
+ |
*stringptr = lexptr; |
return expout; |
} |
@@ -1225,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 * |
-parse_expression (char *string) |
+parse_expression (const char *string) |
{ |
struct expression *exp; |
@@ -1244,7 +1299,8 @@ parse_expression (char *string) |
*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; |
@@ -1253,12 +1309,21 @@ parse_field_expression (char *string, char **name) |
TRY_CATCH (except, RETURN_MASK_ERROR) |
{ |
- in_parse_field = 1; |
+ parse_completion = 1; |
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 (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); |
@@ -1732,8 +1797,6 @@ operator_check_standard (struct expression *exp, int pos, |
case OP_SCOPE: |
case OP_TYPE: |
case UNOP_CAST: |
- case UNOP_DYNAMIC_CAST: |
- case UNOP_REINTERPRET_CAST: |
case UNOP_MAX: |
case UNOP_MEMVAL: |
case UNOP_MIN: |
@@ -1853,15 +1916,15 @@ _initialize_parse (void) |
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."), |