+Wed Nov 25 07:17:13 1992 Fred Fish (fnf@cygnus.com)
+
+ * parse.c (write_exp_string): Complete rewrite to store string
+ contants as a leading explicit length, followed by the string data,
+ followed by a trailing explicit length.
+ * eval.c (evaluate_subexp), expprint.c (print_subexp),
+ parse.c (length_of_subexp), parse.c (prefixify_subexp):
+ Use recorded explicit length of strings in expression elements,
+ rather than strlen. Adjust code to skip over strings stored in
+ expression elements, and code to access strings, to account for
+ new leading explicit size expression element.
+ * parse.c (length_of_subexp): Test for minimum endpos of 1, not
+ 0, to avoid negative expression element indices.
+ * valops.c (search_struct_method): Minor whitespace change.
+
Mon Nov 23 11:14:15 1992 Fred Fish (fnf@cygnus.com)
* c-exp.y (yylex): Add tempbuf, tempbufindex, and tempbufsize,
}
/* Add a string constant to the end of the expression.
- Follow it by its length in bytes, as a separate exp_element. */
+
+ String constants are stored by first writing an expression element
+ that contains the length of the string, then stuffing the string
+ constant itself into however many expression elements are needed
+ to hold it, and then writing another expression element that contains
+ the length of the string. I.E. an expression element at each end of
+ the string records the string length, so you can skip over the
+ expression elements containing the actual string bytes from either
+ end of the string. Note that this also allows gdb to handle
+ strings with embedded null bytes, as is required for some languages.
+
+ Don't be fooled by the fact that the string is null byte terminated,
+ this is strictly for the convenience of debugging gdb itself. Gdb
+ Gdb does not depend up the string being null terminated, since the
+ actual length is recorded in expression elements at each end of the
+ string. The null byte is taken into consideration when computing how
+ many expression elements are required to hold the string constant, of
+ course. */
+
void
write_exp_string (str)
struct stoken str;
{
register int len = str.length;
- register int lenelt
- = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+ register int lenelt;
+ register char *strdata;
- expout_ptr += lenelt;
+ /* Compute the number of expression elements required to hold the string
+ (including a null byte terminator), along with one expression element
+ at each end to record the actual string length (not including the
+ null byte terminator). */
- if (expout_ptr >= expout_size)
+ lenelt = 2 + (len + sizeof (union exp_element)) / sizeof (union exp_element);
+
+ /* Ensure that we have enough available expression elements to store
+ everything. */
+
+ if ((expout_ptr + lenelt) >= expout_size)
{
- expout_size = max (expout_size * 2, expout_ptr + 10);
+ expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
expout = (struct expression *)
xrealloc ((char *) expout, (sizeof (struct expression)
+ (expout_size * sizeof (union exp_element))));
}
- memcpy ((char *) &expout->elts[expout_ptr - lenelt], str.ptr, len);
- ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+
+ /* Write the leading length expression element (which advances the current
+ expression element index), then write the string constant followed by a
+ terminating null byte, and then write the trailing length expression
+ element. */
+
+ write_exp_elt_longcst ((LONGEST) len);
+ strdata = (char *) &expout->elts[expout_ptr];
+ memcpy (strdata, str.ptr, len);
+ *(strdata + len) = '\0';
+ expout_ptr += lenelt - 2;
write_exp_elt_longcst ((LONGEST) len);
}
\f
register int args = 0;
register int i;
- if (endpos < 0)
+ if (endpos < 1)
error ("?error in length_of_subexp");
i = (int) expr->elts[endpos - 1].opcode;
{
/* C++ */
case OP_SCOPE:
- oplen = 4 + ((expr->elts[endpos - 2].longconst
+ oplen = 5 + ((longest_to_int (expr->elts[endpos - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
case OP_FUNCALL:
oplen = 3;
- args = 1 + expr->elts[endpos - 2].longconst;
+ args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
break;
case UNOP_MAX:
case UNOP_MIN:
oplen = 3;
- args = 0;
break;
case BINOP_VAL:
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
+ /* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 3 + ((expr->elts[endpos - 2].longconst
+ oplen = 4 + ((longest_to_int (expr->elts[endpos - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
/* Modula-2 */
case BINOP_MULTI_SUBSCRIPT:
oplen=3;
- args = 1 + expr->elts[endpos- 2].longconst;
+ args = 1 + longest_to_int (expr->elts[endpos- 2].longconst);
break;
case BINOP_ASSIGN_MODIFY:
{
/* C++ */
case OP_SCOPE:
- oplen = 4 + ((inexpr->elts[inend - 2].longconst
+ oplen = 5 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
case OP_FUNCALL:
oplen = 3;
- args = 1 + inexpr->elts[inend - 2].longconst;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
break;
case UNOP_MIN:
case UNOP_MAX:
oplen = 3;
- args = 0;
break;
case UNOP_CAST:
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
+ /* fall through */
case OP_M2_STRING:
case OP_STRING:
- oplen = 3 + ((inexpr->elts[inend - 2].longconst
+ oplen = 4 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
+ sizeof (union exp_element))
/ sizeof (union exp_element));
-
break;
case TERNOP_COND:
/* Modula-2 */
case BINOP_MULTI_SUBSCRIPT:
oplen=3;
- args = 1 + inexpr->elts[inend - 2].longconst;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
break;
/* C++ */