/* Parse expressions for GDB.
- Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
Modified from expread.y by the Department of Computer Science at the
State University of New York at Buffalo, 1991.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* Parse an expression from text in a string,
and return the result as a struct expression pointer.
#include "value.h"
#include "command.h"
#include "language.h"
+#include "f-lang.h"
#include "parser-defs.h"
#include "gdbcmd.h"
#include "symfile.h" /* for overlay functions */
#include "doublest.h"
#include "gdb_assert.h"
#include "block.h"
+#include "source.h"
+#include "objfiles.h"
/* Standard set of definitions for printing, dumping, prefixifying,
* and evaluating expressions. */
int type_stack_depth, type_stack_size;
char *lexptr;
char *prev_lexptr;
-char *namecopy;
int paren_depth;
int comma_terminates;
+
+/* A temporary buffer for identifiers, so we can null-terminate them.
+
+ We allocate this with xrealloc. parse_exp_1 used to allocate with
+ alloca, using the size of the whole expression as a conservative
+ estimate of the space needed. However, macro expansion can
+ introduce names longer than the original expression; there's no
+ practical way to know beforehand how large that might be. */
+char *namecopy;
+size_t namecopy_size;
\f
static int expressiondebug = 0;
+static void
+show_expressiondebug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Expression debugging is %s.\n"), value);
+}
static void free_funcalls (void *ignore);
write_exp_elt_opcode (enum exp_opcode expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.opcode = expelt;
write_exp_elt_sym (struct symbol *expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.symbol = expelt;
write_exp_elt_block (struct block *b)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.block = b;
write_exp_elt (tmp);
}
+void
+write_exp_elt_objfile (struct objfile *objfile)
+{
+ union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
+ tmp.objfile = objfile;
+ write_exp_elt (tmp);
+}
+
void
write_exp_elt_longcst (LONGEST expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.longconst = expelt;
write_exp_elt_dblcst (DOUBLEST expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.doubleconst = expelt;
write_exp_elt_type (struct type *expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.type = expelt;
write_exp_elt_intern (struct internalvar *expelt)
{
union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
tmp.internalvar = expelt;
static struct type *msym_text_symbol_type;
static struct type *msym_data_symbol_type;
static struct type *msym_unknown_symbol_type;
+static struct type *msym_tls_symbol_type;
void
write_exp_msymbol (struct minimal_symbol *msymbol,
write_exp_elt_opcode (OP_LONG);
+ if (SYMBOL_BFD_SECTION (msymbol)
+ && SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL)
+ {
+ bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner;
+ struct objfile *ofp;
+
+ ALL_OBJFILES (ofp)
+ if (ofp->obfd == bfd)
+ break;
+
+ write_exp_elt_opcode (UNOP_MEMVAL_TLS);
+ write_exp_elt_objfile (ofp);
+ write_exp_elt_type (msym_tls_symbol_type);
+ write_exp_elt_opcode (UNOP_MEMVAL_TLS);
+ return;
+ }
+
write_exp_elt_opcode (UNOP_MEMVAL);
switch (msymbol->type)
{
/* Handle tokens that refer to machine registers:
$ followed by a register name. */
- i = frame_map_name_to_regnum (deprecated_selected_frame,
+ i = frame_map_name_to_regnum (deprecated_safe_get_selected_frame (),
str.ptr + 1, str.length - 1);
if (i >= 0)
goto handle_register;
char *
copy_name (struct stoken token)
{
+ /* Make sure there's enough space for the token. */
+ if (namecopy_size < token.length + 1)
+ {
+ namecopy_size = token.length + 1;
+ namecopy = xrealloc (namecopy, token.length + 1);
+ }
+
memcpy (namecopy, token.ptr, token.length);
namecopy[token.length] = 0;
+
return namecopy;
}
\f
{
int oplen = 1;
int args = 0;
+ enum f90_range_type range_type;
int i;
if (endpos < 1)
args = 1;
break;
+ case UNOP_MEMVAL_TLS:
+ oplen = 4;
+ args = 1;
+ break;
+
case UNOP_ABS:
case UNOP_CAP:
case UNOP_CHR:
oplen = 2;
break;
+ case OP_F90_RANGE:
+ oplen = 3;
+
+ range_type = longest_to_int (expr->elts[endpos - 2].longconst);
+ switch (range_type)
+ {
+ case LOW_BOUND_DEFAULT:
+ case HIGH_BOUND_DEFAULT:
+ args = 1;
+ break;
+ case BOTH_BOUND_DEFAULT:
+ args = 0;
+ break;
+ case NONE_BOUND_DEFAULT:
+ args = 2;
+ break;
+ }
+
+ break;
+
default:
args = 1 + (i < (int) BINOP_END);
}
old_chain = make_cleanup (free_funcalls, 0 /*ignore*/);
funcall_chain = 0;
+ /* If no context specified, try using the current frame, if any. */
+
+ if (!block)
+ block = get_selected_block (&expression_context_pc);
+
+ /* Fall back to using the current source static context, if any. */
+
+ if (!block)
+ {
+ struct symtab_and_line cursal = get_current_source_symtab_and_line ();
+ if (cursal.symtab)
+ block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK);
+ }
+
+ /* Save the context, if specified by caller, or found above. */
+
if (block)
{
expression_context_block = block;
expression_context_pc = BLOCK_START (block);
}
- else
- expression_context_block = get_selected_block (&expression_context_pc);
- namecopy = (char *) alloca (strlen (lexptr) + 1);
expout_size = 10;
expout_ptr = 0;
expout = (struct expression *)
init_type (TYPE_CODE_INT, 1, 0,
"<variable (not text or data), no debug info>",
NULL);
+
+ msym_tls_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<thread local variable, no debug info>", NULL);
}
/* This function avoids direct calls to fprintf
Show expression debugging."), _("\
When non-zero, the internal representation of expressions will be printed."),
NULL,
- NULL, /* FIXME: i18n: */
+ show_expressiondebug,
&setdebuglist, &showdebuglist);
}