/* Parse expressions for GDB.
- Copyright (C) 1986, 89, 90, 91, 94, 98, 1999 Free Software Foundation, Inc.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001 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 "parser-defs.h"
#include "gdbcmd.h"
#include "symfile.h" /* for overlay functions */
+#include "inferior.h" /* for NUM_PSEUDO_REGS. NOTE: replace
+ with "gdbarch.h" when appropriate. */
+#include "doublest.h"
+
+\f
+/* Symbols which architectures can redefine. */
+
+/* Some systems have routines whose names start with `$'. Giving this
+ macro a non-zero value tells GDB's expression parser to check for
+ such routines when parsing tokens that begin with `$'.
+
+ On HP-UX, certain system routines (millicode) have names beginning
+ with `$' or `$$'. For example, `$$dyncall' is a millicode routine
+ that handles inter-space procedure calls on PA-RISC. */
+#ifndef SYMBOLS_CAN_START_WITH_DOLLAR
+#define SYMBOLS_CAN_START_WITH_DOLLAR (0)
+#endif
+
+
\f
/* Global variables declared in parser-defs.h (and commented there). */
struct expression *expout;
extern int hp_som_som_object_present;
-static void
-free_funcalls PARAMS ((void));
+static void free_funcalls (void *ignore);
-static void
-prefixify_expression PARAMS ((struct expression *));
+static void prefixify_expression (struct expression *);
static void
-prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
+prefixify_subexp (struct expression *, struct expression *, int, int);
-void _initialize_parse PARAMS ((void));
+void _initialize_parse (void);
/* Data structure for saving values of arglist_len for function calls whose
arguments contain other function calls. */
REGISTER_NAME; std_regs; or a target specific alias hook. */
int
-target_map_name_to_register (str, len)
- char *str;
- int len;
+target_map_name_to_register (char *str, int len)
{
int i;
return i;
}
- /* Try standard aliases */
+ /* Try pseudo-registers, if any. */
+ for (i = NUM_REGS; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i))
+ && STREQN (str, REGISTER_NAME (i), len))
+ {
+ return i;
+ }
+
+ /* Try standard aliases. */
for (i = 0; i < num_std_regs; i++)
if (std_regs[i].name && len == strlen (std_regs[i].name)
&& STREQN (str, std_regs[i].name, len))
saving the data about any containing call. */
void
-start_arglist ()
+start_arglist (void)
{
register struct funcall *new;
and restore the data for the containing function call. */
int
-end_arglist ()
+end_arglist (void)
{
register int val = arglist_len;
register struct funcall *call = funcall_chain;
funcall_chain = call->next;
arglist_len = call->arglist_len;
- free ((PTR) call);
+ xfree (call);
return val;
}
Used when there is an error inside parsing. */
static void
-free_funcalls ()
+free_funcalls (void *ignore)
{
register struct funcall *call, *next;
for (call = funcall_chain; call; call = next)
{
next = call->next;
- free ((PTR) call);
+ xfree (call);
}
}
\f
a register through here */
void
-write_exp_elt (expelt)
- union exp_element expelt;
+write_exp_elt (union exp_element expelt)
{
if (expout_ptr >= expout_size)
{
}
void
-write_exp_elt_opcode (expelt)
- enum exp_opcode expelt;
+write_exp_elt_opcode (enum exp_opcode expelt)
{
union exp_element tmp;
}
void
-write_exp_elt_sym (expelt)
- struct symbol *expelt;
+write_exp_elt_sym (struct symbol *expelt)
{
union exp_element tmp;
}
void
-write_exp_elt_block (b)
- struct block *b;
+write_exp_elt_block (struct block *b)
{
union exp_element tmp;
tmp.block = b;
}
void
-write_exp_elt_longcst (expelt)
- LONGEST expelt;
+write_exp_elt_longcst (LONGEST expelt)
{
union exp_element tmp;
}
void
-write_exp_elt_dblcst (expelt)
- DOUBLEST expelt;
+write_exp_elt_dblcst (DOUBLEST expelt)
{
union exp_element tmp;
}
void
-write_exp_elt_type (expelt)
- struct type *expelt;
+write_exp_elt_type (struct type *expelt)
{
union exp_element tmp;
}
void
-write_exp_elt_intern (expelt)
- struct internalvar *expelt;
+write_exp_elt_intern (struct internalvar *expelt)
{
union exp_element tmp;
void
-write_exp_string (str)
- struct stoken str;
+write_exp_string (struct stoken str)
{
register int len = str.length;
register int lenelt;
either end of the bitstring. */
void
-write_exp_bitstring (str)
- struct stoken str;
+write_exp_bitstring (struct stoken str)
{
register int bits = str.length; /* length in bits */
register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
static struct type *msym_unknown_symbol_type;
void
-write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
- struct minimal_symbol *msymbol;
- struct type *text_symbol_type;
- struct type *data_symbol_type;
+write_exp_msymbol (struct minimal_symbol *msymbol,
+ struct type *text_symbol_type,
+ struct type *data_symbol_type)
{
CORE_ADDR addr;
write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (lookup_pointer_type (builtin_type_void));
+ /* Let's make the type big enough to hold a 64-bit address. */
+ write_exp_elt_type (builtin_type_CORE_ADDR);
addr = SYMBOL_VALUE_ADDRESS (msymbol);
if (overlay_debugging)
*/
void
-write_dollar_variable (str)
- struct stoken str;
+write_dollar_variable (struct stoken str)
{
/* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
and $$digits (equivalent to $<-digits> if you could type that). */
- struct symbol *sym = NULL;
- struct minimal_symbol *msym = NULL;
-
int negate = 0;
int i = 1;
/* Double dollar means negate the number and add -1 as well.
if (i >= 0)
goto handle_register;
- /* On HP-UX, certain system routines (millicode) have names beginning
- with $ or $$, e.g. $$dyncall, which handles inter-space procedure
- calls on PA-RISC. Check for those, first. */
-
- sym = lookup_symbol (copy_name (str), (struct block *) NULL,
- VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
- if (sym)
- {
- write_exp_elt_opcode (OP_VAR_VALUE);
- write_exp_elt_block (block_found); /* set by lookup_symbol */
- write_exp_elt_sym (sym);
- write_exp_elt_opcode (OP_VAR_VALUE);
- return;
- }
- msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
- if (msym)
+ if (SYMBOLS_CAN_START_WITH_DOLLAR)
{
- write_exp_msymbol (msym,
- lookup_function_type (builtin_type_int),
- builtin_type_int);
- return;
+ struct symbol *sym = NULL;
+ struct minimal_symbol *msym = NULL;
+
+ /* On HP-UX, certain system routines (millicode) have names beginning
+ with $ or $$, e.g. $$dyncall, which handles inter-space procedure
+ calls on PA-RISC. Check for those, first. */
+
+ /* This code is not enabled on non HP-UX systems, since worst case
+ symbol table lookup performance is awful, to put it mildly. */
+
+ sym = lookup_symbol (copy_name (str), (struct block *) NULL,
+ VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
+ if (sym)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (block_found); /* set by lookup_symbol */
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return;
+ }
+ msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
+ if (msym)
+ {
+ write_exp_msymbol (msym,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ return;
+ }
}
/* Any other names starting in $ are debugger internal variables. */
{':', ':'};
struct symbol *
-parse_nested_classes_for_hpacc (name, len, token, class_prefix, argptr)
- char *name;
- int len;
- char **token;
- int *class_prefix;
- char **argptr;
+parse_nested_classes_for_hpacc (char *name, int len, char **token,
+ int *class_prefix, char **argptr)
{
/* Comment below comes from decode_line_1 which has very similar
code, which is called for "break" command parsing. */
struct symbol *sym_class = NULL;
struct symbol *sym_var = NULL;
struct type *t;
- register int i;
- int colons_found = 0;
int prefix_len = 0;
int done = 0;
char *q;
}
char *
-find_template_name_end (p)
- char *p;
+find_template_name_end (char *p)
{
int depth = 1;
int just_seen_right = 0;
of a string token. */
char *
-copy_name (token)
- struct stoken token;
+copy_name (struct stoken token)
{
memcpy (namecopy, token.ptr, token.length);
namecopy[token.length] = 0;
to prefix form (in which we can conveniently print or execute it). */
static void
-prefixify_expression (expr)
- register struct expression *expr;
+prefixify_expression (register struct expression *expr)
{
register int len =
sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
whose last exp_element is at index ENDPOS - 1 in EXPR. */
int
-length_of_subexp (expr, endpos)
- register struct expression *expr;
- register int endpos;
+length_of_subexp (register struct expression *expr, register int endpos)
{
register int oplen = 1;
register int args = 0;
In the process, convert it from suffix to prefix form. */
static void
-prefixify_subexp (inexpr, outexpr, inend, outbeg)
- register struct expression *inexpr;
- struct expression *outexpr;
- register int inend;
- int outbeg;
+prefixify_subexp (register struct expression *inexpr,
+ struct expression *outexpr, register int inend, int outbeg)
{
register int oplen = 1;
register int args = 0;
If COMMA is nonzero, stop if a comma is reached. */
struct expression *
-parse_exp_1 (stringptr, block, comma)
- char **stringptr;
- struct block *block;
- int comma;
+parse_exp_1 (char **stringptr, struct block *block, int comma)
{
struct cleanup *old_chain;
if (lexptr == 0 || *lexptr == 0)
error_no_arg ("expression to compute");
- old_chain = make_cleanup ((make_cleanup_func) free_funcalls, 0);
+ old_chain = make_cleanup (free_funcalls, 0 /*ignore*/);
funcall_chain = 0;
expression_context_block = block ? block : get_selected_block ();
expout = (struct expression *)
xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
expout->language_defn = current_language;
- make_cleanup ((make_cleanup_func) free_current_contents, &expout);
+ make_cleanup (free_current_contents, &expout);
if (current_language->la_parser ())
current_language->la_error (NULL);
to use up all of the contents of STRING. */
struct expression *
-parse_expression (string)
- char *string;
+parse_expression (char *string)
{
register struct expression *exp;
exp = parse_exp_1 (&string, 0, 0);
/* Stuff for maintaining a stack of types. Currently just used by C, but
probably useful for any language which declares its types "backwards". */
-void
-push_type (tp)
- enum type_pieces tp;
+static void
+check_type_stack_depth (void)
{
if (type_stack_depth == type_stack_size)
{
type_stack = (union type_stack_elt *)
xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
}
+}
+
+void
+push_type (enum type_pieces tp)
+{
+ check_type_stack_depth ();
type_stack[type_stack_depth++].piece = tp;
}
void
-push_type_int (n)
- int n;
+push_type_int (int n)
{
- if (type_stack_depth == type_stack_size)
- {
- type_stack_size *= 2;
- type_stack = (union type_stack_elt *)
- xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
- }
+ check_type_stack_depth ();
type_stack[type_stack_depth++].int_val = n;
}
+void
+push_type_address_space (char *string)
+{
+ push_type_int (address_space_name_to_int (string));
+}
+
enum type_pieces
-pop_type ()
+pop_type (void)
{
if (type_stack_depth)
return type_stack[--type_stack_depth].piece;
}
int
-pop_type_int ()
+pop_type_int (void)
{
if (type_stack_depth)
return type_stack[--type_stack_depth].int_val;
/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
as modified by all the stuff on the stack. */
struct type *
-follow_types (follow_type)
- struct type *follow_type;
+follow_types (struct type *follow_type)
{
int done = 0;
+ int make_const = 0;
+ int make_volatile = 0;
+ int make_addr_space = 0;
int array_size;
struct type *range_type;
{
case tp_end:
done = 1;
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
+ break;
+ case tp_const:
+ make_const = 1;
+ break;
+ case tp_volatile:
+ make_volatile = 1;
+ break;
+ case tp_space_identifier:
+ make_addr_space = pop_type_int ();
break;
case tp_pointer:
follow_type = lookup_pointer_type (follow_type);
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
break;
case tp_reference:
follow_type = lookup_reference_type (follow_type);
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
break;
case tp_array:
array_size = pop_type_int ();
return follow_type;
}
\f
-static void build_parse PARAMS ((void));
+static void build_parse (void);
static void
-build_parse ()
+build_parse (void)
{
int i;
i = 0;
/* fill it in */
#ifdef PC_REGNUM
- std_regs[i].name = "pc";
- std_regs[i].regnum = PC_REGNUM;
- i++;
+ if (PC_REGNUM >= 0)
+ {
+ std_regs[i].name = "pc";
+ std_regs[i].regnum = PC_REGNUM;
+ i++;
+ }
#endif
#ifdef FP_REGNUM
- std_regs[i].name = "fp";
- std_regs[i].regnum = FP_REGNUM;
- i++;
+ if (FP_REGNUM >= 0)
+ {
+ std_regs[i].name = "fp";
+ std_regs[i].regnum = FP_REGNUM;
+ i++;
+ }
#endif
#ifdef SP_REGNUM
- std_regs[i].name = "sp";
- std_regs[i].regnum = SP_REGNUM;
- i++;
+ if (SP_REGNUM >= 0)
+ {
+ std_regs[i].name = "sp";
+ std_regs[i].regnum = SP_REGNUM;
+ i++;
+ }
#endif
#ifdef PS_REGNUM
- std_regs[i].name = "ps";
- std_regs[i].regnum = PS_REGNUM;
- i++;
+ if (PS_REGNUM >= 0)
+ {
+ std_regs[i].name = "ps";
+ std_regs[i].regnum = PS_REGNUM;
+ i++;
+ }
#endif
memset (&std_regs[i], 0, sizeof (std_regs[i]));
}
void
-_initialize_parse ()
+_initialize_parse (void)
{
type_stack_size = 80;
type_stack_depth = 0;
register_gdbarch_swap (NULL, 0, build_parse);
add_show_from_set (
- add_set_cmd ("expressiondebug", class_maintenance, var_zinteger,
+ add_set_cmd ("expression", class_maintenance, var_zinteger,
(char *) &expressiondebug,
"Set expression debugging.\n\
When non-zero, the internal representation of expressions will be printed.",
- &setlist),
- &showlist);
+ &setdebuglist),
+ &showdebuglist);
}