/* Modula 2 language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2021 Free Software Foundation, Inc.
+ Copyright (C) 1992-2023 Free Software Foundation, Inc.
This file is part of GDB.
#include "c-lang.h"
#include "valprint.h"
#include "gdbarch.h"
+#include "m2-exp.h"
/* A helper function for UNOP_HIGH. */
-static struct value *
+struct value *
eval_op_m2_high (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1)
{
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else
{
arg1 = coerce_ref (arg1);
- struct type *type = check_typedef (value_type (arg1));
+ struct type *type = check_typedef (arg1->type ());
if (m2_is_unbounded_array (type))
{
type = type->field (1).type ();
/* i18n: Do not translate the "_m2_high" part! */
- arg1 = value_struct_elt (&temp, NULL, "_m2_high", NULL,
+ arg1 = value_struct_elt (&temp, {}, "_m2_high", NULL,
_("unbounded structure "
"missing _m2_high field"));
- if (value_type (arg1) != type)
+ if (arg1->type () != type)
arg1 = value_cast (type, arg1);
}
}
return arg1;
}
-static struct value *
-evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
- int *pos, enum noside noside)
+/* A helper function for BINOP_SUBSCRIPT. */
+
+struct value *
+eval_op_m2_subscript (struct type *expect_type, struct expression *exp,
+ enum noside noside,
+ struct value *arg1, struct value *arg2)
{
- enum exp_opcode op = exp->elts[*pos].opcode;
- struct value *arg1;
- struct value *arg2;
- struct type *type;
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
- switch (op)
- {
- case UNOP_HIGH:
- (*pos)++;
- arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
- return eval_op_m2_high (expect_type, exp, noside, arg1);
-
- case BINOP_SUBSCRIPT:
- (*pos)++;
- arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- /* If the user attempts to subscript something that is not an
- array or pointer type (like a plain int variable for example),
- then report this as an error. */
+ arg1 = coerce_ref (arg1);
+ struct type *type = check_typedef (arg1->type ());
- arg1 = coerce_ref (arg1);
- type = check_typedef (value_type (arg1));
-
- if (m2_is_unbounded_array (type))
- {
- struct value *temp = arg1;
- type = type->field (0).type ();
- if (type == NULL || (type->code () != TYPE_CODE_PTR))
- {
- warning (_("internal error: unbounded "
- "array structure is unknown"));
- return evaluate_subexp_standard (expect_type, exp, pos, noside);
- }
- /* i18n: Do not translate the "_m2_contents" part! */
- arg1 = value_struct_elt (&temp, NULL, "_m2_contents", NULL,
- _("unbounded structure "
- "missing _m2_contents field"));
+ if (m2_is_unbounded_array (type))
+ {
+ struct value *temp = arg1;
+ type = type->field (0).type ();
+ if (type == NULL || (type->code () != TYPE_CODE_PTR))
+ error (_("internal error: unbounded "
+ "array structure is unknown"));
+ /* i18n: Do not translate the "_m2_contents" part! */
+ arg1 = value_struct_elt (&temp, {}, "_m2_contents", NULL,
+ _("unbounded structure "
+ "missing _m2_contents field"));
- if (value_type (arg1) != type)
- arg1 = value_cast (type, arg1);
-
- check_typedef (value_type (arg1));
- return value_ind (value_ptradd (arg1, value_as_long (arg2)));
- }
- else
- if (type->code () != TYPE_CODE_ARRAY)
- {
- if (type->name ())
- error (_("cannot subscript something of type `%s'"),
- type->name ());
- else
- error (_("cannot subscript requested type"));
- }
-
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
- else
- return value_subscript (arg1, value_as_long (arg2));
+ if (arg1->type () != type)
+ arg1 = value_cast (type, arg1);
- default:
- return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ check_typedef (arg1->type ());
+ return value_ind (value_ptradd (arg1, value_as_long (arg2)));
}
-
- nosideret:
- return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
+ else
+ if (type->code () != TYPE_CODE_ARRAY)
+ {
+ if (type->name ())
+ error (_("cannot subscript something of type `%s'"),
+ type->name ());
+ else
+ error (_("cannot subscript requested type"));
+ }
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value::zero (type->target_type (), arg1->lval ());
+ else
+ return value_subscript (arg1, value_as_long (arg2));
}
-\f
-
-/* Table of operators and their precedences for printing expressions. */
-const struct op_print m2_language::op_print_tab[] =
-{
- {"+", BINOP_ADD, PREC_ADD, 0},
- {"+", UNOP_PLUS, PREC_PREFIX, 0},
- {"-", BINOP_SUB, PREC_ADD, 0},
- {"-", UNOP_NEG, PREC_PREFIX, 0},
- {"*", BINOP_MUL, PREC_MUL, 0},
- {"/", BINOP_DIV, PREC_MUL, 0},
- {"DIV", BINOP_INTDIV, PREC_MUL, 0},
- {"MOD", BINOP_REM, PREC_MUL, 0},
- {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
- {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
- {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
- {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
- {"=", BINOP_EQUAL, PREC_EQUAL, 0},
- {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
- {"<=", BINOP_LEQ, PREC_ORDER, 0},
- {">=", BINOP_GEQ, PREC_ORDER, 0},
- {">", BINOP_GTR, PREC_ORDER, 0},
- {"<", BINOP_LESS, PREC_ORDER, 0},
- {"^", UNOP_IND, PREC_PREFIX, 0},
- {"@", BINOP_REPEAT, PREC_REPEAT, 0},
- {"CAP", UNOP_CAP, PREC_BUILTIN_FUNCTION, 0},
- {"CHR", UNOP_CHR, PREC_BUILTIN_FUNCTION, 0},
- {"ORD", UNOP_ORD, PREC_BUILTIN_FUNCTION, 0},
- {"FLOAT", UNOP_FLOAT, PREC_BUILTIN_FUNCTION, 0},
- {"HIGH", UNOP_HIGH, PREC_BUILTIN_FUNCTION, 0},
- {"MAX", UNOP_MAX, PREC_BUILTIN_FUNCTION, 0},
- {"MIN", UNOP_MIN, PREC_BUILTIN_FUNCTION, 0},
- {"ODD", UNOP_ODD, PREC_BUILTIN_FUNCTION, 0},
- {"TRUNC", UNOP_TRUNC, PREC_BUILTIN_FUNCTION, 0},
- {NULL, OP_NULL, PREC_BUILTIN_FUNCTION, 0}
-};
\f
-const struct exp_descriptor m2_language::exp_descriptor_modula2 =
-{
- print_subexp_standard,
- operator_length_standard,
- operator_check_standard,
- dump_subexp_body_standard,
- evaluate_subexp_modula2
-};
-
/* Single instance of the M2 language. */
static m2_language m2_language_defn;
lai->set_bool_type (builtin->builtin_bool, "BOOLEAN");
}
-/* See languge.h. */
+/* See language.h. */
void
m2_language::printchar (int c, struct type *type,
struct ui_file *stream) const
{
- fputs_filtered ("'", stream);
+ gdb_puts ("'", stream);
emitchar (c, type, stream, '\'');
- fputs_filtered ("'", stream);
+ gdb_puts ("'", stream);
}
/* See language.h. */
if (length == 0)
{
- fputs_filtered ("\"\"", gdb_stdout);
+ gdb_puts ("\"\"");
return;
}
- for (i = 0; i < length && things_printed < options->print_max; ++i)
+ unsigned int print_max_chars = get_print_max_chars (options);
+ for (i = 0; i < length && things_printed < print_max_chars; ++i)
{
/* Position of the character we are examining
to see whether it is repeated. */
if (need_comma)
{
- fputs_filtered (", ", stream);
+ gdb_puts (", ", stream);
need_comma = 0;
}
{
if (in_quotes)
{
- fputs_filtered ("\", ", stream);
+ gdb_puts ("\", ", stream);
in_quotes = 0;
}
printchar (string[i], elttype, stream);
- fprintf_filtered (stream, " <repeats %u times>", reps);
+ gdb_printf (stream, " <repeats %u times>", reps);
i = rep1 - 1;
things_printed += options->repeat_count_threshold;
need_comma = 1;
{
if (!in_quotes)
{
- fputs_filtered ("\"", stream);
+ gdb_puts ("\"", stream);
in_quotes = 1;
}
emitchar (string[i], elttype, stream, '"');
/* Terminate the quotes if necessary. */
if (in_quotes)
- fputs_filtered ("\"", stream);
+ gdb_puts ("\"", stream);
if (force_ellipses || i < length)
- fputs_filtered ("...", stream);
+ gdb_puts ("...", stream);
}
/* See language.h. */
if (PRINT_LITERAL_FORM (ch))
{
if (ch == '\\' || ch == quoter)
- fputs_filtered ("\\", stream);
- fprintf_filtered (stream, "%c", ch);
+ gdb_puts ("\\", stream);
+ gdb_printf (stream, "%c", ch);
}
else
{
switch (ch)
{
case '\n':
- fputs_filtered ("\\n", stream);
+ gdb_puts ("\\n", stream);
break;
case '\b':
- fputs_filtered ("\\b", stream);
+ gdb_puts ("\\b", stream);
break;
case '\t':
- fputs_filtered ("\\t", stream);
+ gdb_puts ("\\t", stream);
break;
case '\f':
- fputs_filtered ("\\f", stream);
+ gdb_puts ("\\f", stream);
break;
case '\r':
- fputs_filtered ("\\r", stream);
+ gdb_puts ("\\r", stream);
break;
case '\033':
- fputs_filtered ("\\e", stream);
+ gdb_puts ("\\e", stream);
break;
case '\007':
- fputs_filtered ("\\a", stream);
+ gdb_puts ("\\a", stream);
break;
default:
- fprintf_filtered (stream, "\\%.3o", (unsigned int) ch);
+ gdb_printf (stream, "\\%.3o", (unsigned int) ch);
break;
}
}
/* Called during architecture gdbarch initialisation to create language
specific types. */
-static void *
+static struct builtin_m2_type *
build_m2_types (struct gdbarch *gdbarch)
{
- struct builtin_m2_type *builtin_m2_type
- = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_m2_type);
+ struct builtin_m2_type *builtin_m2_type = new struct builtin_m2_type;
+
+ type_allocator alloc (gdbarch);
/* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
builtin_m2_type->builtin_int
- = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "INTEGER");
+ = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 0, "INTEGER");
builtin_m2_type->builtin_card
- = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "CARDINAL");
+ = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 1, "CARDINAL");
builtin_m2_type->builtin_real
- = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch), "REAL",
+ = init_float_type (alloc, gdbarch_float_bit (gdbarch), "REAL",
gdbarch_float_format (gdbarch));
builtin_m2_type->builtin_char
- = arch_character_type (gdbarch, TARGET_CHAR_BIT, 1, "CHAR");
+ = init_character_type (alloc, TARGET_CHAR_BIT, 1, "CHAR");
builtin_m2_type->builtin_bool
- = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "BOOLEAN");
+ = init_boolean_type (alloc, gdbarch_int_bit (gdbarch), 1, "BOOLEAN");
return builtin_m2_type;
}
-static struct gdbarch_data *m2_type_data;
+static const registry<gdbarch>::key<struct builtin_m2_type> m2_type_data;
const struct builtin_m2_type *
builtin_m2_type (struct gdbarch *gdbarch)
{
- return (const struct builtin_m2_type *) gdbarch_data (gdbarch, m2_type_data);
-}
-
-
-/* Initialization for Modula-2 */
+ struct builtin_m2_type *result = m2_type_data.get (gdbarch);
+ if (result == nullptr)
+ {
+ result = build_m2_types (gdbarch);
+ m2_type_data.set (gdbarch, result);
+ }
-void _initialize_m2_language ();
-void
-_initialize_m2_language ()
-{
- m2_type_data = gdbarch_data_register_post_init (build_m2_types);
+ return result;
}