From 5f9769d1720b4b1d0e6375a1eb6a554fa3b29b90 Mon Sep 17 00:00:00 2001 From: "Paul N. Hilfinger" Date: Thu, 25 Sep 2003 08:40:45 +0000 Subject: [PATCH] * 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_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 (operator_length): Move most code to new operator_length_standard function. Use language-specific information. (operator_length_standard): New function taking most code from operator_length. (exp_descriptor_standard): New constant. * expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0 and OP_EXTENDED_LAST. * expprint.c (print_subexp): Use language-specific print_subexp. Make global; remove static declaration. Move most 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): Use new version of op_name function. Use language-specific dump_subexp_body, and move most existing code to dump_subexp_body_standard. (dump_raw_expression): Use new op_name interface. (dump_subexp_body): Move most code to dump_subexp_body_standard. (dump_subexp_body_standard): New function, containing code formerly in dump_subexp_body. * 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 and remove evaluate_exp field. * scm-lang.c (exp_descriptor_scm): New variable, containing Scheme-specific expression evaluator. (scm_language_defn): Add la_exp_desc field and remove evaluate_exp 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. --- gdb/ChangeLog | 74 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/Makefile.in | 3 +- gdb/c-lang.c | 8 ++--- gdb/eval.c | 4 ++- gdb/expprint.c | 44 +++++++++++++++++++++------- gdb/expression.h | 22 +++++++++++++- gdb/f-lang.c | 2 +- gdb/jv-lang.c | 11 ++++++- gdb/language.c | 6 ++-- gdb/language.h | 9 +++--- gdb/m2-lang.c | 2 +- gdb/objc-lang.c | 6 ++-- gdb/p-lang.c | 2 +- gdb/parse.c | 23 ++++++++++++++- gdb/parser-defs.h | 49 +++++++++++++++++++++++++++++++ gdb/scm-lang.c | 11 ++++++- 16 files changed, 243 insertions(+), 33 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 04798de293..12fd3c2d34 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,77 @@ +2003-09-24 Paul N. Hilfinger + + * 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_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 (operator_length): Move most code to new + operator_length_standard function. Use language-specific information. + (operator_length_standard): New function taking most code from + operator_length. + (exp_descriptor_standard): New constant. + + * expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0 + and OP_EXTENDED_LAST. + + * expprint.c (print_subexp): Use language-specific print_subexp. + Make global; remove static declaration. + Move most 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): Use new version of op_name function. + Use language-specific dump_subexp_body, and move most existing code to + dump_subexp_body_standard. + (dump_raw_expression): Use new op_name interface. + (dump_subexp_body): Move most code to dump_subexp_body_standard. + (dump_subexp_body_standard): New function, containing code formerly + in dump_subexp_body. + + * 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 and remove evaluate_exp + field. + * scm-lang.c (exp_descriptor_scm): New variable, containing + Scheme-specific expression evaluator. + (scm_language_defn): Add la_exp_desc field and remove evaluate_exp + 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. + 2003-09-23 Paul N. Hilfinger * parser-defs.h (operator_length): Declare. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 7b681e3723..350a255be5 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1735,7 +1735,8 @@ elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_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) \ diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 4a5a3628ef..f5a87a473b 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -543,9 +543,9 @@ const struct language_defn c_language_defn = 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_language_defn = 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_defn = 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_language_defn = 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 */ diff --git a/gdb/eval.c b/gdb/eval.c index 9a3af671cb..cda14946eb 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -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); } /* Parse the string EXP as a C expression, evaluate it, diff --git a/gdb/expprint.c b/gdb/expprint.c index 8db4c36111..5949475927 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -36,11 +36,6 @@ #include #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,9 +48,18 @@ print_expression (struct expression *exp, struct ui_file *stream) 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; @@ -547,11 +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) { @@ -756,7 +771,7 @@ dump_raw_expression (struct expression *exp, struct ui_file *stream, 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); @@ -791,7 +806,7 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) 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); @@ -806,6 +821,15 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt) 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; diff --git a/gdb/expression.h b/gdb/expression.h index 356725ea2f..03b45c2ef9 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -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 diff --git a/gdb/f-lang.c b/gdb/f-lang.c index 52f56b3607..f84e0505fe 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -462,9 +462,9 @@ const struct language_defn f_language_defn = 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 */ diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c index e9b86d20c4..0913aceb8a 100644 --- a/gdb/jv-lang.c +++ b/gdb/jv-lang.c @@ -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_defn = 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 */ diff --git a/gdb/language.c b/gdb/language.c index 9d195d89b9..28cdd27a24 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -1267,9 +1267,9 @@ const struct language_defn unknown_language_defn = 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_defn = 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_language_defn = 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, diff --git a/gdb/language.h b/gdb/language.h index 75ca555452..baa49ec6fa 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -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); @@ -175,10 +180,6 @@ struct language_defn 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); void (*la_printstr) (struct ui_file * stream, char *string, diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index a54d188d0a..f0679070ff 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -415,9 +415,9 @@ const struct language_defn m2_language_defn = 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 */ diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index e399818224..7c74e6daf3 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -659,9 +659,9 @@ const struct language_defn objc_language_defn = { 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 from_tty) 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); } diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 836f5f32b7..a12f7ec78a 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -451,9 +451,9 @@ const struct language_defn pascal_language_defn = 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 */ diff --git a/gdb/parse.c b/gdb/parse.c index 6166cf633b..da39866f75 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -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 + }; /* Symbols which architectures can redefine. */ @@ -809,13 +820,23 @@ length_of_subexp (struct expression *expr, int endpos) 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 operator_length"); + error ("?error in operator_length_standard"); i = (int) expr->elts[endpos - 1].opcode; diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index 54b39a8b0b..c84fcad2c1 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -159,8 +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 @@ -222,6 +231,46 @@ struct op_print 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. */ diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c index 83d88ccd63..b02fd6fa2b 100644 --- a/gdb/scm-lang.c +++ b/gdb/scm-lang.c @@ -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_defn = 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 */ -- 2.34.1