X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fparse.c;h=0d0467d9ce23cb7882b2de80b38e29eb873cf774;hb=95c391b64aafe6d8868a99dd476e6f110011dd2d;hp=4815854c83105cedc92a8f6b6e688e2c4455be24;hpb=0875794a962c041bde76423e980875a467bb0bbe;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/parse.c b/gdb/parse.c index 4815854c83..0d0467d9ce 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1,8 +1,7 @@ /* Parse expressions for GDB. - Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 1986, 1989-2001, 2004-2005, 2007-2012 Free Software + Foundation, Inc. Modified from expread.y by the Department of Computer Science at the State University of New York at Buffalo, 1991. @@ -23,7 +22,7 @@ along with this program. If not, see . */ /* Parse an expression from text in a string, - and return the result as a struct expression pointer. + and return the result as a struct expression pointer. That structure contains arithmetic operations in reverse polish, with constants represented by operations that are followed by special data. See expression.h for the details of the format. @@ -91,16 +90,6 @@ int in_parse_field; '->'. 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; - -/* 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; static int expressiondebug = 0; static void @@ -124,8 +113,6 @@ show_parserdebug (struct ui_file *file, int from_tty, static void free_funcalls (void *ignore); -static int prefixify_expression (struct expression *); - static int prefixify_subexp (struct expression *, struct expression *, int, int); @@ -190,16 +177,45 @@ free_funcalls (void *ignore) } } -/* This page contains the functions for adding data to the struct expression +/* This page contains the functions for adding data to the struct expression being constructed. */ +/* See definition in parser-defs.h. */ + +void +initialize_expout (int initial_size, const struct language_defn *lang, + struct gdbarch *gdbarch) +{ + expout_size = initial_size; + expout_ptr = 0; + expout = xmalloc (sizeof (struct expression) + + EXP_ELEM_TO_BYTES (expout_size)); + expout->language_defn = lang; + expout->gdbarch = gdbarch; +} + +/* See definition in parser-defs.h. */ + +void +reallocate_expout (void) +{ + /* Record the actual number of expression elements, and then + reallocate the expression memory so that we free up any + excess elements. */ + + expout->nelts = expout_ptr; + expout = xrealloc ((char *) expout, + sizeof (struct expression) + + EXP_ELEM_TO_BYTES (expout_ptr)); +} + /* Add one element to the end of the expression. */ /* To avoid a bug in the Sun 4 compiler, we pass things that can fit into a register through here. */ -void -write_exp_elt (union exp_element expelt) +static void +write_exp_elt (const union exp_element *expelt) { if (expout_ptr >= expout_size) { @@ -208,7 +224,7 @@ write_exp_elt (union exp_element expelt) xrealloc ((char *) expout, sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size)); } - expout->elts[expout_ptr++] = expelt; + expout->elts[expout_ptr++] = *expelt; } void @@ -218,7 +234,7 @@ write_exp_elt_opcode (enum exp_opcode expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.opcode = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -228,7 +244,7 @@ write_exp_elt_sym (struct symbol *expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.symbol = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -238,7 +254,7 @@ write_exp_elt_block (struct block *b) memset (&tmp, 0, sizeof (union exp_element)); tmp.block = b; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -248,7 +264,7 @@ write_exp_elt_objfile (struct objfile *objfile) memset (&tmp, 0, sizeof (union exp_element)); tmp.objfile = objfile; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -258,7 +274,7 @@ write_exp_elt_longcst (LONGEST expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.longconst = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -268,7 +284,7 @@ write_exp_elt_dblcst (DOUBLEST expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.doubleconst = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -280,7 +296,7 @@ write_exp_elt_decfloatcst (gdb_byte expelt[16]) for (index = 0; index < 16; index++) tmp.decfloatconst[index] = expelt[index]; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -290,7 +306,7 @@ write_exp_elt_type (struct type *expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.type = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } void @@ -300,7 +316,7 @@ write_exp_elt_intern (struct internalvar *expelt) memset (&tmp, 0, sizeof (union exp_element)); tmp.internalvar = expelt; - write_exp_elt (tmp); + write_exp_elt (&tmp); } /* Add a string constant to the end of the expression. @@ -745,13 +761,28 @@ find_template_name_end (char *p) } +/* Return a null-terminated temporary copy of the name of a string token. + + Tokens that refer to names do so with explicit pointer and length, + so they can share the storage that lexptr is parsing. + When it is necessary to pass a name to a function that expects + a null-terminated string, the substring is copied out + into a separate block of storage. -/* Return a null-terminated temporary copy of the name - of a string token. */ + N.B. A single buffer is reused on each call. */ char * copy_name (struct stoken token) { + /* 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. */ + static char *namecopy; + static size_t namecopy_size; + /* Make sure there's enough space for the token. */ if (namecopy_size < token.length + 1) { @@ -765,14 +796,10 @@ copy_name (struct stoken token) return namecopy; } -/* Reverse an expression from suffix form (in which it is constructed) - to prefix form (in which we can conveniently print or execute it). - Ordinarily this always returns -1. However, if EXPOUT_LAST_STRUCT - is not -1 (i.e., we are trying to complete a field name), it will - return the index of the subexpression which is the left-hand-side - of the struct operation at EXPOUT_LAST_STRUCT. */ -static int +/* See comments on parser-defs.h. */ + +int prefixify_expression (struct expression *expr) { int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts); @@ -853,6 +880,7 @@ operator_length_standard (const struct expression *expr, int endpos, case OP_BOOL: case OP_LAST: case OP_INTERNALVAR: + case OP_VAR_ENTRY_VALUE: oplen = 3; break; @@ -963,7 +991,6 @@ operator_length_standard (const struct expression *expr, int endpos, /* C++ */ case OP_THIS: - case OP_OBJC_SELF: oplen = 2; break; @@ -1060,7 +1087,7 @@ prefixify_subexp (struct expression *inexpr, } /* Read an expression from the string *STRINGPTR points to, - parse it, and return a pointer to a struct expression that we malloc. + parse it, and return a pointer to a struct expression that we malloc. Use block BLOCK as the lexical context for variable names; if BLOCK is zero, use the block of the selected stack frame. Meanwhile, advance *STRINGPTR to point after the expression, @@ -1152,12 +1179,7 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma, else lang = current_language; - expout_size = 10; - expout_ptr = 0; - expout = (struct expression *) - xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size)); - expout->language_defn = lang; - expout->gdbarch = get_current_arch (); + initialize_expout (10, lang, get_current_arch ()); TRY_CATCH (except, RETURN_MASK_ALL) { @@ -1175,14 +1197,7 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma, discard_cleanups (old_chain); - /* Record the actual number of expression elements, and then - reallocate the expression memory so that we free up any - excess elements. */ - - expout->nelts = expout_ptr; - expout = (struct expression *) - xrealloc ((char *) expout, - sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr)); + reallocate_expout (); /* Convert expression from postfix form as generated by yacc parser, to a prefix form. */ @@ -1283,7 +1298,6 @@ int parse_float (const char *p, int len, DOUBLEST *d, const char **suffix) { char *copy; - char *s; int n, num; copy = xmalloc (len + 1); @@ -1353,6 +1367,49 @@ check_type_stack_depth (void) } } +/* A helper function for insert_type and insert_type_address_space. + This does work of expanding the type stack and inserting the new + element, ELEMENT, into the stack at location SLOT. */ + +static void +insert_into_type_stack (int slot, union type_stack_elt element) +{ + check_type_stack_depth (); + + if (slot < type_stack_depth) + memmove (&type_stack[slot + 1], &type_stack[slot], + (type_stack_depth - slot) * sizeof (union type_stack_elt)); + type_stack[slot] = element; + ++type_stack_depth; +} + +/* Insert a new type, TP, at the bottom of the type stack. If TP is + tp_pointer or tp_reference, it is inserted at the bottom. If TP is + a qualifier, it is inserted at slot 1 (just above a previous + tp_pointer) if there is anything on the stack, or simply pushed if + the stack is empty. Other values for TP are invalid. */ + +void +insert_type (enum type_pieces tp) +{ + union type_stack_elt element; + int slot; + + gdb_assert (tp == tp_pointer || tp == tp_reference + || tp == tp_const || tp == tp_volatile); + + /* If there is anything on the stack (we know it will be a + tp_pointer), insert the qualifier above it. Otherwise, simply + push this on the top of the stack. */ + if (type_stack_depth && (tp == tp_const || tp == tp_volatile)) + slot = 1; + else + slot = 0; + + element.piece = tp; + insert_into_type_stack (slot, element); +} + void push_type (enum type_pieces tp) { @@ -1367,10 +1424,32 @@ push_type_int (int n) type_stack[type_stack_depth++].int_val = n; } +/* Insert a tp_space_identifier and the corresponding address space + value into the stack. STRING is the name of an address space, as + recognized by address_space_name_to_int. If the stack is empty, + the new elements are simply pushed. If the stack is not empty, + this function assumes that the first item on the stack is a + tp_pointer, and the new values are inserted above the first + item. */ + void -push_type_address_space (char *string) +insert_type_address_space (char *string) { - push_type_int (address_space_name_to_int (parse_gdbarch, string)); + union type_stack_elt element; + int slot; + + /* If there is anything on the stack (we know it will be a + tp_pointer), insert the address space qualifier above it. + Otherwise, simply push this on the top of the stack. */ + if (type_stack_depth) + slot = 1; + else + slot = 0; + + element.piece = tp_space_identifier; + insert_into_type_stack (slot, element); + element.int_val = address_space_name_to_int (parse_gdbarch, string); + insert_into_type_stack (slot, element); } enum type_pieces