* RFA: Changes to allow extensions to operator set
@ 2003-09-01 9:39 Paul Hilfinger
2003-09-04 2:18 ` Andrew Cagney
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Paul Hilfinger @ 2003-09-01 9:39 UTC (permalink / raw)
To: gdb-patches
After a long hiatus, I am back. In response to the last time I started
to submit Ada-related patches, Andrew Cagney wrote that it really
ought not be necessary to extend the set of operators in expression.h
to add Ada (or any other language, presumably). OK, here is a set
of non-Ada-specific patches that allow one to add new language modules
without adding to the operators in expression.h.
While I was in here, I made a few other modifications that I hope meet
with general approval:
1. There was essentially duplicate code in prefixify_subexp and
length_of_subexp. I have factored out the duplication. [In the
process, by the way, I happened to notice that BINOP_VAL was
defined only in length_of_subexp, and indeed that there appears to
be no code anywhere to handle its evaluation.]
2. Currently, the function dump_prefix_expression is used to dump
postfix expressions and dump_postfix_expression is used to dump
prefix expressions. It is probably a sign of the weakening
effects of age on the intellect that I found this confusing, and
have renamed dump_prefix_expression to dump_raw_expression (because
in principle it doesn't really care whether the expression is
pre- or postfix), and dump_postfix_expression to dump_prefix_expression.
3. The current dump_prefix_expression tries to first print the expression
it is dumping with print_expression. This doesn't work, however,
because print_expression operates on prefix expressions, and
the current dump_prefix_expression is only used on postfix
expressions. I simply removed the print_expression.
4. I removed register declarations in routines I touched, just on
general principles. [I believe that all register declarations in
GDB and much other GNU software are anachronistic holdovers from
some bygone era. GCC ignores them, or so I'm told, except to
insure that & is not applied to register variables. Furthermore,
my impression is that many of these declarations would be
inappropriate even in non-optimizing compilers, since they often
seem to be used rather indiscriminantly in ways that are likely to
favor putting the wrong things into registers.]
One explanatory comment as to technique: I bundled up a related set of
function pointers into a new type (struct exp_descriptor) and put a
pointer to the structure into the language_defn vectors (i.e., as
opposed to just adding the four functions contained in it to the
language_defn vector). I thought it looked neater, but more to the
point, it avoided some awkward dependency issues.
I leave it to other interested parties to move language-specific
operators currently in expression.h, eval.c, etc., back into their
respective language-specific files, should they wish to do so. We
only intend to use this change for the Ada-related operators.
No test suite regressions seen on GNU Linux.
P. Hilfinger
Ada Core Technologies, Inc.
ChangeLog:
2003-09-01 Paul N. Hilfinger <hilfingr@nile.gnat.com>
* parser-defs.h (struct exp_descriptor): New definition, containing
language-specific info for printing, prefixifying, and
dumping expressions.
(exp_descriptor_standard): Declare new variable.
(print_subexp): Make global and declare here (from expprint.c).
(dump_subexp): Ditto.
(dump_subexp_body_standard): Declare.
(operator_length): Declare.
(operator_length_standard): Declare.
(op_name_standard): Declare.
(print_subexp): Declare.
(print_subexp_standard): Declare.
* language.h (struct language_defn): Add la_exp_desc field to hold
pointer to table for language-specific operators.
* parse.c (length_of_subexp): Use operator_length to get
operator lengths and arities for operators.
Remove register declarations.
Move most code to new operator_length_standard function.
(operator_length_standard): New function taking most code from
length_of_subexp.
(prefixify_expression): Remove register declarations.
(prefixify_subexp): Remove large case and use operator_length instead.
Remove register declarations.
(operator_length): New function. Uses language-specific information.
(exp_descriptor_standard): New constant.
(parse_exp_1): Use renamings:
dump_prefix_expression => dump_raw_expression and
dump_postfix_expression => dump_prefix_expression.
* expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0
and OP_EXTENDED_LAST.
(dump_prefix_expression): Rename to ...
(dump_raw_expression): New name.
(dump_postfix_expression): Rename to ...
(dump_prefix_expression): New name.
* expprint.c (print_subexp): Make global, remove static declaration.
Remove register declarations. Use language-specific print_subexp.
Move most existing code to print_subexp_standard.
(print_subexp_standard): New function, containing code formerly in
print_subexp.
(op_name): Add expression to argument signature.
Use langauge-specific op_name.
Move most code to op_name_standard.
(op_name_standard): New function, containing code formerly in op_name.
(dump_subexp): Make global. Add comment.
Use new version of op_name function.
Use language-specific dump_subexp_body, and move most existing code to
dump_subexp_body_standard.
(dump_subexp_body): New function.
(dump_subexp_body_standard): New function, containing code formerly
in dump_subexp.
(dump_prefix_expression): Rename to dump_raw_expression.
Remove attempt to print the expression via print_expression: it can't
work before the expression is prefixified!
Use new version of op_name.
(dump_raw_expression): Renamed from dump_prefix_expression.
(dump_postfix_expression): Rename to dump_prefix_expression, since
that's what it does!
Remove 'note' parameter, since this routine must be used on
prefixified expression.
(dump_prefix_expression): Renamed from dump_postfix_expression.
* language.c (unknown_language): Add default la_exp_desc field.
(auto_language): Ditto.
(local_language): Ditto.
* jv-lang.c (java_language): Ditto.
* f-lang.c (f_language_defn): Ditto.
* c-lang.c (c_language_defn): Ditto.
(cplus_language_defn): Ditto.
(asm_language_defn): Ditto.
(minimal_language_defn): Ditto.
* p-lang.c (pascal_language_defn): Ditto.
* m2-lang.c (m2_language_defn): Ditto.
* scm-lang.c (scm_language_defn): Ditto.
* objc-lang.c (objc_language_defn): Ditto.
Index: current-public.21/gdb/p-lang.c
--- current-public.21/gdb/p-lang.c Tue, 17 Jun 2003 02:39:19 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.2 644)
+++ submit.8(w)/gdb/p-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.3 644)
@@ -451,6 +451,7 @@ const struct language_defn pascal_langua
range_check_on,
type_check_on,
case_sensitive_on,
+ &exp_descriptor_standard,
pascal_parse,
pascal_error,
evaluate_subexp_standard,
Index: current-public.21/gdb/c-lang.c
--- current-public.21/gdb/c-lang.c Tue, 17 Jun 2003 02:39:19 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.3 644)
+++ submit.8(w)/gdb/c-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.4 644)
@@ -543,6 +543,7 @@ const struct language_defn c_language_de
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
evaluate_subexp_standard,
@@ -599,6 +600,7 @@ const struct language_defn cplus_languag
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
evaluate_subexp_standard,
@@ -632,6 +634,7 @@ const struct language_defn asm_language_
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
evaluate_subexp_standard,
@@ -670,6 +673,7 @@ const struct language_defn minimal_langu
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
evaluate_subexp_standard,
Index: current-public.21/gdb/expprint.c
--- current-public.21/gdb/expprint.c Fri, 18 Jul 2003 23:35:25 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3 644)
+++ submit.8(w)/gdb/expprint.c Tue, 26 Aug 2003 03:08:13 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3.1.2 644)
@@ -36,11 +36,6 @@
#include <ctype.h>
#endif
-/* Prototypes for local functions */
-
-static void print_subexp (struct expression *, int *, struct ui_file *,
- enum precedence);
-
void
print_expression (struct expression *exp, struct ui_file *stream)
{
@@ -53,13 +48,21 @@ print_expression (struct expression *exp
if the precedence of the main operator of this subexpression is less,
parentheses are needed here. */
-static void
-print_subexp (register struct expression *exp, register int *pos,
+void
+print_subexp (struct expression *exp, int *pos,
struct ui_file *stream, enum precedence prec)
{
- register unsigned tem;
- register const struct op_print *op_print_tab;
- register int pc;
+ exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
+}
+
+/* Standard implementation of print_subexp for use in language_defn vectors. */
+void
+print_subexp_standard (struct expression *exp, int *pos,
+ struct ui_file *stream, enum precedence prec)
+{
+ unsigned tem;
+ const struct op_print *op_print_tab;
+ int pc;
unsigned nargs;
register char *op_str;
int assign_modify = 0;
@@ -547,10 +550,22 @@ op_string (enum exp_opcode op)
/* Support for dumping the raw data from expressions in a human readable
form. */
-static char *op_name (int opcode);
+static char *op_name (struct expression *, enum exp_opcode);
+static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
+
+/* Name for OPCODE, when it appears in expression EXP. */
static char *
-op_name (int opcode)
+op_name (struct expression *exp, enum exp_opcode opcode)
+{
+ return exp->language_defn->la_exp_desc->op_name (opcode);
+}
+
+/* Default name for the standard operator OPCODE (i.e., one defined in
+ the definition of enum exp_opcode). */
+
+char *
+op_name_standard (enum exp_opcode opcode)
{
switch (opcode)
{
@@ -737,8 +752,8 @@ op_name (int opcode)
}
void
-dump_prefix_expression (struct expression *exp, struct ui_file *stream,
- char *note)
+dump_raw_expression (struct expression *exp, struct ui_file *stream,
+ char *note)
{
int elt;
char *opcode_name;
@@ -747,11 +762,6 @@ dump_prefix_expression (struct expressio
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_host_address (exp, stream);
- fprintf_filtered (stream, ", %s:\nExpression: `", note);
- if (exp->elts[0].opcode != OP_TYPE)
- print_expression (exp, stream);
- else
- fprintf_filtered (stream, "Type printing not yet supported....");
fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
exp->language_defn->la_name, exp->nelts,
(long) sizeof (union exp_element));
@@ -760,7 +770,7 @@ dump_prefix_expression (struct expressio
for (elt = 0; elt < exp->nelts; elt++)
{
fprintf_filtered (stream, "\t%5d ", elt);
- opcode_name = op_name (exp->elts[elt].opcode);
+ opcode_name = op_name (exp, exp->elts[elt].opcode);
fprintf_filtered (stream, "%20s ", opcode_name);
print_longest (stream, 'd', 0, exp->elts[elt].longconst);
@@ -778,10 +788,11 @@ dump_prefix_expression (struct expressio
}
}
-static int dump_subexp (struct expression *exp, struct ui_file *stream,
- int elt);
+/* Dump the subexpression of prefix expression EXP whose operator is at
+ position ELT onto STREAM. Returns the position of the next
+ subexpression in EXP. */
-static int
+int
dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
{
static int indent = 0;
@@ -794,9 +805,34 @@ dump_subexp (struct expression *exp, str
fprintf_filtered (stream, " ");
indent += 2;
- fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
+ fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode));
+
+ elt = dump_subexp_body (exp, stream, elt);
- switch (exp->elts[elt++].opcode)
+ indent -= 2;
+
+ return elt;
+}
+
+/* Dump the operands of prefix expression EXP whose opcode is at
+ position ELT onto STREAM. Returns the position of the next
+ subexpression in EXP. */
+
+static int
+dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
+{
+ return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
+}
+
+/* Default value for subexp_body in exp_descriptor vector. */
+
+int
+dump_subexp_body_standard (struct expression *exp,
+ struct ui_file *stream, int elt)
+{
+ int opcode = exp->elts[elt++].opcode;
+
+ switch (opcode)
{
case TERNOP_COND:
case TERNOP_SLICE:
@@ -914,7 +950,7 @@ dump_subexp (struct expression *exp, str
break;
case OP_FUNCALL:
{
- int nargs;
+ int i, nargs;
nargs = longest_to_int (exp->elts[elt].longconst);
@@ -1006,20 +1042,17 @@ dump_subexp (struct expression *exp, str
fprintf_filtered (stream, "Unknown format");
}
- indent -= 2;
-
return elt;
}
void
-dump_postfix_expression (struct expression *exp, struct ui_file *stream,
- char *note)
+dump_prefix_expression (struct expression *exp, struct ui_file *stream)
{
int elt;
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_host_address (exp, stream);
- fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
if (exp->elts[0].opcode != OP_TYPE)
print_expression (exp, stream);
else
Index: current-public.21/gdb/expression.h
--- current-public.21/gdb/expression.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.2 644)
+++ submit.8(w)/gdb/expression.h Wed, 27 Aug 2003 00:24:54 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.5 644)
@@ -322,7 +322,22 @@ enum exp_opcode
OP_EXPRSTRING,
/* An Objective C Foundation Class NSString constant */
- OP_OBJC_NSSTRING
+ OP_OBJC_NSSTRING,
+
+ /* First extension operator. Individual language modules define
+ extra operators they need as constants with values
+ OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
+ enumerated type definition:
+ enum foo_extension_operator {
+ BINOP_MOGRIFY = OP_EXTENDED0,
+ BINOP_FROB,
+ ...
+ }; */
+ OP_EXTENDED0,
+
+ /* Last possible extension operator. Defined simply to specify a
+ minimum range for the representation. */
+ OP_EXTENDED_LAST = 0xff
};
union exp_element
@@ -393,11 +408,7 @@ extern void print_expression (struct exp
extern char *op_string (enum exp_opcode);
-extern void dump_prefix_expression (struct expression *,
- struct ui_file *,
- char *);
-extern void dump_postfix_expression (struct expression *,
- struct ui_file *,
- char *);
+extern void dump_raw_expression (struct expression *, struct ui_file *, char *);
+extern void dump_prefix_expression (struct expression *, struct ui_file *);
#endif /* !defined (EXPRESSION_H) */
Index: current-public.21/gdb/f-lang.c
--- current-public.21/gdb/f-lang.c Tue, 17 Jun 2003 02:39:19 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.2 644)
+++ submit.8(w)/gdb/f-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.3 644)
@@ -462,6 +462,7 @@ const struct language_defn f_language_de
range_check_on,
type_check_on,
case_sensitive_off,
+ &exp_descriptor_standard,
f_parse, /* parser */
f_error, /* parser error function */
evaluate_subexp_standard,
Index: current-public.21/gdb/jv-lang.c
--- current-public.21/gdb/jv-lang.c Tue, 17 Jun 2003 02:41:56 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3 644)
+++ submit.8(w)/gdb/jv-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3.1.1 644)
@@ -1047,6 +1047,7 @@ const struct language_defn java_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
java_parse,
java_error,
evaluate_subexp_java,
Index: current-public.21/gdb/language.c
--- current-public.21/gdb/language.c Fri, 22 Aug 2003 00:46:52 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1 644)
+++ submit.8(w)/gdb/language.c Fri, 22 Aug 2003 10:47:57 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1.1.1 644)
@@ -1267,6 +1267,7 @@ const struct language_defn unknown_langu
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
@@ -1301,6 +1302,7 @@ const struct language_defn auto_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
@@ -1334,6 +1336,7 @@ const struct language_defn local_languag
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
Index: current-public.21/gdb/language.h
--- current-public.21/gdb/language.h Fri, 22 Aug 2003 00:46:52 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1 644)
+++ submit.8(w)/gdb/language.h Fri, 22 Aug 2003 10:48:02 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1.1.1 644)
@@ -167,6 +167,11 @@ struct language_defn
/* Default case sensitivity */
enum case_sensitivity la_case_sensitivity;
+ /* Definitions related to expression printing, prefixifying, and
+ dumping */
+
+ const struct exp_descriptor *la_exp_desc;
+
/* Parser function. */
int (*la_parser) (void);
Index: current-public.21/gdb/m2-lang.c
--- current-public.21/gdb/m2-lang.c Tue, 17 Jun 2003 02:39:19 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.2 644)
+++ submit.8(w)/gdb/m2-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.3 644)
@@ -415,6 +415,7 @@ const struct language_defn m2_language_d
range_check_on,
type_check_on,
case_sensitive_on,
+ &exp_descriptor_standard,
m2_parse, /* parser */
m2_error, /* parser error function */
evaluate_subexp_standard,
Index: current-public.21/gdb/parse.c
--- current-public.21/gdb/parse.c Fri, 18 Jul 2003 23:35:25 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4 644)
+++ submit.8(w)/gdb/parse.c Mon, 01 Sep 2003 00:10:14 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4.1.2 644)
@@ -50,6 +50,16 @@
#include "gdb_assert.h"
#include "block.h"
+/* Standard set of definitions for printing, dumping, and prefixifying
+ * expressions. */
+
+const struct exp_descriptor exp_descriptor_standard =
+ {
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard
+ };
\f
/* Symbols which architectures can redefine. */
@@ -769,12 +779,11 @@ copy_name (struct stoken token)
to prefix form (in which we can conveniently print or execute it). */
static void
-prefixify_expression (register struct expression *expr)
+prefixify_expression (struct expression *expr)
{
- register int len =
- sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
- register struct expression *temp;
- register int inpos = expr->nelts, outpos = 0;
+ int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
+ struct expression *temp;
+ int inpos = expr->nelts, outpos = 0;
temp = (struct expression *) alloca (len);
@@ -784,18 +793,48 @@ prefixify_expression (register struct ex
prefixify_subexp (temp, expr, inpos, outpos);
}
-/* Return the number of exp_elements in the subexpression of EXPR
- whose last exp_element is at index ENDPOS - 1 in EXPR. */
+/* Return the number of exp_elements in the postfix subexpression
+ of EXPR whose operator is at index ENDPOS - 1 in EXPR. */
int
-length_of_subexp (register struct expression *expr, register int endpos)
+length_of_subexp (struct expression *expr, int endpos)
+{
+ int oplen, args, i;
+
+ operator_length (expr, endpos, &oplen, &args);
+
+ while (args > 0)
+ {
+ oplen += length_of_subexp (expr, endpos - oplen);
+ args--;
+ }
+
+ return oplen;
+}
+
+/* Sets *OPLENP to the length of the operator whose (last) index is
+ ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that
+ operator takes. */
+
+void
+operator_length (struct expression *expr, int endpos, int *oplenp, int *argsp)
{
- register int oplen = 1;
- register int args = 0;
- register int i;
+ expr->language_defn->la_exp_desc->operator_length (expr, endpos,
+ oplenp, argsp);
+}
+
+/* Default value for operator_length in exp_descriptor vectors. */
+
+void
+operator_length_standard (struct expression *expr, int endpos,
+ int *oplenp, int *argsp)
+{
+ int oplen = 1;
+ int args = 0;
+ int i;
if (endpos < 1)
- error ("?error in length_of_subexp");
+ error ("?error in operator_length_standard");
i = (int) expr->elts[endpos - 1].opcode;
@@ -916,13 +955,8 @@ length_of_subexp (register struct expres
args = 1 + (i < (int) BINOP_END);
}
- while (args > 0)
- {
- oplen += length_of_subexp (expr, endpos - oplen);
- args--;
- }
-
- return oplen;
+ *oplenp = oplen;
+ *argsp = args;
}
/* Copy the subexpression ending just before index INEND in INEXPR
@@ -930,135 +964,16 @@ length_of_subexp (register struct expres
In the process, convert it from suffix to prefix form. */
static void
-prefixify_subexp (register struct expression *inexpr,
- struct expression *outexpr, register int inend, int outbeg)
+prefixify_subexp (struct expression *inexpr,
+ struct expression *outexpr, int inend, int outbeg)
{
- register int oplen = 1;
- register int args = 0;
- register int i;
+ int oplen;
+ int args;
+ int i;
int *arglens;
enum exp_opcode opcode;
- /* Compute how long the last operation is (in OPLEN),
- and also how many preceding subexpressions serve as
- arguments for it (in ARGS). */
-
- opcode = inexpr->elts[inend - 1].opcode;
- switch (opcode)
- {
- /* C++ */
- case OP_SCOPE:
- oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
- oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
-
- case OP_LONG:
- case OP_DOUBLE:
- case OP_VAR_VALUE:
- oplen = 4;
- break;
-
- case OP_TYPE:
- case OP_BOOL:
- case OP_LAST:
- case OP_REGISTER:
- case OP_INTERNALVAR:
- oplen = 3;
- break;
-
- case OP_COMPLEX:
- oplen = 1;
- args = 2;
- break;
-
- case OP_FUNCALL:
- case OP_F77_UNDETERMINED_ARGLIST:
- oplen = 3;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- case OP_OBJC_MSGCALL: /* Objective C message (method) call */
- oplen = 4;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- case UNOP_MIN:
- case UNOP_MAX:
- oplen = 3;
- break;
-
- case UNOP_CAST:
- case UNOP_MEMVAL:
- oplen = 3;
- args = 1;
- break;
-
- case UNOP_ABS:
- case UNOP_CAP:
- case UNOP_CHR:
- case UNOP_FLOAT:
- case UNOP_HIGH:
- case UNOP_ODD:
- case UNOP_ORD:
- case UNOP_TRUNC:
- oplen = 1;
- args = 1;
- break;
-
- case STRUCTOP_STRUCT:
- case STRUCTOP_PTR:
- case OP_LABELED:
- args = 1;
- /* fall through */
- case OP_M2_STRING:
- case OP_STRING:
- case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant */
- case OP_OBJC_SELECTOR: /* Objective C "@selector" pseudo-op */
- case OP_NAME:
- case OP_EXPRSTRING:
- oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
- oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
-
- case OP_BITSTRING:
- oplen = longest_to_int (inexpr->elts[inend - 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 (inexpr->elts[inend - 2].longconst);
- args -= longest_to_int (inexpr->elts[inend - 3].longconst);
- args += 1;
- break;
-
- case TERNOP_COND:
- case TERNOP_SLICE:
- case TERNOP_SLICE_COUNT:
- args = 3;
- break;
-
- case BINOP_ASSIGN_MODIFY:
- oplen = 3;
- args = 2;
- break;
-
- /* Modula-2 */
- case MULTI_SUBSCRIPT:
- oplen = 3;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- /* C++ */
- case OP_THIS:
- case OP_OBJC_SELF:
- oplen = 2;
- break;
-
- default:
- args = 1 + ((int) opcode < (int) BINOP_END);
- }
+ operator_length (inexpr, inend, &oplen, &args);
/* Copy the final operator itself, from the end of the input
to the beginning of the output. */
@@ -1156,14 +1071,13 @@ parse_exp_1 (char **stringptr, struct bl
parser, to a prefix form. */
if (expressiondebug)
- dump_prefix_expression (expout, gdb_stdlog,
- "before conversion to prefix form");
+ dump_raw_expression (expout, gdb_stdlog,
+ "before conversion to prefix form");
prefixify_expression (expout);
if (expressiondebug)
- dump_postfix_expression (expout, gdb_stdlog,
- "after conversion to prefix form");
+ dump_prefix_expression (expout, gdb_stdlog);
*stringptr = lexptr;
return expout;
Index: current-public.21/gdb/parser-defs.h
--- current-public.21/gdb/parser-defs.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2 644)
+++ submit.8(w)/gdb/parser-defs.h Mon, 01 Sep 2003 00:08:49 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2.1.2 644)
@@ -159,6 +159,17 @@ extern int pop_type_int (void);
extern int length_of_subexp (struct expression *, int);
+extern int dump_subexp (struct expression *, struct ui_file *, int);
+
+extern int dump_subexp_body_standard (struct expression *,
+ struct ui_file *, int);
+
+extern void operator_length (struct expression *, int, int *, int *);
+
+extern void operator_length_standard (struct expression *, int, int *, int *);
+
+extern char *op_name_standard (enum exp_opcode);
+
extern struct type *follow_types (struct type *);
/* During parsing of a C expression, the pointer to the next character
@@ -219,6 +230,42 @@ struct op_print
For a unary operator: 1 iff postfix. */
int right_assoc;
};
+
+/* Information needed to print and prefixify expressions for a given
+ language. */
+
+struct exp_descriptor
+ {
+ /* Print subexpression */
+ void (*print_subexp) (struct expression *, int *, struct ui_file *,
+ enum precedence);
+
+ /* Returns number of exp_elements needed to represent an operator and
+ the number of subexpressions it takes. */
+ void (*operator_length) (struct expression*, int, int*, int *);
+
+ /* Name of this operator for dumping purposes. */
+ char *(*op_name) (enum exp_opcode);
+
+ /* Dump the rest of this (prefix) expression after the operator
+ itself has been printed. See dump_subexp_body_standard in
+ (expprint.c). */
+ int (*dump_subexp_body) (struct expression *, struct ui_file *, int);
+ };
+
+
+/* Default descriptor containing standard definitions of all
+ elements. */
+extern const struct exp_descriptor exp_descriptor_standard;
+
+/* Functions used by language-specific extended operators to (recursively)
+ print/dump subexpressions */
+
+extern void print_subexp (struct expression *, int *, struct ui_file *,
+ enum precedence);
+
+extern void print_subexp_standard (struct expression *, int *,
+ struct ui_file *, enum precedence);
/* Function used to avoid direct calls to fprintf
in the code generated by the bison parser. */
Index: current-public.21/gdb/scm-lang.c
--- current-public.21/gdb/scm-lang.c Tue, 17 Jun 2003 02:39:19 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.3 644)
+++ submit.8(w)/gdb/scm-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.4 644)
@@ -241,6 +241,7 @@ const struct language_defn scm_language_
range_check_off,
type_check_off,
case_sensitive_off,
+ &exp_descriptor_standard,
scm_parse,
c_error,
evaluate_subexp_scm,
Index: current-public.21/gdb/objc-lang.c
--- current-public.21/gdb/objc-lang.c Tue, 17 Jun 2003 02:41:56 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4 644)
+++ submit.8(w)/gdb/objc-lang.c Sat, 26 Jul 2003 22:59:24 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4.1.1 644)
@@ -659,6 +659,7 @@ const struct language_defn objc_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
objc_parse,
objc_error,
evaluate_subexp_standard,
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-01 9:39 RFA: Changes to allow extensions to operator set Paul Hilfinger
@ 2003-09-04 2:18 ` Andrew Cagney
2003-09-05 8:32 ` Paul Hilfinger
2003-09-05 15:57 ` Andrew Cagney
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Andrew Cagney @ 2003-09-04 2:18 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
> 4. I removed register declarations in routines I touched, just on
> general principles. [I believe that all register declarations in
> GDB and much other GNU software are anachronistic holdovers from
> some bygone era. GCC ignores them, or so I'm told, except to
> insure that & is not applied to register variables. Furthermore,
> my impression is that many of these declarations would be
> inappropriate even in non-optimizing compilers, since they often
> seem to be used rather indiscriminantly in ways that are likely to
> favor putting the wrong things into registers.]
BTW,
This is a separate but obvious (and tedious) change (you'll notice I
occasionally expunge "register" from random files). Can you first up
just expunge the "register" on the files you're interested in? Doing
this keeps the cosmetic and functional changes separate.
Oh, gdb.base/store.exp abuses "register" to create a few test senarios.
enjoy,
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-04 2:18 ` Andrew Cagney
@ 2003-09-05 8:32 ` Paul Hilfinger
0 siblings, 0 replies; 11+ messages in thread
From: Paul Hilfinger @ 2003-09-05 8:32 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
> This is a separate but obvious (and tedious) change (you'll notice I
> occasionally expunge "register" from random files). Can you first up
> just expunge the "register" on the files you're interested in? Doing
> this keeps the cosmetic and functional changes separate.
Sure.
> Oh, gdb.base/store.exp abuses "register" to create a few test senarios.
Well, I'm keeping my hands off the testsuite for this round anyway.
Paul
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-01 9:39 RFA: Changes to allow extensions to operator set Paul Hilfinger
2003-09-04 2:18 ` Andrew Cagney
@ 2003-09-05 15:57 ` Andrew Cagney
2003-09-05 16:23 ` Andrew Cagney
2003-09-05 16:29 ` Andrew Cagney
3 siblings, 0 replies; 11+ messages in thread
From: Andrew Cagney @ 2003-09-05 15:57 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
> 2. Currently, the function dump_prefix_expression is used to dump
> postfix expressions and dump_postfix_expression is used to dump
> prefix expressions. It is probably a sign of the weakening
> effects of age on the intellect that I found this confusing, and
> have renamed dump_prefix_expression to dump_raw_expression (because
> in principle it doesn't really care whether the expression is
> pre- or postfix), and dump_postfix_expression to dump_prefix_expression.
>
> 3. The current dump_prefix_expression tries to first print the expression
> it is dumping with print_expression. This doesn't work, however,
> because print_expression operates on prefix expressions, and
> the current dump_prefix_expression is only used on postfix
> expressions. I simply removed the print_expression.
Bang head against table. I think it's a sign that the code is rarely
exercised. Yes, ok.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-01 9:39 RFA: Changes to allow extensions to operator set Paul Hilfinger
2003-09-04 2:18 ` Andrew Cagney
2003-09-05 15:57 ` Andrew Cagney
@ 2003-09-05 16:23 ` Andrew Cagney
2003-09-06 11:13 ` Paul Hilfinger
2003-09-05 16:29 ` Andrew Cagney
3 siblings, 1 reply; 11+ messages in thread
From: Andrew Cagney @ 2003-09-05 16:23 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
> +/* Information needed to print and prefixify expressions for a given
> + language. */
> +
> +struct exp_descriptor
> + {
> + /* Print subexpression */
> + void (*print_subexp) (struct expression *, int *, struct ui_file *,
> + enum precedence);
> +
> + /* Returns number of exp_elements needed to represent an operator and
> + the number of subexpressions it takes. */
> + void (*operator_length) (struct expression*, int, int*, int *);
> +
> + /* Name of this operator for dumping purposes. */
> + char *(*op_name) (enum exp_opcode);
> +
> + /* Dump the rest of this (prefix) expression after the operator
> + itself has been printed. See dump_subexp_body_standard in
> + (expprint.c). */
> + int (*dump_subexp_body) (struct expression *, struct ui_file *, int);
> + };
Here is a method to handle operator evaluation missing? Otherwize won't
the jumbo switch in evaluate_subexp_standard still need to be modified
as languages add additional operators.
I was thinking more of
struct operator
{
const char *name;
void (*length) (struct expression *exp, struct operator *op, ?others?);
int (*eval) (...);
?others?
int opcode; // for backward compatibility
};
struct exp_descriptor
{
int num_oper;
const struct operator *op; // is **op easier?
dump_...;
print_...;
}
which is a step beyond what you posted. It should completly eliminate
the need to add to that OP enum list (and eliminate the enum).
To create backward compatibility, the default table would just have all
its length() and eval() members pointing at the default_* methods you
posted (they could pull the "enum exp_opcode" ->opcode). Ada would have
a larger table.
Does this work?
> One explanatory comment as to technique: I bundled up a related set of
> function pointers into a new type (struct exp_descriptor) and put a
> pointer to the structure into the language_defn vectors (i.e., as
> opposed to just adding the four functions contained in it to the
> language_defn vector). I thought it looked neater, but more to the
> point, it avoided some awkward dependency issues.
Yes, definitly. Like the strategy.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-01 9:39 RFA: Changes to allow extensions to operator set Paul Hilfinger
` (2 preceding siblings ...)
2003-09-05 16:23 ` Andrew Cagney
@ 2003-09-05 16:29 ` Andrew Cagney
3 siblings, 0 replies; 11+ messages in thread
From: Andrew Cagney @ 2003-09-05 16:29 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
> 1. There was essentially duplicate code in prefixify_subexp and
> length_of_subexp. I have factored out the duplication. [In the
> process, by the way, I happened to notice that BINOP_VAL was
> defined only in length_of_subexp, and indeed that there appears to
> be no code anywhere to handle its evaluation.]
If I understand it correctly, this refactoring (hey I get to use a
buzword) making operator_length global and then calling it from
length_of_subexp is independant of the other stuff, so yes, it can go in.
Nice cleanup.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-05 16:23 ` Andrew Cagney
@ 2003-09-06 11:13 ` Paul Hilfinger
2003-09-11 18:55 ` Andrew Cagney
0 siblings, 1 reply; 11+ messages in thread
From: Paul Hilfinger @ 2003-09-06 11:13 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
> [Where] is a method to handle operator evaluation missing? Otherwize won't
> the jumbo switch in evaluate_subexp_standard still need to be modified
> as languages add additional operators.
Not so. The language vector already contains
/* Evaluate an expression. */
struct value *(*evaluate_exp) (struct type *, struct expression *,
int *, enum noside);
Let me make clear that we do have an existence proof that the changes
I submitted suffice, since we have used them (in patches still to
come) to extend the operator set with the extra Ada operators WITHOUT
extensions to expression.h, expprint.c, etc. So if something is
missing, it can't be all that much.
> I was thinking more of
> struct operator
> {
> const char *name;
> void (*length) (struct expression *exp, struct operator *op, ?others?);
> int (*eval) (...);
> ...
> };
> struct exp_descriptor
> {
> int num_oper;
> const struct operator *op; // is **op easier?
> ...
In short, you want to object orient these suckers. Well as a matter
of fact, I actually implemented something along these lines in an earlier
iteration. It certainly can be made to work. However,
1. To do it consistently requires a much more extensive and somewhat
tedious change to the existing machinery (which works well enough)
giving me even more opportunities to overlook something ("overlook"
== "screw up").
2. For example, to really do it up brown you'd want to modify all the
.y files so that instead of emitting the integer codes directly, as they
do now, there'd be operator-specific emission routines for parsing, so
that, e.g., sequences like
write_exp_elt_opcode (OP_FUNCALL);
write_exp_elt_longcst ((LONGEST) end_arglist ());
write_exp_elt_opcode (OP_FUNCALL); }
became
OP_FUNCALL->write_exp_longest ((LONGEST) end_arglist ());
or some such thing.
3. Personally, I find that this is one of those gray cases where the OOP
style gains little in clarity. That is, we have choice of writing (A) an
enumeration type and a few big functions of the form
<type> <func> (<args>) {
<prologue>
switch (<op>) {
case A:
<A code>
case B:
<B code>
}
}
and of writing (B) LOTS of little functions of the form
<type> <func_X> (<args>) {
<prologue>
<X code>
}
plus a big dispatch vector (of struct operators, in your case) naming them.
Perhaps I am overinterpreting your suggestion, but I see a lot of effort
for little gain in clarity (maybe <0) in going from the current style (A)
to style (B). In fact, for these reasons, I went so far as to tear up my
original, more bject-oriented version of this extension mechanism and
go back to the mechanism I submitted, as a simpler and more conservative
solution.
Now if and when David Carlton gets his way and we eventually re-do GDB
in C++, it might be time to revisit this decision, since C++ would
remove the tedious table building and welter of names.
Paul
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-06 11:13 ` Paul Hilfinger
@ 2003-09-11 18:55 ` Andrew Cagney
2003-09-13 8:58 ` Paul Hilfinger
2003-09-18 9:20 ` Paul Hilfinger
0 siblings, 2 replies; 11+ messages in thread
From: Andrew Cagney @ 2003-09-11 18:55 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
>> [Where] is a method to handle operator evaluation missing? Otherwize won't
>> the jumbo switch in evaluate_subexp_standard still need to be modified
>> as languages add additional operators.
>
>
> Not so. The language vector already contains
>
> /* Evaluate an expression. */
> struct value *(*evaluate_exp) (struct type *, struct expression *,
> int *, enum noside);
Ah. Is ada doing anything special with that - something that will bite
later? Looking at the existing languages - they appear to simply be
overriding select operators but nothing more.
> In short, you want to object orient these suckers. Well as a matter
> of fact, I actually implemented something along these lines in an earlier
> iteration. It certainly can be made to work. However,
Yes.
> 1. To do it consistently requires a much more extensive and somewhat
> tedious change to the existing machinery (which works well enough)
> giving me even more opportunities to overlook something ("overlook"
> == "screw up").
True. Need to look for baby steps.
> 2. For example, to really do it up brown you'd want to modify all the
> .y files so that instead of emitting the integer codes directly, as they
> do now, there'd be operator-specific emission routines for parsing, so
> that, e.g., sequences like
>
> write_exp_elt_opcode (OP_FUNCALL);
> write_exp_elt_longcst ((LONGEST) end_arglist ());
> write_exp_elt_opcode (OP_FUNCALL); }
>
> became
>
> OP_FUNCALL->write_exp_longest ((LONGEST) end_arglist ());
>
> or some such thing.
Yes, eventually. In an as yet un-scheduled future round.
> 3. Personally, I find that this is one of those gray cases where the OOP
> style gains little in clarity. That is, we have choice of writing (A) an
> enumeration type and a few big functions of the form
>
> <type> <func> (<args>) {
> <prologue>
> switch (<op>) {
> case A:
> <A code>
> case B:
> <B code>
> }
> }
This, I think, is easier short term.
> and of writing (B) LOTS of little functions of the form
>
> <type> <func_X> (<args>) {
> <prologue>
> <X code>
> }
This, I think, is easier long term - it's clear exactly which methods
need to be implemented to make the new object functional - no chasing
after all those switch statements to figure out if/where each needs to
be changed.
It took me some time to understand why the OO style really was better
and how come Java omiting enum's was a good thing.
> plus a big dispatch vector (of struct operators, in your case) naming them.
> Perhaps I am overinterpreting your suggestion, but I see a lot of effort
> for little gain in clarity (maybe <0) in going from the current style (A)
> to style (B). In fact, for these reasons, I went so far as to tear up my
> original, more bject-oriented version of this extension mechanism and
> go back to the mechanism I submitted, as a simpler and more conservative
> solution.
sed would quickly create the initial table.
> Now if and when David Carlton gets his way and we eventually re-do GDB
> in C++, it might be time to revisit this decision, since C++ would
> remove the tedious table building and welter of names.
Not if, when. GDB's beeing re-done OO regardless of the C++ schedule.
Can you please move evaluate_exp to the new expresion descriptor (is
anything else missing?); modify:
> + OP_OBJC_NSSTRING,
> +
> + /* First extension operator. Individual language modules define
> + extra operators they need as constants with values
> + OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
> + enumerated type definition:
> + enum foo_extension_operator {
> + BINOP_MOGRIFY = OP_EXTENDED0,
> + BINOP_FROB,
> + ...
> + }; */
> + OP_EXTENDED0,
> +
> + /* Last possible extension operator. Defined simply to specify a
> + minimum range for the representation. */
> + OP_EXTENDED_LAST = 0xff
to provide a an explicit and finite number of extended operators
OP_EXTENDED_0, OP_EXTENDED_1, ... (I'm assuming Ada will contain enum {
OP_ADA_... = OP_EXTENDED_0, ... }); add a note that this is an interum
and it will go away.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-11 18:55 ` Andrew Cagney
@ 2003-09-13 8:58 ` Paul Hilfinger
2003-09-18 9:20 ` Paul Hilfinger
1 sibling, 0 replies; 11+ messages in thread
From: Paul Hilfinger @ 2003-09-13 8:58 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Andrew,
>> Not so. The language vector already contains
>>
>> /* Evaluate an expression. */
>> struct value *(*evaluate_exp) (struct type *, struct expression *,
>> int *, enum noside);
>Ah. Is ada doing anything special with that - something that will bite
>later? Looking at the existing languages - they appear to simply be
>overriding select operators but nothing more.
Nope; it overrides some stuff, and (of course), handles the new operators
it defines.
> It took me some time to understand why the OO style really was better
> and how come Java omiting enum's was a good thing.
So I guess I don't have to ask how you feel about C# putting them back
in (:->).
> Not if, when. GDB's being re-done OO regardless of the C++ schedule.
Yes, and none too soon in general. It's just that for this particular
application --- large sets of operator objects with a fairly small set
of virtual operations in the interface --- I've always found the gains
achieved by the OO formulation to be just a tad disappointing. I find
moreover that to make things readably concise in C or C++, I generally
end up resorting to macros, a separate pre-processing step, or a
specialized implementation language for dealing with expression trees.
The GDB community appears to have an almost superstitious aversion to
macros which I've never entirely understood (probably because I
instinctively write only beautifully clear macro definitions myself
;->). Pre-processing tends to confuse debuggers, and specialized
implementation languages are generally not widely implemented.
> Can you please move evaluate_exp to the new expresion descriptor (is
> anything else missing?); modify:
Sure; sounds sensible.
> to provide a an explicit and finite number of extended operators
> OP_EXTENDED_0, OP_EXTENDED_1, ... (I'm assuming Ada will contain enum {
> OP_ADA_... = OP_EXTENDED_0, ... }); add a note that this is an interum
> and it will go away.
OK.
Paul
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-11 18:55 ` Andrew Cagney
2003-09-13 8:58 ` Paul Hilfinger
@ 2003-09-18 9:20 ` Paul Hilfinger
2003-09-22 17:04 ` Andrew Cagney
1 sibling, 1 reply; 11+ messages in thread
From: Paul Hilfinger @ 2003-09-18 9:20 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Andrew,
Here is a version of the patch I submitted earlier that I believe addresses
your comments from last time. The specific changes from last time that you
wanted were
1. Putting evaluate_exp into the exp_descriptor structure.
2. Modifying the description of the OP_EXTENDED_LAST operator slightly
and including a note indicating the temporary nature of the extension
mechanism and our intention to OOize expression handling in general.
Other parts you previously approved. If these changes were what you
were after, I will commit.
Paul
ChangeLog:
2003-09-18 Paul N. Hilfinger <hilfingr@nile.gnat.com>
* parser-defs.h (struct exp_descriptor): New definition, containing
language-specific info for printing, prefixifying, dumping, and
evaluating expressions.
(exp_descriptor_standard): Declare new variable.
(print_subexp): Make global and declare here (from expprint.c).
(dump_subexp): Ditto.
(dump_subexp_body_standard): Declare.
(operator_length): Declare.
(operator_length_standard): Declare.
(op_name_standard): Declare.
(print_subexp): Declare.
(print_subexp_standard): Declare.
* language.h (struct language_defn): Add la_exp_desc field to hold
pointer to table for language-specific operators.
Remove evaluate_exp field, which is now in struct exp_descriptor.
* parse.c (length_of_subexp): Use operator_length to get
operator lengths and arities for operators.
Move most code to new operator_length_standard function.
(operator_length_standard): New function taking most code from
length_of_subexp.
(prefixify_subexp): Remove large case and use operator_length instead.
(operator_length): New function. Uses language-specific information.
(exp_descriptor_standard): New constant.
(parse_exp_1): Use renamings:
dump_prefix_expression => dump_raw_expression and
dump_postfix_expression => dump_prefix_expression.
* expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0
and OP_EXTENDED_LAST.
(dump_prefix_expression): Rename to ...
(dump_raw_expression): New name.
(dump_postfix_expression): Rename to ...
(dump_prefix_expression): New name.
* expprint.c (print_subexp): Make global, remove static declaration.
Use language-specific print_subexp.
Move most existing code to print_subexp_standard.
(print_subexp_standard): New function, containing code formerly in
print_subexp.
(op_name): Add expression to argument signature.
Use langauge-specific op_name.
Move most code to op_name_standard.
(op_name_standard): New function, containing code formerly in op_name.
(dump_subexp): Make global. Add comment.
Use new version of op_name function.
Use language-specific dump_subexp_body, and move most existing code to
dump_subexp_body_standard.
(dump_subexp_body): New function.
(dump_subexp_body_standard): New function, containing code formerly
in dump_subexp.
(dump_prefix_expression): Rename to dump_raw_expression.
Remove attempt to print the expression via print_expression: it can't
work before the expression is prefixified!
Use new version of op_name.
(dump_raw_expression): Renamed from dump_prefix_expression.
(dump_postfix_expression): Rename to dump_prefix_expression, since
that's what it does!
Remove 'note' parameter, since this routine must be used on
prefixified expression.
(dump_prefix_expression): Renamed from dump_postfix_expression.
* language.c (unknown_language): Add default la_exp_desc field and
remove evaluate_exp field.
(auto_language): Ditto.
(local_language): Ditto.
* f-lang.c (f_language_defn): Ditto.
* c-lang.c (c_language_defn): Ditto.
(cplus_language_defn): Ditto.
(asm_language_defn): Ditto.
(minimal_language_defn): Ditto.
* p-lang.c (pascal_language_defn): Ditto.
* m2-lang.c (m2_language_defn): Ditto.
* objc-lang.c (objc_language_defn): Ditto.
* jv-lang.c (exp_descriptor_java): New variable, containing
Java-specific expression evaluator.
(java_language_defn): Add la_exp_desc field.
* scm-lang.c (exp_descriptor_scm): New variable, containing
Scheme-specific expression evaluator.
(scm_language_defn): Add la_exp_desc field.
* objc-lang.c (print_object_command): Take evaluate_exp from the
la_exp_desc field.
* Makefile.in (eval.o): Add dependency on parser-defs.h.
* eval.c: Include parser-defs.h for the full declaration of
la_exp_desc's type.
(evaluate_subexp): Get evaluate_exp out of la_exp_desc field.
Index: current-public.25/gdb/p-lang.c
--- current-public.25/gdb/p-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.2.2.1 644)
+++ submit.16(w)/gdb/p-lang.c Tue, 16 Sep 2003 01:31:55 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.2.2.3 644)
@@ -451,9 +451,9 @@ const struct language_defn pascal_langua
range_check_on,
type_check_on,
case_sensitive_on,
+ &exp_descriptor_standard,
pascal_parse,
pascal_error,
- evaluate_subexp_standard,
pascal_printchar, /* Print a character constant */
pascal_printstr, /* Function to print string constant */
pascal_emit_char, /* Print a single char */
Index: current-public.25/gdb/Makefile.in
--- current-public.25/gdb/Makefile.in Wed, 17 Sep 2003 23:22:28 -0700 hilfingr (GdbPub/g/6_Makefile.i 1.1.1.8.1.1.1.1.1.1.1.1.1.3.2.1 644)
+++ submit.16(w)/gdb/Makefile.in Wed, 17 Sep 2003 23:35:15 -0700 hilfingr (GdbPub/g/6_Makefile.i 1.1.1.8.1.1.1.1.1.1.1.1.1.3.2.2 644)
@@ -1735,7 +1735,8 @@ elfread.o: elfread.c $(defs_h) $(bfd_h)
environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
- $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h)
+ $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h) \
+ $(parser_defs_h)
event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \
$(gdb_string_h)
event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
Index: current-public.25/gdb/c-lang.c
--- current-public.25/gdb/c-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.3.2.1 644)
+++ submit.16(w)/gdb/c-lang.c Tue, 16 Sep 2003 21:35:59 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.3.2.3 644)
@@ -543,9 +543,9 @@ const struct language_defn c_language_de
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
- evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_emit_char, /* Print a single char */
@@ -599,9 +599,9 @@ const struct language_defn cplus_languag
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
- evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_emit_char, /* Print a single char */
@@ -632,9 +632,9 @@ const struct language_defn asm_language_
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
- evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_emit_char, /* Print a single char */
@@ -670,9 +670,9 @@ const struct language_defn minimal_langu
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
- evaluate_subexp_standard,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_emit_char, /* Print a single char */
Index: current-public.25/gdb/eval.c
--- current-public.25/gdb/eval.c Wed, 17 Sep 2003 23:22:28 -0700 hilfingr (GdbPub/h/26_eval.c 1.1.1.3.1.1.3.1 644)
+++ submit.16(w)/gdb/eval.c Wed, 17 Sep 2003 23:37:29 -0700 hilfingr (GdbPub/h/26_eval.c 1.1.1.3.1.1.3.2 644)
@@ -35,6 +35,7 @@
#include "infcall.h"
#include "objc-lang.h"
#include "block.h"
+#include "parser-defs.h"
/* Defined in symtab.c */
extern int hp_som_som_object_present;
@@ -70,7 +71,8 @@ static struct value *
evaluate_subexp (struct type *expect_type, struct expression *exp,
int *pos, enum noside noside)
{
- return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
+ return (*exp->language_defn->la_exp_desc->evaluate_exp)
+ (expect_type, exp, pos, noside);
}
\f
/* Parse the string EXP as a C expression, evaluate it,
Index: current-public.25/gdb/expprint.c
--- current-public.25/gdb/expprint.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3.3.1 644)
+++ submit.16(w)/gdb/expprint.c Thu, 18 Sep 2003 02:08:41 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3.3.3 644)
@@ -36,11 +36,6 @@
#include <ctype.h>
#endif
-/* Prototypes for local functions */
-
-static void print_subexp (struct expression *, int *, struct ui_file *,
- enum precedence);
-
void
print_expression (struct expression *exp, struct ui_file *stream)
{
@@ -53,10 +48,19 @@ print_expression (struct expression *exp
if the precedence of the main operator of this subexpression is less,
parentheses are needed here. */
-static void
+void
print_subexp (struct expression *exp, int *pos,
struct ui_file *stream, enum precedence prec)
{
+ exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
+}
+
+/* Standard implementation of print_subexp for use in language_defn
+ vectors. */
+void
+print_subexp_standard (struct expression *exp, int *pos,
+ struct ui_file *stream, enum precedence prec)
+{
unsigned tem;
const struct op_print *op_print_tab;
int pc;
@@ -547,10 +551,22 @@ op_string (enum exp_opcode op)
/* Support for dumping the raw data from expressions in a human readable
form. */
-static char *op_name (int opcode);
+static char *op_name (struct expression *, enum exp_opcode);
+static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
+
+/* Name for OPCODE, when it appears in expression EXP. */
static char *
-op_name (int opcode)
+op_name (struct expression *exp, enum exp_opcode opcode)
+{
+ return exp->language_defn->la_exp_desc->op_name (opcode);
+}
+
+/* Default name for the standard operator OPCODE (i.e., one defined in
+ the definition of enum exp_opcode). */
+
+char *
+op_name_standard (enum exp_opcode opcode)
{
switch (opcode)
{
@@ -737,8 +753,8 @@ op_name (int opcode)
}
void
-dump_prefix_expression (struct expression *exp, struct ui_file *stream,
- char *note)
+dump_raw_expression (struct expression *exp, struct ui_file *stream,
+ char *note)
{
int elt;
char *opcode_name;
@@ -747,11 +763,6 @@ dump_prefix_expression (struct expressio
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_host_address (exp, stream);
- fprintf_filtered (stream, ", %s:\nExpression: `", note);
- if (exp->elts[0].opcode != OP_TYPE)
- print_expression (exp, stream);
- else
- fprintf_filtered (stream, "Type printing not yet supported....");
fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
exp->language_defn->la_name, exp->nelts,
(long) sizeof (union exp_element));
@@ -760,7 +771,7 @@ dump_prefix_expression (struct expressio
for (elt = 0; elt < exp->nelts; elt++)
{
fprintf_filtered (stream, "\t%5d ", elt);
- opcode_name = op_name (exp->elts[elt].opcode);
+ opcode_name = op_name (exp, exp->elts[elt].opcode);
fprintf_filtered (stream, "%20s ", opcode_name);
print_longest (stream, 'd', 0, exp->elts[elt].longconst);
@@ -778,10 +789,11 @@ dump_prefix_expression (struct expressio
}
}
-static int dump_subexp (struct expression *exp, struct ui_file *stream,
- int elt);
+/* Dump the subexpression of prefix expression EXP whose operator is at
+ position ELT onto STREAM. Returns the position of the next
+ subexpression in EXP. */
-static int
+int
dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
{
static int indent = 0;
@@ -794,9 +806,34 @@ dump_subexp (struct expression *exp, str
fprintf_filtered (stream, " ");
indent += 2;
- fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
+ fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode));
+
+ elt = dump_subexp_body (exp, stream, elt);
- switch (exp->elts[elt++].opcode)
+ indent -= 2;
+
+ return elt;
+}
+
+/* Dump the operands of prefix expression EXP whose opcode is at
+ position ELT onto STREAM. Returns the position of the next
+ subexpression in EXP. */
+
+static int
+dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
+{
+ return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
+}
+
+/* Default value for subexp_body in exp_descriptor vector. */
+
+int
+dump_subexp_body_standard (struct expression *exp,
+ struct ui_file *stream, int elt)
+{
+ int opcode = exp->elts[elt++].opcode;
+
+ switch (opcode)
{
case TERNOP_COND:
case TERNOP_SLICE:
@@ -914,7 +951,7 @@ dump_subexp (struct expression *exp, str
break;
case OP_FUNCALL:
{
- int nargs;
+ int i, nargs;
nargs = longest_to_int (exp->elts[elt].longconst);
@@ -1006,20 +1043,17 @@ dump_subexp (struct expression *exp, str
fprintf_filtered (stream, "Unknown format");
}
- indent -= 2;
-
return elt;
}
void
-dump_postfix_expression (struct expression *exp, struct ui_file *stream,
- char *note)
+dump_prefix_expression (struct expression *exp, struct ui_file *stream)
{
int elt;
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_host_address (exp, stream);
- fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
if (exp->elts[0].opcode != OP_TYPE)
print_expression (exp, stream);
else
Index: current-public.25/gdb/expression.h
--- current-public.25/gdb/expression.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.2 644)
+++ submit.16(w)/gdb/expression.h Thu, 18 Sep 2003 01:44:54 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.6 644)
@@ -322,7 +322,27 @@ enum exp_opcode
OP_EXPRSTRING,
/* An Objective C Foundation Class NSString constant */
- OP_OBJC_NSSTRING
+ OP_OBJC_NSSTRING,
+
+ /* First extension operator. Individual language modules define
+ extra operators they need as constants with values
+ OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
+ enumerated type definition:
+ enum foo_extension_operator {
+ BINOP_MOGRIFY = OP_EXTENDED0,
+ BINOP_FROB,
+ ...
+ }; */
+ OP_EXTENDED0,
+
+ /* Last possible extension operator. Defined to provide an
+ explicit and finite number of extended operators. */
+ OP_EXTENDED_LAST = 0xff
+ /* NOTE: Eventually, we expect to convert to an object-oriented
+ formulation for expression operators that does away with the
+ need for these extension operators, and indeed for this
+ entire enumeration type. Therefore, consider the OP_EXTENDED
+ definitions to be a temporary measure. */
};
union exp_element
@@ -393,11 +413,7 @@ extern void print_expression (struct exp
extern char *op_string (enum exp_opcode);
-extern void dump_prefix_expression (struct expression *,
- struct ui_file *,
- char *);
-extern void dump_postfix_expression (struct expression *,
- struct ui_file *,
- char *);
+extern void dump_raw_expression (struct expression *, struct ui_file *, char *);
+extern void dump_prefix_expression (struct expression *, struct ui_file *);
#endif /* !defined (EXPRESSION_H) */
Index: current-public.25/gdb/f-lang.c
--- current-public.25/gdb/f-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.2.2.1 644)
+++ submit.16(w)/gdb/f-lang.c Tue, 16 Sep 2003 01:31:54 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.2.2.3 644)
@@ -462,9 +462,9 @@ const struct language_defn f_language_de
range_check_on,
type_check_on,
case_sensitive_off,
+ &exp_descriptor_standard,
f_parse, /* parser */
f_error, /* parser error function */
- evaluate_subexp_standard,
f_printchar, /* Print character constant */
f_printstr, /* function to print string constant */
f_emit_char, /* Function to print a single character */
Index: current-public.25/gdb/jv-lang.c
--- current-public.25/gdb/jv-lang.c Sat, 13 Sep 2003 23:40:42 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3.3.1.1.1 644)
+++ submit.16(w)/gdb/jv-lang.c Tue, 16 Sep 2003 01:31:54 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3.3.1.1.1.1.1 644)
@@ -1030,6 +1030,15 @@ const struct op_print java_op_print_tab[
{NULL, 0, 0, 0}
};
+const struct exp_descriptor exp_descriptor_java =
+{
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_java
+};
+
const struct language_defn java_language_defn =
{
"java", /* Language name */
@@ -1038,9 +1047,9 @@ const struct language_defn java_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_java,
java_parse,
java_error,
- evaluate_subexp_java,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
java_emit_char, /* Function to print a single character */
Index: current-public.25/gdb/language.c
--- current-public.25/gdb/language.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1.3.1 644)
+++ submit.16(w)/gdb/language.c Tue, 16 Sep 2003 01:31:53 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1.3.3 644)
@@ -1267,9 +1267,9 @@ const struct language_defn unknown_langu
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
- evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
unk_lang_emit_char,
@@ -1301,9 +1301,9 @@ const struct language_defn auto_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
- evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
unk_lang_emit_char,
@@ -1334,9 +1334,9 @@ const struct language_defn local_languag
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
- evaluate_subexp_standard,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
unk_lang_emit_char,
Index: current-public.25/gdb/language.h
--- current-public.25/gdb/language.h Fri, 22 Aug 2003 00:46:52 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1 644)
+++ submit.16(w)/gdb/language.h Tue, 16 Sep 2003 01:22:12 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1.1.2 644)
@@ -167,6 +167,11 @@ struct language_defn
/* Default case sensitivity */
enum case_sensitivity la_case_sensitivity;
+ /* Definitions related to expression printing, prefixifying, and
+ dumping */
+
+ const struct exp_descriptor *la_exp_desc;
+
/* Parser function. */
int (*la_parser) (void);
@@ -174,10 +179,6 @@ struct language_defn
/* Parser error function */
void (*la_error) (char *);
-
- /* Evaluate an expression. */
- struct value *(*evaluate_exp) (struct type *, struct expression *,
- int *, enum noside);
void (*la_printchar) (int ch, struct ui_file * stream);
Index: current-public.25/gdb/m2-lang.c
--- current-public.25/gdb/m2-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.2.2.1 644)
+++ submit.16(w)/gdb/m2-lang.c Tue, 16 Sep 2003 01:31:53 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.2.2.3 644)
@@ -415,9 +415,9 @@ const struct language_defn m2_language_d
range_check_on,
type_check_on,
case_sensitive_on,
+ &exp_descriptor_standard,
m2_parse, /* parser */
m2_error, /* parser error function */
- evaluate_subexp_standard,
m2_printchar, /* Print character constant */
m2_printstr, /* function to print string constant */
m2_emit_char, /* Function to print a single character */
Index: current-public.25/gdb/parse.c
--- current-public.25/gdb/parse.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4.3.1 644)
+++ submit.16(w)/gdb/parse.c Thu, 18 Sep 2003 02:08:40 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4.3.4 644)
@@ -50,6 +50,17 @@
#include "gdb_assert.h"
#include "block.h"
+/* Standard set of definitions for printing, dumping, prefixifying,
+ * and evaluating expressions. */
+
+const struct exp_descriptor exp_descriptor_standard =
+ {
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_standard
+ };
\f
/* Symbols which architectures can redefine. */
@@ -771,8 +782,7 @@ copy_name (struct stoken token)
static void
prefixify_expression (struct expression *expr)
{
- int len =
- sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
+ int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
struct expression *temp;
int inpos = expr->nelts, outpos = 0;
@@ -784,18 +794,48 @@ prefixify_expression (struct expression
prefixify_subexp (temp, expr, inpos, outpos);
}
-/* Return the number of exp_elements in the subexpression of EXPR
- whose last exp_element is at index ENDPOS - 1 in EXPR. */
+/* Return the number of exp_elements in the postfix subexpression
+ of EXPR whose operator is at index ENDPOS - 1 in EXPR. */
int
length_of_subexp (struct expression *expr, int endpos)
{
+ int oplen, args, i;
+
+ operator_length (expr, endpos, &oplen, &args);
+
+ while (args > 0)
+ {
+ oplen += length_of_subexp (expr, endpos - oplen);
+ args--;
+ }
+
+ return oplen;
+}
+
+/* Sets *OPLENP to the length of the operator whose (last) index is
+ ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that
+ operator takes. */
+
+void
+operator_length (struct expression *expr, int endpos, int *oplenp, int *argsp)
+{
+ expr->language_defn->la_exp_desc->operator_length (expr, endpos,
+ oplenp, argsp);
+}
+
+/* Default value for operator_length in exp_descriptor vectors. */
+
+void
+operator_length_standard (struct expression *expr, int endpos,
+ int *oplenp, int *argsp)
+{
int oplen = 1;
int args = 0;
int i;
if (endpos < 1)
- error ("?error in length_of_subexp");
+ error ("?error in operator_length_standard");
i = (int) expr->elts[endpos - 1].opcode;
@@ -916,13 +956,8 @@ length_of_subexp (struct expression *exp
args = 1 + (i < (int) BINOP_END);
}
- while (args > 0)
- {
- oplen += length_of_subexp (expr, endpos - oplen);
- args--;
- }
-
- return oplen;
+ *oplenp = oplen;
+ *argsp = args;
}
/* Copy the subexpression ending just before index INEND in INEXPR
@@ -933,132 +968,13 @@ static void
prefixify_subexp (struct expression *inexpr,
struct expression *outexpr, int inend, int outbeg)
{
- int oplen = 1;
- int args = 0;
+ int oplen;
+ int args;
int i;
int *arglens;
enum exp_opcode opcode;
- /* Compute how long the last operation is (in OPLEN),
- and also how many preceding subexpressions serve as
- arguments for it (in ARGS). */
-
- opcode = inexpr->elts[inend - 1].opcode;
- switch (opcode)
- {
- /* C++ */
- case OP_SCOPE:
- oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
- oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
-
- case OP_LONG:
- case OP_DOUBLE:
- case OP_VAR_VALUE:
- oplen = 4;
- break;
-
- case OP_TYPE:
- case OP_BOOL:
- case OP_LAST:
- case OP_REGISTER:
- case OP_INTERNALVAR:
- oplen = 3;
- break;
-
- case OP_COMPLEX:
- oplen = 1;
- args = 2;
- break;
-
- case OP_FUNCALL:
- case OP_F77_UNDETERMINED_ARGLIST:
- oplen = 3;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- case OP_OBJC_MSGCALL: /* Objective C message (method) call */
- oplen = 4;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- case UNOP_MIN:
- case UNOP_MAX:
- oplen = 3;
- break;
-
- case UNOP_CAST:
- case UNOP_MEMVAL:
- oplen = 3;
- args = 1;
- break;
-
- case UNOP_ABS:
- case UNOP_CAP:
- case UNOP_CHR:
- case UNOP_FLOAT:
- case UNOP_HIGH:
- case UNOP_ODD:
- case UNOP_ORD:
- case UNOP_TRUNC:
- oplen = 1;
- args = 1;
- break;
-
- case STRUCTOP_STRUCT:
- case STRUCTOP_PTR:
- case OP_LABELED:
- args = 1;
- /* fall through */
- case OP_M2_STRING:
- case OP_STRING:
- case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant */
- case OP_OBJC_SELECTOR: /* Objective C "@selector" pseudo-op */
- case OP_NAME:
- case OP_EXPRSTRING:
- oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
- oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
- break;
-
- case OP_BITSTRING:
- oplen = longest_to_int (inexpr->elts[inend - 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 (inexpr->elts[inend - 2].longconst);
- args -= longest_to_int (inexpr->elts[inend - 3].longconst);
- args += 1;
- break;
-
- case TERNOP_COND:
- case TERNOP_SLICE:
- case TERNOP_SLICE_COUNT:
- args = 3;
- break;
-
- case BINOP_ASSIGN_MODIFY:
- oplen = 3;
- args = 2;
- break;
-
- /* Modula-2 */
- case MULTI_SUBSCRIPT:
- oplen = 3;
- args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
- break;
-
- /* C++ */
- case OP_THIS:
- case OP_OBJC_SELF:
- oplen = 2;
- break;
-
- default:
- args = 1 + ((int) opcode < (int) BINOP_END);
- }
+ operator_length (inexpr, inend, &oplen, &args);
/* Copy the final operator itself, from the end of the input
to the beginning of the output. */
@@ -1156,14 +1072,13 @@ parse_exp_1 (char **stringptr, struct bl
parser, to a prefix form. */
if (expressiondebug)
- dump_prefix_expression (expout, gdb_stdlog,
- "before conversion to prefix form");
+ dump_raw_expression (expout, gdb_stdlog,
+ "before conversion to prefix form");
prefixify_expression (expout);
if (expressiondebug)
- dump_postfix_expression (expout, gdb_stdlog,
- "after conversion to prefix form");
+ dump_prefix_expression (expout, gdb_stdlog);
*stringptr = lexptr;
return expout;
Index: current-public.25/gdb/parser-defs.h
--- current-public.25/gdb/parser-defs.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2 644)
+++ submit.16(w)/gdb/parser-defs.h Thu, 18 Sep 2003 01:58:16 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2.1.5 644)
@@ -159,6 +159,17 @@ extern int pop_type_int (void);
extern int length_of_subexp (struct expression *, int);
+extern int dump_subexp (struct expression *, struct ui_file *, int);
+
+extern int dump_subexp_body_standard (struct expression *,
+ struct ui_file *, int);
+
+extern void operator_length (struct expression *, int, int *, int *);
+
+extern void operator_length_standard (struct expression *, int, int *, int *);
+
+extern char *op_name_standard (enum exp_opcode);
+
extern struct type *follow_types (struct type *);
/* During parsing of a C expression, the pointer to the next character
@@ -219,6 +230,46 @@ struct op_print
For a unary operator: 1 iff postfix. */
int right_assoc;
};
+
+/* Information needed to print, prefixify, and evaluate expressions for
+ a given language. */
+
+struct exp_descriptor
+ {
+ /* Print subexpression. */
+ void (*print_subexp) (struct expression *, int *, struct ui_file *,
+ enum precedence);
+
+ /* Returns number of exp_elements needed to represent an operator and
+ the number of subexpressions it takes. */
+ void (*operator_length) (struct expression*, int, int*, int *);
+
+ /* Name of this operator for dumping purposes. */
+ char *(*op_name) (enum exp_opcode);
+
+ /* Dump the rest of this (prefix) expression after the operator
+ itself has been printed. See dump_subexp_body_standard in
+ (expprint.c). */
+ int (*dump_subexp_body) (struct expression *, struct ui_file *, int);
+
+ /* Evaluate an expression. */
+ struct value *(*evaluate_exp) (struct type *, struct expression *,
+ int *, enum noside);
+ };
+
+
+/* Default descriptor containing standard definitions of all
+ elements. */
+extern const struct exp_descriptor exp_descriptor_standard;
+
+/* Functions used by language-specific extended operators to (recursively)
+ print/dump subexpressions. */
+
+extern void print_subexp (struct expression *, int *, struct ui_file *,
+ enum precedence);
+
+extern void print_subexp_standard (struct expression *, int *,
+ struct ui_file *, enum precedence);
/* Function used to avoid direct calls to fprintf
in the code generated by the bison parser. */
Index: current-public.25/gdb/scm-lang.c
--- current-public.25/gdb/scm-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.3.2.1 644)
+++ submit.16(w)/gdb/scm-lang.c Tue, 16 Sep 2003 01:31:52 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.3.2.3 644)
@@ -233,6 +233,15 @@ nosideret:
return value_from_longest (builtin_type_long, (LONGEST) 1);
}
+const struct exp_descriptor exp_descriptor_scm =
+{
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_scm
+};
+
const struct language_defn scm_language_defn =
{
"scheme", /* Language name */
@@ -241,9 +250,9 @@ const struct language_defn scm_language_
range_check_off,
type_check_off,
case_sensitive_off,
+ &exp_descriptor_scm,
scm_parse,
c_error,
- evaluate_subexp_scm,
scm_printchar, /* Print a character constant */
scm_printstr, /* Function to print string constant */
NULL, /* Function to print a single character */
Index: current-public.25/gdb/objc-lang.c
--- current-public.25/gdb/objc-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4.3.1 644)
+++ submit.16(w)/gdb/objc-lang.c Tue, 16 Sep 2003 01:48:04 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4.3.3 644)
@@ -659,9 +659,9 @@ const struct language_defn objc_language
range_check_off,
type_check_off,
case_sensitive_on,
+ &exp_descriptor_standard,
objc_parse,
objc_error,
- evaluate_subexp_standard,
objc_printchar, /* Print a character constant */
objc_printstr, /* Function to print string constant */
objc_emit_char,
@@ -1537,8 +1537,8 @@ print_object_command (char *args, int fr
make_cleanup (free_current_contents, &expr);
int pc = 0;
- object = expr->language_defn->evaluate_exp (builtin_type_void_data_ptr,
- expr, &pc, EVAL_NORMAL);
+ object = expr->language_defn->la_exp_desc->evaluate_exp
+ (builtin_type_void_data_ptr, expr, &pc, EVAL_NORMAL);
do_cleanups (old_chain);
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFA: Changes to allow extensions to operator set
2003-09-18 9:20 ` Paul Hilfinger
@ 2003-09-22 17:04 ` Andrew Cagney
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Cagney @ 2003-09-22 17:04 UTC (permalink / raw)
To: Paul Hilfinger; +Cc: gdb-patches
> Andrew,
>
> Here is a version of the patch I submitted earlier that I believe addresses
> your comments from last time. The specific changes from last time that you
> wanted were
>
> 1. Putting evaluate_exp into the exp_descriptor structure.
>
> 2. Modifying the description of the OP_EXTENDED_LAST operator slightly
> and including a note indicating the temporary nature of the extension
> mechanism and our intention to OOize expression handling in general.
Yes.
> Other parts you previously approved.
Are they in yet?
> If these changes were what you
> were after, I will commit.
Ok, once the others have been committed. Ada is now a little bit less
scary, Thanks!
Andrew
> ChangeLog:
>
> 2003-09-18 Paul N. Hilfinger <hilfingr@nile.gnat.com>
>
> * parser-defs.h (struct exp_descriptor): New definition, containing
> language-specific info for printing, prefixifying, dumping, and
> evaluating expressions.
> (exp_descriptor_standard): Declare new variable.
> (print_subexp): Make global and declare here (from expprint.c).
> (dump_subexp): Ditto.
> (dump_subexp_body_standard): Declare.
> (operator_length): Declare.
> (operator_length_standard): Declare.
> (op_name_standard): Declare.
> (print_subexp): Declare.
> (print_subexp_standard): Declare.
>
> * language.h (struct language_defn): Add la_exp_desc field to hold
> pointer to table for language-specific operators.
> Remove evaluate_exp field, which is now in struct exp_descriptor.
>
> * parse.c (length_of_subexp): Use operator_length to get
> operator lengths and arities for operators.
> Move most code to new operator_length_standard function.
> (operator_length_standard): New function taking most code from
> length_of_subexp.
> (prefixify_subexp): Remove large case and use operator_length instead.
> (operator_length): New function. Uses language-specific information.
> (exp_descriptor_standard): New constant.
> (parse_exp_1): Use renamings:
> dump_prefix_expression => dump_raw_expression and
> dump_postfix_expression => dump_prefix_expression.
>
> * expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0
> and OP_EXTENDED_LAST.
> (dump_prefix_expression): Rename to ...
> (dump_raw_expression): New name.
> (dump_postfix_expression): Rename to ...
> (dump_prefix_expression): New name.
>
> * expprint.c (print_subexp): Make global, remove static declaration.
> Use language-specific print_subexp.
> Move most existing code to print_subexp_standard.
> (print_subexp_standard): New function, containing code formerly in
> print_subexp.
> (op_name): Add expression to argument signature.
> Use langauge-specific op_name.
> Move most code to op_name_standard.
> (op_name_standard): New function, containing code formerly in op_name.
> (dump_subexp): Make global. Add comment.
> Use new version of op_name function.
> Use language-specific dump_subexp_body, and move most existing code to
> dump_subexp_body_standard.
> (dump_subexp_body): New function.
> (dump_subexp_body_standard): New function, containing code formerly
> in dump_subexp.
> (dump_prefix_expression): Rename to dump_raw_expression.
> Remove attempt to print the expression via print_expression: it can't
> work before the expression is prefixified!
> Use new version of op_name.
> (dump_raw_expression): Renamed from dump_prefix_expression.
> (dump_postfix_expression): Rename to dump_prefix_expression, since
> that's what it does!
> Remove 'note' parameter, since this routine must be used on
> prefixified expression.
> (dump_prefix_expression): Renamed from dump_postfix_expression.
>
> * language.c (unknown_language): Add default la_exp_desc field and
> remove evaluate_exp field.
> (auto_language): Ditto.
> (local_language): Ditto.
> * f-lang.c (f_language_defn): Ditto.
> * c-lang.c (c_language_defn): Ditto.
> (cplus_language_defn): Ditto.
> (asm_language_defn): Ditto.
> (minimal_language_defn): Ditto.
> * p-lang.c (pascal_language_defn): Ditto.
> * m2-lang.c (m2_language_defn): Ditto.
> * objc-lang.c (objc_language_defn): Ditto.
>
> * jv-lang.c (exp_descriptor_java): New variable, containing
> Java-specific expression evaluator.
> (java_language_defn): Add la_exp_desc field.
> * scm-lang.c (exp_descriptor_scm): New variable, containing
> Scheme-specific expression evaluator.
> (scm_language_defn): Add la_exp_desc field.
> * objc-lang.c (print_object_command): Take evaluate_exp from the
> la_exp_desc field.
>
> * Makefile.in (eval.o): Add dependency on parser-defs.h.
>
> * eval.c: Include parser-defs.h for the full declaration of
> la_exp_desc's type.
> (evaluate_subexp): Get evaluate_exp out of la_exp_desc field.
>
>
>
> Index: current-public.25/gdb/p-lang.c
> --- current-public.25/gdb/p-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.2.2.1 644)
> +++ submit.16(w)/gdb/p-lang.c Tue, 16 Sep 2003 01:31:55 -0700 hilfingr (GdbPub/e/26_p-lang.c 1.1.1.2.2.3 644)
> @@ -451,9 +451,9 @@ const struct language_defn pascal_langua
> range_check_on,
> type_check_on,
> case_sensitive_on,
> + &exp_descriptor_standard,
> pascal_parse,
> pascal_error,
> - evaluate_subexp_standard,
> pascal_printchar, /* Print a character constant */
> pascal_printstr, /* Function to print string constant */
> pascal_emit_char, /* Print a single char */
> Index: current-public.25/gdb/Makefile.in
> --- current-public.25/gdb/Makefile.in Wed, 17 Sep 2003 23:22:28 -0700 hilfingr (GdbPub/g/6_Makefile.i 1.1.1.8.1.1.1.1.1.1.1.1.1.3.2.1 644)
> +++ submit.16(w)/gdb/Makefile.in Wed, 17 Sep 2003 23:35:15 -0700 hilfingr (GdbPub/g/6_Makefile.i 1.1.1.8.1.1.1.1.1.1.1.1.1.3.2.2 644)
> @@ -1735,7 +1735,8 @@ elfread.o: elfread.c $(defs_h) $(bfd_h)
> environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
> eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
> $(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
> - $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h)
> + $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h) \
> + $(parser_defs_h)
> event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \
> $(gdb_string_h)
> event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
> Index: current-public.25/gdb/c-lang.c
> --- current-public.25/gdb/c-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.3.2.1 644)
> +++ submit.16(w)/gdb/c-lang.c Tue, 16 Sep 2003 21:35:59 -0700 hilfingr (GdbPub/g/28_c-lang.c 1.1.1.3.2.3 644)
> @@ -543,9 +543,9 @@ const struct language_defn c_language_de
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> c_preprocess_and_parse,
> c_error,
> - evaluate_subexp_standard,
> c_printchar, /* Print a character constant */
> c_printstr, /* Function to print string constant */
> c_emit_char, /* Print a single char */
> @@ -599,9 +599,9 @@ const struct language_defn cplus_languag
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> c_preprocess_and_parse,
> c_error,
> - evaluate_subexp_standard,
> c_printchar, /* Print a character constant */
> c_printstr, /* Function to print string constant */
> c_emit_char, /* Print a single char */
> @@ -632,9 +632,9 @@ const struct language_defn asm_language_
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> c_preprocess_and_parse,
> c_error,
> - evaluate_subexp_standard,
> c_printchar, /* Print a character constant */
> c_printstr, /* Function to print string constant */
> c_emit_char, /* Print a single char */
> @@ -670,9 +670,9 @@ const struct language_defn minimal_langu
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> c_preprocess_and_parse,
> c_error,
> - evaluate_subexp_standard,
> c_printchar, /* Print a character constant */
> c_printstr, /* Function to print string constant */
> c_emit_char, /* Print a single char */
> Index: current-public.25/gdb/eval.c
> --- current-public.25/gdb/eval.c Wed, 17 Sep 2003 23:22:28 -0700 hilfingr (GdbPub/h/26_eval.c 1.1.1.3.1.1.3.1 644)
> +++ submit.16(w)/gdb/eval.c Wed, 17 Sep 2003 23:37:29 -0700 hilfingr (GdbPub/h/26_eval.c 1.1.1.3.1.1.3.2 644)
> @@ -35,6 +35,7 @@
> #include "infcall.h"
> #include "objc-lang.h"
> #include "block.h"
> +#include "parser-defs.h"
>
> /* Defined in symtab.c */
> extern int hp_som_som_object_present;
> @@ -70,7 +71,8 @@ static struct value *
> evaluate_subexp (struct type *expect_type, struct expression *exp,
> int *pos, enum noside noside)
> {
> - return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
> + return (*exp->language_defn->la_exp_desc->evaluate_exp)
> + (expect_type, exp, pos, noside);
> }
> \f
> /* Parse the string EXP as a C expression, evaluate it,
> Index: current-public.25/gdb/expprint.c
> --- current-public.25/gdb/expprint.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3.3.1 644)
> +++ submit.16(w)/gdb/expprint.c Thu, 18 Sep 2003 02:08:41 -0700 hilfingr (GdbPub/h/29_expprint.c 1.1.1.3.3.3 644)
> @@ -36,11 +36,6 @@
> #include <ctype.h>
> #endif
>
> -/* Prototypes for local functions */
> -
> -static void print_subexp (struct expression *, int *, struct ui_file *,
> - enum precedence);
> -
> void
> print_expression (struct expression *exp, struct ui_file *stream)
> {
> @@ -53,10 +48,19 @@ print_expression (struct expression *exp
> if the precedence of the main operator of this subexpression is less,
> parentheses are needed here. */
>
> -static void
> +void
> print_subexp (struct expression *exp, int *pos,
> struct ui_file *stream, enum precedence prec)
> {
> + exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
> +}
> +
> +/* Standard implementation of print_subexp for use in language_defn
> + vectors. */
> +void
> +print_subexp_standard (struct expression *exp, int *pos,
> + struct ui_file *stream, enum precedence prec)
> +{
> unsigned tem;
> const struct op_print *op_print_tab;
> int pc;
> @@ -547,10 +551,22 @@ op_string (enum exp_opcode op)
> /* Support for dumping the raw data from expressions in a human readable
> form. */
>
> -static char *op_name (int opcode);
> +static char *op_name (struct expression *, enum exp_opcode);
> +static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
> +
> +/* Name for OPCODE, when it appears in expression EXP. */
>
> static char *
> -op_name (int opcode)
> +op_name (struct expression *exp, enum exp_opcode opcode)
> +{
> + return exp->language_defn->la_exp_desc->op_name (opcode);
> +}
> +
> +/* Default name for the standard operator OPCODE (i.e., one defined in
> + the definition of enum exp_opcode). */
> +
> +char *
> +op_name_standard (enum exp_opcode opcode)
> {
> switch (opcode)
> {
> @@ -737,8 +753,8 @@ op_name (int opcode)
> }
>
> void
> -dump_prefix_expression (struct expression *exp, struct ui_file *stream,
> - char *note)
> +dump_raw_expression (struct expression *exp, struct ui_file *stream,
> + char *note)
> {
> int elt;
> char *opcode_name;
> @@ -747,11 +763,6 @@ dump_prefix_expression (struct expressio
>
> fprintf_filtered (stream, "Dump of expression @ ");
> gdb_print_host_address (exp, stream);
> - fprintf_filtered (stream, ", %s:\nExpression: `", note);
> - if (exp->elts[0].opcode != OP_TYPE)
> - print_expression (exp, stream);
> - else
> - fprintf_filtered (stream, "Type printing not yet supported....");
> fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
> exp->language_defn->la_name, exp->nelts,
> (long) sizeof (union exp_element));
> @@ -760,7 +771,7 @@ dump_prefix_expression (struct expressio
> for (elt = 0; elt < exp->nelts; elt++)
> {
> fprintf_filtered (stream, "\t%5d ", elt);
> - opcode_name = op_name (exp->elts[elt].opcode);
> + opcode_name = op_name (exp, exp->elts[elt].opcode);
>
> fprintf_filtered (stream, "%20s ", opcode_name);
> print_longest (stream, 'd', 0, exp->elts[elt].longconst);
> @@ -778,10 +789,11 @@ dump_prefix_expression (struct expressio
> }
> }
>
> -static int dump_subexp (struct expression *exp, struct ui_file *stream,
> - int elt);
> +/* Dump the subexpression of prefix expression EXP whose operator is at
> + position ELT onto STREAM. Returns the position of the next
> + subexpression in EXP. */
>
> -static int
> +int
> dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
> {
> static int indent = 0;
> @@ -794,9 +806,34 @@ dump_subexp (struct expression *exp, str
> fprintf_filtered (stream, " ");
> indent += 2;
>
> - fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
> + fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode));
> +
> + elt = dump_subexp_body (exp, stream, elt);
>
> - switch (exp->elts[elt++].opcode)
> + indent -= 2;
> +
> + return elt;
> +}
> +
> +/* Dump the operands of prefix expression EXP whose opcode is at
> + position ELT onto STREAM. Returns the position of the next
> + subexpression in EXP. */
> +
> +static int
> +dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
> +{
> + return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
> +}
> +
> +/* Default value for subexp_body in exp_descriptor vector. */
> +
> +int
> +dump_subexp_body_standard (struct expression *exp,
> + struct ui_file *stream, int elt)
> +{
> + int opcode = exp->elts[elt++].opcode;
> +
> + switch (opcode)
> {
> case TERNOP_COND:
> case TERNOP_SLICE:
> @@ -914,7 +951,7 @@ dump_subexp (struct expression *exp, str
> break;
> case OP_FUNCALL:
> {
> - int nargs;
> + int i, nargs;
>
> nargs = longest_to_int (exp->elts[elt].longconst);
>
> @@ -1006,20 +1043,17 @@ dump_subexp (struct expression *exp, str
> fprintf_filtered (stream, "Unknown format");
> }
>
> - indent -= 2;
> -
> return elt;
> }
>
> void
> -dump_postfix_expression (struct expression *exp, struct ui_file *stream,
> - char *note)
> +dump_prefix_expression (struct expression *exp, struct ui_file *stream)
> {
> int elt;
>
> fprintf_filtered (stream, "Dump of expression @ ");
> gdb_print_host_address (exp, stream);
> - fprintf_filtered (stream, ", %s:\nExpression: `", note);
> + fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
> if (exp->elts[0].opcode != OP_TYPE)
> print_expression (exp, stream);
> else
> Index: current-public.25/gdb/expression.h
> --- current-public.25/gdb/expression.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.2 644)
> +++ submit.16(w)/gdb/expression.h Thu, 18 Sep 2003 01:44:54 -0700 hilfingr (GdbPub/h/30_expression 1.1.1.6 644)
> @@ -322,7 +322,27 @@ enum exp_opcode
> OP_EXPRSTRING,
>
> /* An Objective C Foundation Class NSString constant */
> - OP_OBJC_NSSTRING
> + OP_OBJC_NSSTRING,
> +
> + /* First extension operator. Individual language modules define
> + extra operators they need as constants with values
> + OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
> + enumerated type definition:
> + enum foo_extension_operator {
> + BINOP_MOGRIFY = OP_EXTENDED0,
> + BINOP_FROB,
> + ...
> + }; */
> + OP_EXTENDED0,
> +
> + /* Last possible extension operator. Defined to provide an
> + explicit and finite number of extended operators. */
> + OP_EXTENDED_LAST = 0xff
> + /* NOTE: Eventually, we expect to convert to an object-oriented
> + formulation for expression operators that does away with the
> + need for these extension operators, and indeed for this
> + entire enumeration type. Therefore, consider the OP_EXTENDED
> + definitions to be a temporary measure. */
> };
>
> union exp_element
> @@ -393,11 +413,7 @@ extern void print_expression (struct exp
>
> extern char *op_string (enum exp_opcode);
>
> -extern void dump_prefix_expression (struct expression *,
> - struct ui_file *,
> - char *);
> -extern void dump_postfix_expression (struct expression *,
> - struct ui_file *,
> - char *);
> +extern void dump_raw_expression (struct expression *, struct ui_file *, char *);
> +extern void dump_prefix_expression (struct expression *, struct ui_file *);
>
> #endif /* !defined (EXPRESSION_H) */
> Index: current-public.25/gdb/f-lang.c
> --- current-public.25/gdb/f-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.2.2.1 644)
> +++ submit.16(w)/gdb/f-lang.c Tue, 16 Sep 2003 01:31:54 -0700 hilfingr (GdbPub/h/32_f-lang.c 1.1.1.2.2.3 644)
> @@ -462,9 +462,9 @@ const struct language_defn f_language_de
> range_check_on,
> type_check_on,
> case_sensitive_off,
> + &exp_descriptor_standard,
> f_parse, /* parser */
> f_error, /* parser error function */
> - evaluate_subexp_standard,
> f_printchar, /* Print character constant */
> f_printstr, /* function to print string constant */
> f_emit_char, /* Function to print a single character */
> Index: current-public.25/gdb/jv-lang.c
> --- current-public.25/gdb/jv-lang.c Sat, 13 Sep 2003 23:40:42 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3.3.1.1.1 644)
> +++ submit.16(w)/gdb/jv-lang.c Tue, 16 Sep 2003 01:31:54 -0700 hilfingr (GdbPub/i/30_jv-lang.c 1.1.1.3.3.1.1.1.1.1 644)
> @@ -1030,6 +1030,15 @@ const struct op_print java_op_print_tab[
> {NULL, 0, 0, 0}
> };
>
> +const struct exp_descriptor exp_descriptor_java =
> +{
> + print_subexp_standard,
> + operator_length_standard,
> + op_name_standard,
> + dump_subexp_body_standard,
> + evaluate_subexp_java
> +};
> +
> const struct language_defn java_language_defn =
> {
> "java", /* Language name */
> @@ -1038,9 +1047,9 @@ const struct language_defn java_language
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_java,
> java_parse,
> java_error,
> - evaluate_subexp_java,
> c_printchar, /* Print a character constant */
> c_printstr, /* Function to print string constant */
> java_emit_char, /* Function to print a single character */
> Index: current-public.25/gdb/language.c
> --- current-public.25/gdb/language.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1.3.1 644)
> +++ submit.16(w)/gdb/language.c Tue, 16 Sep 2003 01:31:53 -0700 hilfingr (GdbPub/i/34_language.c 1.1.1.3.1.1.3.3 644)
> @@ -1267,9 +1267,9 @@ const struct language_defn unknown_langu
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> unk_lang_parser,
> unk_lang_error,
> - evaluate_subexp_standard,
> unk_lang_printchar, /* Print character constant */
> unk_lang_printstr,
> unk_lang_emit_char,
> @@ -1301,9 +1301,9 @@ const struct language_defn auto_language
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> unk_lang_parser,
> unk_lang_error,
> - evaluate_subexp_standard,
> unk_lang_printchar, /* Print character constant */
> unk_lang_printstr,
> unk_lang_emit_char,
> @@ -1334,9 +1334,9 @@ const struct language_defn local_languag
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> unk_lang_parser,
> unk_lang_error,
> - evaluate_subexp_standard,
> unk_lang_printchar, /* Print character constant */
> unk_lang_printstr,
> unk_lang_emit_char,
> Index: current-public.25/gdb/language.h
> --- current-public.25/gdb/language.h Fri, 22 Aug 2003 00:46:52 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1 644)
> +++ submit.16(w)/gdb/language.h Tue, 16 Sep 2003 01:22:12 -0700 hilfingr (GdbPub/i/35_language.h 1.1.1.3.1.1.1.2 644)
> @@ -167,6 +167,11 @@ struct language_defn
> /* Default case sensitivity */
> enum case_sensitivity la_case_sensitivity;
>
> + /* Definitions related to expression printing, prefixifying, and
> + dumping */
> +
> + const struct exp_descriptor *la_exp_desc;
> +
> /* Parser function. */
>
> int (*la_parser) (void);
> @@ -174,10 +179,6 @@ struct language_defn
> /* Parser error function */
>
> void (*la_error) (char *);
> -
> - /* Evaluate an expression. */
> - struct value *(*evaluate_exp) (struct type *, struct expression *,
> - int *, enum noside);
>
> void (*la_printchar) (int ch, struct ui_file * stream);
>
> Index: current-public.25/gdb/m2-lang.c
> --- current-public.25/gdb/m2-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.2.2.1 644)
> +++ submit.16(w)/gdb/m2-lang.c Tue, 16 Sep 2003 01:31:53 -0700 hilfingr (GdbPub/i/38_m2-lang.c 1.1.1.2.2.3 644)
> @@ -415,9 +415,9 @@ const struct language_defn m2_language_d
> range_check_on,
> type_check_on,
> case_sensitive_on,
> + &exp_descriptor_standard,
> m2_parse, /* parser */
> m2_error, /* parser error function */
> - evaluate_subexp_standard,
> m2_printchar, /* Print character constant */
> m2_printstr, /* function to print string constant */
> m2_emit_char, /* Function to print a single character */
> Index: current-public.25/gdb/parse.c
> --- current-public.25/gdb/parse.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4.3.1 644)
> +++ submit.16(w)/gdb/parse.c Thu, 18 Sep 2003 02:08:40 -0700 hilfingr (GdbPub/j/29_parse.c 1.1.1.4.3.4 644)
> @@ -50,6 +50,17 @@
> #include "gdb_assert.h"
> #include "block.h"
>
> +/* Standard set of definitions for printing, dumping, prefixifying,
> + * and evaluating expressions. */
> +
> +const struct exp_descriptor exp_descriptor_standard =
> + {
> + print_subexp_standard,
> + operator_length_standard,
> + op_name_standard,
> + dump_subexp_body_standard,
> + evaluate_subexp_standard
> + };
> \f
> /* Symbols which architectures can redefine. */
>
> @@ -771,8 +782,7 @@ copy_name (struct stoken token)
> static void
> prefixify_expression (struct expression *expr)
> {
> - int len =
> - sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
> + int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
> struct expression *temp;
> int inpos = expr->nelts, outpos = 0;
>
> @@ -784,18 +794,48 @@ prefixify_expression (struct expression
> prefixify_subexp (temp, expr, inpos, outpos);
> }
>
> -/* Return the number of exp_elements in the subexpression of EXPR
> - whose last exp_element is at index ENDPOS - 1 in EXPR. */
> +/* Return the number of exp_elements in the postfix subexpression
> + of EXPR whose operator is at index ENDPOS - 1 in EXPR. */
>
> int
> length_of_subexp (struct expression *expr, int endpos)
> {
> + int oplen, args, i;
> +
> + operator_length (expr, endpos, &oplen, &args);
> +
> + while (args > 0)
> + {
> + oplen += length_of_subexp (expr, endpos - oplen);
> + args--;
> + }
> +
> + return oplen;
> +}
> +
> +/* Sets *OPLENP to the length of the operator whose (last) index is
> + ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that
> + operator takes. */
> +
> +void
> +operator_length (struct expression *expr, int endpos, int *oplenp, int *argsp)
> +{
> + expr->language_defn->la_exp_desc->operator_length (expr, endpos,
> + oplenp, argsp);
> +}
> +
> +/* Default value for operator_length in exp_descriptor vectors. */
> +
> +void
> +operator_length_standard (struct expression *expr, int endpos,
> + int *oplenp, int *argsp)
> +{
> int oplen = 1;
> int args = 0;
> int i;
>
> if (endpos < 1)
> - error ("?error in length_of_subexp");
> + error ("?error in operator_length_standard");
>
> i = (int) expr->elts[endpos - 1].opcode;
>
> @@ -916,13 +956,8 @@ length_of_subexp (struct expression *exp
> args = 1 + (i < (int) BINOP_END);
> }
>
> - while (args > 0)
> - {
> - oplen += length_of_subexp (expr, endpos - oplen);
> - args--;
> - }
> -
> - return oplen;
> + *oplenp = oplen;
> + *argsp = args;
> }
>
> /* Copy the subexpression ending just before index INEND in INEXPR
> @@ -933,132 +968,13 @@ static void
> prefixify_subexp (struct expression *inexpr,
> struct expression *outexpr, int inend, int outbeg)
> {
> - int oplen = 1;
> - int args = 0;
> + int oplen;
> + int args;
> int i;
> int *arglens;
> enum exp_opcode opcode;
>
> - /* Compute how long the last operation is (in OPLEN),
> - and also how many preceding subexpressions serve as
> - arguments for it (in ARGS). */
> -
> - opcode = inexpr->elts[inend - 1].opcode;
> - switch (opcode)
> - {
> - /* C++ */
> - case OP_SCOPE:
> - oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
> - oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
> - break;
> -
> - case OP_LONG:
> - case OP_DOUBLE:
> - case OP_VAR_VALUE:
> - oplen = 4;
> - break;
> -
> - case OP_TYPE:
> - case OP_BOOL:
> - case OP_LAST:
> - case OP_REGISTER:
> - case OP_INTERNALVAR:
> - oplen = 3;
> - break;
> -
> - case OP_COMPLEX:
> - oplen = 1;
> - args = 2;
> - break;
> -
> - case OP_FUNCALL:
> - case OP_F77_UNDETERMINED_ARGLIST:
> - oplen = 3;
> - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
> - break;
> -
> - case OP_OBJC_MSGCALL: /* Objective C message (method) call */
> - oplen = 4;
> - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
> - break;
> -
> - case UNOP_MIN:
> - case UNOP_MAX:
> - oplen = 3;
> - break;
> -
> - case UNOP_CAST:
> - case UNOP_MEMVAL:
> - oplen = 3;
> - args = 1;
> - break;
> -
> - case UNOP_ABS:
> - case UNOP_CAP:
> - case UNOP_CHR:
> - case UNOP_FLOAT:
> - case UNOP_HIGH:
> - case UNOP_ODD:
> - case UNOP_ORD:
> - case UNOP_TRUNC:
> - oplen = 1;
> - args = 1;
> - break;
> -
> - case STRUCTOP_STRUCT:
> - case STRUCTOP_PTR:
> - case OP_LABELED:
> - args = 1;
> - /* fall through */
> - case OP_M2_STRING:
> - case OP_STRING:
> - case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant */
> - case OP_OBJC_SELECTOR: /* Objective C "@selector" pseudo-op */
> - case OP_NAME:
> - case OP_EXPRSTRING:
> - oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
> - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
> - break;
> -
> - case OP_BITSTRING:
> - oplen = longest_to_int (inexpr->elts[inend - 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 (inexpr->elts[inend - 2].longconst);
> - args -= longest_to_int (inexpr->elts[inend - 3].longconst);
> - args += 1;
> - break;
> -
> - case TERNOP_COND:
> - case TERNOP_SLICE:
> - case TERNOP_SLICE_COUNT:
> - args = 3;
> - break;
> -
> - case BINOP_ASSIGN_MODIFY:
> - oplen = 3;
> - args = 2;
> - break;
> -
> - /* Modula-2 */
> - case MULTI_SUBSCRIPT:
> - oplen = 3;
> - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
> - break;
> -
> - /* C++ */
> - case OP_THIS:
> - case OP_OBJC_SELF:
> - oplen = 2;
> - break;
> -
> - default:
> - args = 1 + ((int) opcode < (int) BINOP_END);
> - }
> + operator_length (inexpr, inend, &oplen, &args);
>
> /* Copy the final operator itself, from the end of the input
> to the beginning of the output. */
> @@ -1156,14 +1072,13 @@ parse_exp_1 (char **stringptr, struct bl
> parser, to a prefix form. */
>
> if (expressiondebug)
> - dump_prefix_expression (expout, gdb_stdlog,
> - "before conversion to prefix form");
> + dump_raw_expression (expout, gdb_stdlog,
> + "before conversion to prefix form");
>
> prefixify_expression (expout);
>
> if (expressiondebug)
> - dump_postfix_expression (expout, gdb_stdlog,
> - "after conversion to prefix form");
> + dump_prefix_expression (expout, gdb_stdlog);
>
> *stringptr = lexptr;
> return expout;
> Index: current-public.25/gdb/parser-defs.h
> --- current-public.25/gdb/parser-defs.h Tue, 17 Jun 2003 02:35:33 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2 644)
> +++ submit.16(w)/gdb/parser-defs.h Thu, 18 Sep 2003 01:58:16 -0700 hilfingr (GdbPub/j/30_parser-def 1.1.1.2.1.5 644)
> @@ -159,6 +159,17 @@ extern int pop_type_int (void);
>
> extern int length_of_subexp (struct expression *, int);
>
> +extern int dump_subexp (struct expression *, struct ui_file *, int);
> +
> +extern int dump_subexp_body_standard (struct expression *,
> + struct ui_file *, int);
> +
> +extern void operator_length (struct expression *, int, int *, int *);
> +
> +extern void operator_length_standard (struct expression *, int, int *, int *);
> +
> +extern char *op_name_standard (enum exp_opcode);
> +
> extern struct type *follow_types (struct type *);
>
> /* During parsing of a C expression, the pointer to the next character
> @@ -219,6 +230,46 @@ struct op_print
> For a unary operator: 1 iff postfix. */
> int right_assoc;
> };
> +
> +/* Information needed to print, prefixify, and evaluate expressions for
> + a given language. */
> +
> +struct exp_descriptor
> + {
> + /* Print subexpression. */
> + void (*print_subexp) (struct expression *, int *, struct ui_file *,
> + enum precedence);
> +
> + /* Returns number of exp_elements needed to represent an operator and
> + the number of subexpressions it takes. */
> + void (*operator_length) (struct expression*, int, int*, int *);
> +
> + /* Name of this operator for dumping purposes. */
> + char *(*op_name) (enum exp_opcode);
> +
> + /* Dump the rest of this (prefix) expression after the operator
> + itself has been printed. See dump_subexp_body_standard in
> + (expprint.c). */
> + int (*dump_subexp_body) (struct expression *, struct ui_file *, int);
> +
> + /* Evaluate an expression. */
> + struct value *(*evaluate_exp) (struct type *, struct expression *,
> + int *, enum noside);
> + };
> +
> +
> +/* Default descriptor containing standard definitions of all
> + elements. */
> +extern const struct exp_descriptor exp_descriptor_standard;
> +
> +/* Functions used by language-specific extended operators to (recursively)
> + print/dump subexpressions. */
> +
> +extern void print_subexp (struct expression *, int *, struct ui_file *,
> + enum precedence);
> +
> +extern void print_subexp_standard (struct expression *, int *,
> + struct ui_file *, enum precedence);
>
> /* Function used to avoid direct calls to fprintf
> in the code generated by the bison parser. */
> Index: current-public.25/gdb/scm-lang.c
> --- current-public.25/gdb/scm-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.3.2.1 644)
> +++ submit.16(w)/gdb/scm-lang.c Tue, 16 Sep 2003 01:31:52 -0700 hilfingr (GdbPub/k/14_scm-lang.c 1.1.1.3.2.3 644)
> @@ -233,6 +233,15 @@ nosideret:
> return value_from_longest (builtin_type_long, (LONGEST) 1);
> }
>
> +const struct exp_descriptor exp_descriptor_scm =
> +{
> + print_subexp_standard,
> + operator_length_standard,
> + op_name_standard,
> + dump_subexp_body_standard,
> + evaluate_subexp_scm
> +};
> +
> const struct language_defn scm_language_defn =
> {
> "scheme", /* Language name */
> @@ -241,9 +250,9 @@ const struct language_defn scm_language_
> range_check_off,
> type_check_off,
> case_sensitive_off,
> + &exp_descriptor_scm,
> scm_parse,
> c_error,
> - evaluate_subexp_scm,
> scm_printchar, /* Print a character constant */
> scm_printstr, /* Function to print string constant */
> NULL, /* Function to print a single character */
> Index: current-public.25/gdb/objc-lang.c
> --- current-public.25/gdb/objc-lang.c Thu, 11 Sep 2003 02:43:43 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4.3.1 644)
> +++ submit.16(w)/gdb/objc-lang.c Tue, 16 Sep 2003 01:48:04 -0700 hilfingr (GdbPub/C/b/24_objc-lang. 1.4.3.3 644)
> @@ -659,9 +659,9 @@ const struct language_defn objc_language
> range_check_off,
> type_check_off,
> case_sensitive_on,
> + &exp_descriptor_standard,
> objc_parse,
> objc_error,
> - evaluate_subexp_standard,
> objc_printchar, /* Print a character constant */
> objc_printstr, /* Function to print string constant */
> objc_emit_char,
> @@ -1537,8 +1537,8 @@ print_object_command (char *args, int fr
> make_cleanup (free_current_contents, &expr);
> int pc = 0;
>
> - object = expr->language_defn->evaluate_exp (builtin_type_void_data_ptr,
> - expr, &pc, EVAL_NORMAL);
> + object = expr->language_defn->la_exp_desc->evaluate_exp
> + (builtin_type_void_data_ptr, expr, &pc, EVAL_NORMAL);
> do_cleanups (old_chain);
> }
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2003-09-22 17:04 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-01 9:39 RFA: Changes to allow extensions to operator set Paul Hilfinger
2003-09-04 2:18 ` Andrew Cagney
2003-09-05 8:32 ` Paul Hilfinger
2003-09-05 15:57 ` Andrew Cagney
2003-09-05 16:23 ` Andrew Cagney
2003-09-06 11:13 ` Paul Hilfinger
2003-09-11 18:55 ` Andrew Cagney
2003-09-13 8:58 ` Paul Hilfinger
2003-09-18 9:20 ` Paul Hilfinger
2003-09-22 17:04 ` Andrew Cagney
2003-09-05 16:29 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox