/* 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.
#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"
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;
+
\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 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);
}
void
-write_exp_elt_block (struct block *b)
+write_exp_elt_block (const struct block *b)
{
union exp_element tmp;
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;
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
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';
+}
+
\f
/* Recognize tokens that start with '$'. These include:
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)
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);
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;
}
-char *
-find_template_name_end (char *p)
+const char *
+find_template_name_end (const char *p)
{
int depth = 1;
int just_seen_right = 0;
case UNOP_ODD:
case UNOP_ORD:
case UNOP_TRUNC:
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
+ case OP_TYPEID:
oplen = 1;
args = 1;
break;
oplen++;
break;
- case OP_LABELED:
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
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 TERNOP_COND:
case TERNOP_SLICE:
- case TERNOP_SLICE_COUNT:
args = 3;
break;
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
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;
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;
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)
{
}
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
if (expressiondebug)
dump_prefix_expression (expout, gdb_stdlog);
+ do_cleanups (inner_chain);
+ discard_cleanups (old_chain);
+
*stringptr = lexptr;
return expout;
}
to use up all of the contents of STRING. */
struct expression *
-parse_expression (char *string)
+parse_expression (const char *string)
{
struct expression *exp;
*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;
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);
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."),