* [PATCH] Unbounded array support implemented (for Modula-2)
@ 2007-07-26 7:07 Gaius Mulley
2007-07-26 7:36 ` Markus Deuling
2007-07-26 22:58 ` Pierre Muller
0 siblings, 2 replies; 18+ messages in thread
From: Gaius Mulley @ 2007-07-26 7:07 UTC (permalink / raw)
To: gdb-patches
Hi,
The patch below allows users debugging Modula-2 programs to print
unbounded parameter contents, ptype the parameter declaration and
perform unbounded array subscript queries. It also adds TSIZE
(pseudonym for SIZE) and implements HIGH (yields the last legal index
for an unbounded array).
Wondering whether this is okay to commit? Feel free to suggest
improvements etc,
regards,
Gaius
I've run check-gdb and get the following final results:
# of expected passes 11389
# of unexpected failures 78
# of unexpected successes 2
# of expected failures 41
# of known failures 39
# of unresolved testcases 1
# of untested testcases 8
# of unsupported tests 14
... build-gdb/gdb/testsuite/../../gdb/gdb version
# 6.6.50.20070724-cvs -nx
2004-07-26 Gaius Mulley <gaius@glam.ac.uk>
* doc/gdb.texinfo: Add TSIZE definition, removed
statement about unbounded arrays being unimplemented.
* m2-valprint.c (m2_print_array_contents): New function.
(m2_print_unbounded_array): New function.
(m2_print_array_contents): New function.
* m2-typeprint.c (m2_unbounded_array): New function.
(m2_is_unbounded_array): New function.
(m2_print_type): Test for unbounded array when walking
across structs.
* m2-lang.h: Added extern m2_is_unbounded_array.
* m2-lang.c (evaluate_subexp_modula2): New function.
(exp_descriptor_modula2): New structure.
(m2_language_defn): Use exp_descriptor_modula2.
* m2-exp.y: Added TSIZE and binary subscript.
--- gdb-cvs/src/gdb/doc/gdb.texinfo 2007-07-12 08:57:57.000000000 +0100
+++ gdb-cvs-modified/src/gdb/doc/gdb.texinfo 2007-07-25 23:50:48.000000000 +0100
@@ -9908,6 +9908,9 @@
@item TRUNC(@var{r})
Returns the integral part of @var{r}.
+@item TSIZE(@var{x})
+Returns the size of its argument. @var{x} can be a variable or a type.
+
@item VAL(@var{t},@var{i})
Returns the member of the type @var{t} whose ordinal value is @var{i}.
@end table
@@ -10038,7 +10041,7 @@
Note that the array handling is not yet complete and although the type
is printed correctly, expression handling still assumes that all
arrays have a lower bound of zero and not @code{-10} as in the example
-above. Unbounded arrays are also not yet recognized in @value{GDBN}.
+above.
Here are some more type related Modula-2 examples:
--- gdb-cvs/src/gdb/m2-valprint.c 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-valprint.c 2007-07-26 00:35:17.000000000 +0100
@@ -35,6 +35,12 @@
int print_unpacked_pointer (struct type *type,
CORE_ADDR address, CORE_ADDR addr,
int format, struct ui_file *stream);
+static void
+m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty,
+ int deref_ref, int recurse, int len);
/* Print function pointer with inferior address ADDRESS onto stdio
@@ -178,6 +184,36 @@
}
}
+static void
+m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ int deref_ref, enum val_prettyprint pretty,
+ int recurse)
+{
+ struct type *content_type;
+ CORE_ADDR addr;
+ LONGEST len;
+ struct value *val;
+
+ CHECK_TYPEDEF (type);
+ content_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0));
+
+ addr = unpack_pointer (TYPE_FIELD_TYPE (type, 0),
+ (TYPE_FIELD_BITPOS (type, 0) / 8) +
+ valaddr + embedded_offset);
+
+ val = value_at_lazy (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)),
+ addr);
+ len = unpack_field_as_long (type, valaddr + embedded_offset, 1);
+
+ fprintf_filtered (stream, "{");
+ m2_print_array_contents (value_type (val), value_contents(val),
+ value_embedded_offset (val), addr, stream,
+ format, deref_ref, pretty, recurse, len);
+ fprintf_filtered (stream, ", HIGH = %d}", (int) len);
+}
+
int
print_unpacked_pointer (struct type *type,
CORE_ADDR address, CORE_ADDR addr,
@@ -203,13 +239,15 @@
&& TYPE_CODE (elttype) == TYPE_CODE_INT
&& (format == 0 || format == 's')
&& addr != 0)
- return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+ return val_print_string (addr, -1, TYPE_LENGTH (elttype),
+ stream);
return 0;
}
static void
-print_variable_at_address (struct type *type, const gdb_byte *valaddr,
+print_variable_at_address (struct type *type,
+ const gdb_byte *valaddr,
struct ui_file *stream, int format,
int deref_ref, int recurse,
enum val_prettyprint pretty)
@@ -235,6 +273,49 @@
fputs_filtered ("???", stream);
}
+
+/*
+ * m2_print_array_contents - prints out the contents of an
+ * array up to a max_print values.
+ * It prints arrays of char as a string
+ * and all other data types as comma
+ * separated values.
+ */
+
+static void
+m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty,
+ int deref_ref, int recurse, int len)
+{
+ int eltlen;
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_LENGTH (type) > 0)
+ {
+ eltlen = TYPE_LENGTH (type);
+ if (prettyprint_arrays)
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ /* For an array of chars, print with string syntax. */
+ if (eltlen == 1 &&
+ ((TYPE_CODE (type) == TYPE_CODE_INT)
+ || ((current_language->la_language == language_m2)
+ && (TYPE_CODE (type) == TYPE_CODE_CHAR)))
+ && (format == 0 || format == 's'))
+ val_print_string (address, len+1, eltlen, stream);
+ else
+ {
+ fprintf_filtered (stream, "{");
+ val_print_array_elements (type, valaddr + embedded_offset,
+ address, stream, format,
+ deref_ref, recurse, pretty, 0);
+ fprintf_filtered (stream, "}");
+ }
+ }
+}
+
+
/* Print data of type TYPE located at VALADDR (within GDB), which came from
the inferior at address ADDRESS, onto stdio stream STREAM according to
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
@@ -366,6 +447,10 @@
if (m2_is_long_set (type))
m2_print_long_set (type, valaddr, embedded_offset, address,
stream, format, pretty);
+ else if (m2_is_unbounded_array (type))
+ m2_print_unbounded_array (type, valaddr, embedded_offset,
+ address, stream, format, deref_ref,
+ pretty, recurse);
else
cp_print_value_fields (type, type, valaddr, embedded_offset,
address, stream, format,
--- gdb-cvs/src/gdb/m2-typeprint.c 2007-06-29 01:35:08.000000000 +0100
+++ gdb-cvs-modified/src/gdb/m2-typeprint.c 2007-07-25 20:58:40.000000000 +0100
@@ -55,6 +55,8 @@
int show, int level);
static int m2_long_set (struct type *type, struct ui_file *stream,
int show, int level);
+static int m2_unbounded_array (struct type *type, struct ui_file *stream,
+ int show, int level);
static void m2_record_fields (struct type *type, struct ui_file *stream,
int show, int level);
static void m2_unknown (const char *s, struct type *type,
@@ -62,6 +64,7 @@
int m2_is_long_set (struct type *type);
int m2_is_long_set_of_type (struct type *type, struct type **of_type);
+int m2_is_unbounded_array (struct type *type);
void
@@ -90,7 +93,8 @@
break;
case TYPE_CODE_STRUCT:
- if (m2_long_set (type, stream, show, level))
+ if (m2_long_set (type, stream, show, level)
+ || m2_unbounded_array (type, stream, show, level))
break;
m2_record_fields (type, stream, show, level);
break;
@@ -474,6 +478,57 @@
return 0;
}
+/*
+ * m2_is_unbounded_array - returns TRUE if, type, should be regarded
+ * as a Modula-2 unbounded ARRAY type.
+ */
+
+int
+m2_is_unbounded_array (struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ /*
+ * check if we have a structure with exactly two fields named
+ * _m2_contents and _m2_high. It also checks to see if the
+ * type of _m2_contents is a pointer. The TYPE_TARGET_TYPE
+ * of the pointer determines the unbounded ARRAY OF type.
+ */
+ if (TYPE_NFIELDS (type) != 2)
+ return 0;
+ if (strcmp (TYPE_FIELD_NAME (type, 0), "_m2_contents") != 0)
+ return 0;
+ if (strcmp (TYPE_FIELD_NAME (type, 1), "_m2_high") != 0)
+ return 0;
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) != TYPE_CODE_PTR)
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * m2_unbounded_array - if the struct type matches a Modula-2 unbounded
+ * parameter type then display the type as an
+ * ARRAY OF type. Returns TRUE if an unbounded
+ * array type was detected.
+ */
+
+static int
+m2_unbounded_array (struct type *type, struct ui_file *stream, int show, int level)
+{
+ struct type *of_type;
+
+ if (m2_is_unbounded_array (type))
+ {
+ fputs_filtered ("ARRAY OF ", stream);
+ m2_print_type (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)),
+ "", stream, 0, level);
+ return 1;
+ }
+ return 0;
+}
+
void
m2_record_fields (struct type *type, struct ui_file *stream, int show,
int level)
--- gdb-cvs/src/gdb/m2-lang.h 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-lang.h 2007-07-25 18:33:42.000000000 +0100
@@ -28,6 +28,7 @@
int);
extern int m2_is_long_set (struct type *type);
+extern int m2_is_unbounded_array (struct type *type);
extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int, int, int,
--- gdb-cvs/src/gdb/m2-lang.c 2007-06-16 21:10:51.000000000 +0100
+++ gdb-cvs-modified/src/gdb/m2-lang.c 2007-07-26 00:44:38.000000000 +0100
@@ -189,6 +189,100 @@
fputs_filtered ("...", stream);
}
+static struct value *
+evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
+ int *pos, enum noside noside)
+{
+ int pc = *pos;
+ int i;
+ char *name;
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ struct value *arg1;
+ struct value *arg2;
+ struct type *type;
+ switch (op)
+ {
+ case UNOP_HIGH:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else
+ {
+ arg1 = coerce_ref (arg1);
+ type = check_typedef (value_type (arg1));
+
+ if (m2_is_unbounded_array (type))
+ {
+ struct value *temp = arg1;
+ type = TYPE_FIELD_TYPE (type, 1);
+ /* i18n: Do not translate the "_m2_high" part! */
+ arg1 = value_struct_elt (&temp, NULL, "_m2_high", NULL,
+ _("unbounded structure "
+ "missing _m2_high field"));
+
+ if (value_type (arg1) != type)
+ arg1 = value_cast (type, arg1);
+ }
+ }
+ return 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);
+ type = check_typedef (value_type (arg1));
+
+ if (m2_is_unbounded_array (type))
+ {
+ struct value *temp = arg1;
+ type = TYPE_FIELD_TYPE (type, 0);
+ if (type == NULL || (TYPE_CODE (type) != 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 (value_type (arg1) != type)
+ arg1 = value_cast (type, arg1);
+
+ type = check_typedef (value_type (arg1));
+ return value_ind (value_add (arg1, arg2));
+ }
+ else
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ {
+ if (TYPE_NAME (type))
+ error (_("cannot subscript something of type `%s'"),
+ TYPE_NAME (type));
+ 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, arg2);
+
+ default:
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ }
+
+ nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
/* FIXME: This is a copy of c_create_fundamental_type(), before
all the non-C types were stripped from it. Needs to be fixed
by an experienced Modula programmer. */
@@ -428,6 +522,15 @@
= builtin->builtin_bool;
}
+const struct exp_descriptor exp_descriptor_modula2 =
+{
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_modula2
+};
+
const struct language_defn m2_language_defn =
{
"modula-2",
@@ -437,7 +540,7 @@
type_check_on,
case_sensitive_on,
array_row_major,
- &exp_descriptor_standard,
+ &exp_descriptor_modula2,
m2_parse, /* parser */
m2_error, /* parser error function */
null_post_parser,
--- gdb-cvs/src/gdb/m2-exp.y 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-exp.y 2007-07-25 21:16:14.000000000 +0100
@@ -174,6 +174,7 @@
%token <sval> TYPENAME
%token SIZE CAP ORD HIGH ABS MIN_FUNC MAX_FUNC FLOAT_FUNC VAL CHR ODD TRUNC
+%token TSIZE
%token INC DEC INCL EXCL
/* The GDB scope operator */
@@ -288,6 +289,10 @@
{ write_exp_elt_opcode (UNOP_TRUNC); }
;
+exp : TSIZE '(' exp ')'
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
+ ;
+
exp : SIZE exp %prec UNARY
{ write_exp_elt_opcode (UNOP_SIZEOF); }
;
@@ -353,6 +358,10 @@
write_exp_elt_opcode (MULTI_SUBSCRIPT); }
;
+exp : exp '[' exp ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ ;
+
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
@@ -809,6 +818,7 @@
{"SIZE", SIZE },
{"FLOAT", FLOAT_FUNC },
{"TRUNC", TRUNC },
+ {"TSIZE", SIZE },
};
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-26 7:07 [PATCH] Unbounded array support implemented (for Modula-2) Gaius Mulley
@ 2007-07-26 7:36 ` Markus Deuling
2007-07-27 12:26 ` Gaius Mulley
2007-07-26 22:58 ` Pierre Muller
1 sibling, 1 reply; 18+ messages in thread
From: Markus Deuling @ 2007-07-26 7:36 UTC (permalink / raw)
To: Gaius Mulley; +Cc: gdb-patches
Hi Gaius,
Gaius Mulley schrieb:
> Hi,
>
> The patch below allows users debugging Modula-2 programs to print
> unbounded parameter contents, ptype the parameter declaration and
> perform unbounded array subscript queries. It also adds TSIZE
> (pseudonym for SIZE) and implements HIGH (yields the last legal index
> for an unbounded array).
>
> Wondering whether this is okay to commit? Feel free to suggest
> improvements etc,
>
> regards,
> Gaius
>
> I've run check-gdb and get the following final results:
>
> # of expected passes 11389
> # of unexpected failures 78
> # of unexpected successes 2
> # of expected failures 41
> # of known failures 39
> # of unresolved testcases 1
> # of untested testcases 8
> # of unsupported tests 14
>
> ... build-gdb/gdb/testsuite/../../gdb/gdb version
> # 6.6.50.20070724-cvs -nx
>
>
do you build GDB on x86? These are my results:
# of expected passes···Â·······11554
# of unexpected failures·······29
# of unexpected successes······1
# of expected failures········42
# of unknown successes········6
# of known failures····Â·······44
# of unresolved testcases······1
# of untested testcases·······8
# of unsupported tests········16
/home/deuling/gdb/dev/build/gdb/testsuite/../../gdb/gdb version 6.6.50.20070725-cvs -nx
Maybe you should compare test results with and without your patch to see if your patch introduces regressions.
It also would be nice to have a new test case to test the new features.
> @@ -203,13 +239,15 @@
> && TYPE_CODE (elttype) == TYPE_CODE_INT
> && (format == 0 || format == 's')
> && addr != 0)
> - return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
> + return val_print_string (addr, -1, TYPE_LENGTH (elttype),
> + stream);
>
> return 0;
> }
This seems to be unnecessary. The current line is < 80 chars.
> @@ -235,6 +273,49 @@
> fputs_filtered ("???", stream);
> }
>
> +
> +/*
> + * m2_print_array_contents - prints out the contents of an
> + * array up to a max_print values.
> + * It prints arrays of char as a string
> + * and all other data types as comma
> + * separated values.
> + */
The final */ should in the same line as "separated values." with two spaces between.
There are some more of that.
> +static struct value *
> +evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
> + int *pos, enum noside noside)
> +{
> + int pc = *pos;
> + int i;
> + char *name;
> + enum exp_opcode op = exp->elts[*pos].opcode;
> + struct value *arg1;
> + struct value *arg2;
> + struct type *type;
> + switch (op)
I think "int i", "char *name" and "int pc" are unneeded in this function?
There should be an empty line after variable declaration to seperate it from the code.
Regards,
--
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-26 7:07 [PATCH] Unbounded array support implemented (for Modula-2) Gaius Mulley
2007-07-26 7:36 ` Markus Deuling
@ 2007-07-26 22:58 ` Pierre Muller
2007-07-27 13:17 ` Gaius Mulley
2007-07-28 0:59 ` Jim Blandy
1 sibling, 2 replies; 18+ messages in thread
From: Pierre Muller @ 2007-07-26 22:58 UTC (permalink / raw)
To: 'Gaius Mulley', gdb-patches
Could you explain why you need to add
TSIZE as a synonym of SIZE?
Is it just a matter of parser shift/reduce conflicts?
Is TSIZE a modula-2 function?
Is your change in gdb.texinfo in a modula-2 specific
area?
Modula-2 is not the only language supporting unbounded
arrays, I would be interested in using the same kind of code for
pascal language support.
Maybe a more general approach would be useful?
One more remark:
in m2_unbounded_array function, it would probably
be better to honor the value of the show argument,
and to only output something if show is non-zero.
Pierre Muller
GDB pascal language support maintainer
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-26 7:36 ` Markus Deuling
@ 2007-07-27 12:26 ` Gaius Mulley
2007-07-27 20:22 ` Eli Zaretskii
0 siblings, 1 reply; 18+ messages in thread
From: Gaius Mulley @ 2007-07-27 12:26 UTC (permalink / raw)
To: Markus Deuling; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 23749 bytes --]
Markus Deuling <deuling@de.ibm.com> writes:
> Gaius Mulley schrieb:
>>
>> The patch below allows users debugging Modula-2 programs to print
>> unbounded parameter contents, ptype the parameter declaration and
>> perform unbounded array subscript queries. It also adds TSIZE
>> (pseudonym for SIZE) and implements HIGH (yields the last legal index
>> for an unbounded array).
>>
>> Wondering whether this is okay to commit? Feel free to suggest
>> improvements etc,
>>
>> I've run check-gdb and get the following final results:
>>
>> # of expected passes 11389
>> # of unexpected failures 78
>> # of unexpected successes 2
>> # of expected failures 41
>> # of known failures 39
>> # of unresolved testcases 1
>> # of untested testcases 8
>> # of unsupported tests 14
>>
>> ... build-gdb/gdb/testsuite/../../gdb/gdb version
>> # 6.6.50.20070724-cvs -nx
>>
>
> do you build GDB on x86? These are my results:
>
> # of expected passes··········11554
> # of unexpected failures·······29
> # of unexpected successes······1
> # of expected failures········42
> # of unknown successes········6
> # of known failures···········44
> # of unresolved testcases······1
> # of untested testcases·······8
> # of unsupported tests········16
> /home/deuling/gdb/dev/build/gdb/testsuite/../../gdb/gdb version
> 6.6.50.20070725-cvs -nx
>
> Maybe you should compare test results with and without your patch to
> see if your patch introduces regressions.
Hi,
thanks for the suggestions - I ran mine on Debian Etch LP64. But I've
since ran it on i386 and have the following results:
before patching:
# of expected passes 11521
# of unexpected failures 11
# of unexpected successes 1
# of expected failures 41
# of unknown successes 6
# of known failures 51
# of untested testcases 8
# of unsupported tests 16
after patching
# of expected passes 11529
# of unexpected failures 11
# of unexpected successes 1
# of expected failures 41
# of unknown successes 6
# of known failures 51
# of untested testcases 8
# of unsupported tests 16
[the extra passes are the new Modula-2 tests - see below]
> It also would be nice to have a new test case to test the new
> features.
sure, I've included a tar ball of new files which implement eight
Modula-2 regression tests against these patches. They build a C test
program which mimics the unbounded array construct and tells gdb to
"set lang modula-2" etc.
>> @@ -203,13 +239,15 @@
>> && TYPE_CODE (elttype) == TYPE_CODE_INT
>> && (format == 0 || format == 's')
>> && addr != 0)
>> - return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
>> + return val_print_string (addr, -1, TYPE_LENGTH (elttype),
>> + stream);
>> return 0;
>> }
> This seems to be unnecessary. The current line is < 80 chars.
ok, thanks - I've reverted this.
>> @@ -235,6 +273,49 @@
>> fputs_filtered ("???", stream);
>> }
>> +
>> +/*
>> + * m2_print_array_contents - prints out the contents of an
>> + * array up to a max_print values.
>> + * It prints arrays of char as a string
>> + * and all other data types as comma
>> + * separated values.
>> + */
> The final */ should in the same line as "separated values." with two spaces between.
> There are some more of that.
ok I've correct all occurrences of the */ in these files now.
>> +static struct value *
>> +evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
>> + int *pos, enum noside noside)
>> +{
>> + int pc = *pos;
>> + int i;
>> + char *name;
>> + enum exp_opcode op = exp->elts[*pos].opcode;
>> + struct value *arg1;
>> + struct value *arg2;
>> + struct type *type;
>> + switch (op)
>
> I think "int i", "char *name" and "int pc" are unneeded in this function?
> There should be an empty line after variable declaration to seperate
> it from the code.
ahh yes - true - all removed now. Thank you for the feedback!
Here are the revised patches:
2004-07-26 Gaius Mulley <gaius@glam.ac.uk>
* doc/gdb.texinfo: Add TSIZE definition, removed
statement about unbounded arrays being unimplemented.
* m2-valprint.c (m2_print_array_contents): New function.
(m2_print_unbounded_array): New function.
(m2_print_array_contents): New function.
* m2-typeprint.c (m2_unbounded_array): New function.
(m2_is_unbounded_array): New function.
(m2_print_type): Test for unbounded array when walking
across structs.
* m2-lang.h: Added extern m2_is_unbounded_array.
* m2-lang.c (evaluate_subexp_modula2): New function.
(exp_descriptor_modula2): New structure.
(m2_language_defn): Use exp_descriptor_modula2.
* m2-exp.y: Added TSIZE and binary subscript.
and ChangeLog for testsuite directory:
2007-07-26 Gaius Mulley <gaius@glam.ac.uk>
* configure.ac: Added gdb.modula2/Makefile to AC_OUTPUT.
* gdb.modula2: New directory.
* gdb.modula2/Makefile.in: New file.
* gdb.modula2/unbounded-array.exp: New file.
* gdb.modula2/unbounded1.c: New file.
--- gdb-cvs/src/gdb/doc/gdb.texinfo 2007-07-12 08:57:57.000000000 +0100
+++ gdb-cvs-modified/src/gdb/doc/gdb.texinfo 2007-07-25 23:50:48.000000000 +0100
@@ -9908,6 +9908,9 @@
@item TRUNC(@var{r})
Returns the integral part of @var{r}.
+@item TSIZE(@var{x})
+Returns the size of its argument. @var{x} can be a variable or a type.
+
@item VAL(@var{t},@var{i})
Returns the member of the type @var{t} whose ordinal value is @var{i}.
@end table
@@ -10038,7 +10041,7 @@
Note that the array handling is not yet complete and although the type
is printed correctly, expression handling still assumes that all
arrays have a lower bound of zero and not @code{-10} as in the example
-above. Unbounded arrays are also not yet recognized in @value{GDBN}.
+above.
Here are some more type related Modula-2 examples:
--- gdb-cvs/src/gdb/m2-valprint.c 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-valprint.c 2007-07-26 12:53:02.000000000 +0100
@@ -35,6 +35,12 @@
int print_unpacked_pointer (struct type *type,
CORE_ADDR address, CORE_ADDR addr,
int format, struct ui_file *stream);
+static void
+m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty,
+ int deref_ref, int recurse, int len);
/* Print function pointer with inferior address ADDRESS onto stdio
@@ -58,9 +64,8 @@
print_address_demangle (func_addr, stream, demangle);
}
-/*
- * get_long_set_bounds - assigns the bounds of the long set to low and high.
- */
+/* get_long_set_bounds - assigns the bounds of the long set to low and
+ high. */
int
get_long_set_bounds (struct type *type, LONGEST *low, LONGEST *high)
@@ -178,6 +183,36 @@
}
}
+static void
+m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ int deref_ref, enum val_prettyprint pretty,
+ int recurse)
+{
+ struct type *content_type;
+ CORE_ADDR addr;
+ LONGEST len;
+ struct value *val;
+
+ CHECK_TYPEDEF (type);
+ content_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0));
+
+ addr = unpack_pointer (TYPE_FIELD_TYPE (type, 0),
+ (TYPE_FIELD_BITPOS (type, 0) / 8) +
+ valaddr + embedded_offset);
+
+ val = value_at_lazy (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)),
+ addr);
+ len = unpack_field_as_long (type, valaddr + embedded_offset, 1);
+
+ fprintf_filtered (stream, "{");
+ m2_print_array_contents (value_type (val), value_contents(val),
+ value_embedded_offset (val), addr, stream,
+ format, deref_ref, pretty, recurse, len);
+ fprintf_filtered (stream, ", HIGH = %d}", (int) len);
+}
+
int
print_unpacked_pointer (struct type *type,
CORE_ADDR address, CORE_ADDR addr,
@@ -209,7 +244,8 @@
}
static void
-print_variable_at_address (struct type *type, const gdb_byte *valaddr,
+print_variable_at_address (struct type *type,
+ const gdb_byte *valaddr,
struct ui_file *stream, int format,
int deref_ref, int recurse,
enum val_prettyprint pretty)
@@ -235,6 +271,47 @@
fputs_filtered ("???", stream);
}
+
+/* m2_print_array_contents - prints out the contents of an
+ array up to a max_print values.
+ It prints arrays of char as a string
+ and all other data types as comma
+ separated values. */
+
+static void
+m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty,
+ int deref_ref, int recurse, int len)
+{
+ int eltlen;
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_LENGTH (type) > 0)
+ {
+ eltlen = TYPE_LENGTH (type);
+ if (prettyprint_arrays)
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ /* For an array of chars, print with string syntax. */
+ if (eltlen == 1 &&
+ ((TYPE_CODE (type) == TYPE_CODE_INT)
+ || ((current_language->la_language == language_m2)
+ && (TYPE_CODE (type) == TYPE_CODE_CHAR)))
+ && (format == 0 || format == 's'))
+ val_print_string (address, len+1, eltlen, stream);
+ else
+ {
+ fprintf_filtered (stream, "{");
+ val_print_array_elements (type, valaddr + embedded_offset,
+ address, stream, format,
+ deref_ref, recurse, pretty, 0);
+ fprintf_filtered (stream, "}");
+ }
+ }
+}
+
+
/* Print data of type TYPE located at VALADDR (within GDB), which came from
the inferior at address ADDRESS, onto stdio stream STREAM according to
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
@@ -366,6 +443,10 @@
if (m2_is_long_set (type))
m2_print_long_set (type, valaddr, embedded_offset, address,
stream, format, pretty);
+ else if (m2_is_unbounded_array (type))
+ m2_print_unbounded_array (type, valaddr, embedded_offset,
+ address, stream, format, deref_ref,
+ pretty, recurse);
else
cp_print_value_fields (type, type, valaddr, embedded_offset,
address, stream, format,
--- gdb-cvs/src/gdb/m2-typeprint.c 2007-06-29 01:35:08.000000000 +0100
+++ gdb-cvs-modified/src/gdb/m2-typeprint.c 2007-07-26 13:06:47.000000000 +0100
@@ -55,6 +55,8 @@
int show, int level);
static int m2_long_set (struct type *type, struct ui_file *stream,
int show, int level);
+static int m2_unbounded_array (struct type *type, struct ui_file *stream,
+ int show, int level);
static void m2_record_fields (struct type *type, struct ui_file *stream,
int show, int level);
static void m2_unknown (const char *s, struct type *type,
@@ -62,6 +64,7 @@
int m2_is_long_set (struct type *type);
int m2_is_long_set_of_type (struct type *type, struct type **of_type);
+int m2_is_unbounded_array (struct type *type);
void
@@ -90,7 +93,8 @@
break;
case TYPE_CODE_STRUCT:
- if (m2_long_set (type, stream, show, level))
+ if (m2_long_set (type, stream, show, level)
+ || m2_unbounded_array (type, stream, show, level))
break;
m2_record_fields (type, stream, show, level);
break;
@@ -152,9 +156,7 @@
}
}
-/*
- * m2_type_name - if a, type, has a name then print it.
- */
+/* m2_type_name - if a, type, has a name then print it. */
void
m2_type_name (struct type *type, struct ui_file *stream)
@@ -163,9 +165,7 @@
fputs_filtered (TYPE_NAME (type), stream);
}
-/*
- * m2_range - displays a Modula-2 subrange type.
- */
+/* m2_range - displays a Modula-2 subrange type. */
void
m2_range (struct type *type, struct ui_file *stream, int show,
@@ -197,9 +197,7 @@
m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
}
-/*
- * m2_array - prints out a Modula-2 ARRAY ... OF type
- */
+/* m2_array - prints out a Modula-2 ARRAY ... OF type. */
static void m2_array (struct type *type, struct ui_file *stream,
int show, int level)
@@ -326,9 +324,8 @@
if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
{
- /*
- * check if all fields of the RECORD are consecutive sets
- */
+ /* check if all fields of the RECORD are consecutive sets. */
+
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
{
@@ -350,12 +347,10 @@
return 0;
}
-/*
- * m2_get_discrete_bounds - a wrapper for get_discrete_bounds which
- * understands that CHARs might be signed.
- * This should be integrated into gdbtypes.c
- * inside get_discrete_bounds.
- */
+/* m2_get_discrete_bounds - a wrapper for get_discrete_bounds which
+ understands that CHARs might be signed.
+ This should be integrated into gdbtypes.c
+ inside get_discrete_bounds. */
int
m2_get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
@@ -379,11 +374,9 @@
}
}
-/*
- * m2_is_long_set_of_type - returns TRUE if the long set was declared as
- * SET OF <oftype> of_type is assigned to the
- * subtype.
- */
+/* m2_is_long_set_of_type - returns TRUE if the long set was declared as
+ SET OF <oftype> of_type is assigned to the
+ subtype. */
int
m2_is_long_set_of_type (struct type *type, struct type **of_type)
@@ -474,12 +467,60 @@
return 0;
}
+/* m2_is_unbounded_array - returns TRUE if, type, should be regarded
+ as a Modula-2 unbounded ARRAY type. */
+
+int
+m2_is_unbounded_array (struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ /*
+ * check if we have a structure with exactly two fields named
+ * _m2_contents and _m2_high. It also checks to see if the
+ * type of _m2_contents is a pointer. The TYPE_TARGET_TYPE
+ * of the pointer determines the unbounded ARRAY OF type.
+ */
+ if (TYPE_NFIELDS (type) != 2)
+ return 0;
+ if (strcmp (TYPE_FIELD_NAME (type, 0), "_m2_contents") != 0)
+ return 0;
+ if (strcmp (TYPE_FIELD_NAME (type, 1), "_m2_high") != 0)
+ return 0;
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) != TYPE_CODE_PTR)
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+/* m2_unbounded_array - if the struct type matches a Modula-2 unbounded
+ parameter type then display the type as an
+ ARRAY OF type. Returns TRUE if an unbounded
+ array type was detected. */
+
+static int
+m2_unbounded_array (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ if (m2_is_unbounded_array (type))
+ {
+ if (show > 0)
+ {
+ fputs_filtered ("ARRAY OF ", stream);
+ m2_print_type (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)),
+ "", stream, 0, level);
+ }
+ return 1;
+ }
+ return 0;
+}
+
void
m2_record_fields (struct type *type, struct ui_file *stream, int show,
int level)
{
- /* Print the tag if it exists.
- */
+ /* Print the tag if it exists. */
if (TYPE_TAG_NAME (type) != NULL)
{
if (strncmp (TYPE_TAG_NAME (type), "$$", 2) != 0)
--- gdb-cvs/src/gdb/m2-lang.h 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-lang.h 2007-07-25 18:33:42.000000000 +0100
@@ -28,6 +28,7 @@
int);
extern int m2_is_long_set (struct type *type);
+extern int m2_is_unbounded_array (struct type *type);
extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int, int, int,
--- gdb-cvs/src/gdb/m2-lang.c 2007-06-16 21:10:51.000000000 +0100
+++ gdb-cvs-modified/src/gdb/m2-lang.c 2007-07-26 12:59:24.000000000 +0100
@@ -39,8 +39,7 @@
string whose delimiter is QUOTER. Note that that format for printing
characters and strings is language specific.
FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version.
- */
+ be replaced with a true Modula version. */
static void
m2_emit_char (int c, struct ui_file *stream, int quoter)
@@ -89,7 +88,7 @@
}
/* FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version. */
+ be replaced with a true Modula version. */
static void
m2_printchar (int c, struct ui_file *stream)
@@ -104,7 +103,7 @@
are printed as appropriate. Print ellipses at the end if we
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version. */
+ be replaced with a true Modula version. */
static void
m2_printstr (struct ui_file *stream, const gdb_byte *string,
@@ -189,9 +188,100 @@
fputs_filtered ("...", stream);
}
+static struct value *
+evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
+ int *pos, enum noside noside)
+{
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ struct value *arg1;
+ struct value *arg2;
+ struct type *type;
+ switch (op)
+ {
+ case UNOP_HIGH:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else
+ {
+ arg1 = coerce_ref (arg1);
+ type = check_typedef (value_type (arg1));
+
+ if (m2_is_unbounded_array (type))
+ {
+ struct value *temp = arg1;
+ type = TYPE_FIELD_TYPE (type, 1);
+ /* i18n: Do not translate the "_m2_high" part! */
+ arg1 = value_struct_elt (&temp, NULL, "_m2_high", NULL,
+ _("unbounded structure "
+ "missing _m2_high field"));
+
+ if (value_type (arg1) != type)
+ arg1 = value_cast (type, arg1);
+ }
+ }
+ return 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);
+ type = check_typedef (value_type (arg1));
+
+ if (m2_is_unbounded_array (type))
+ {
+ struct value *temp = arg1;
+ type = TYPE_FIELD_TYPE (type, 0);
+ if (type == NULL || (TYPE_CODE (type) != 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 (value_type (arg1) != type)
+ arg1 = value_cast (type, arg1);
+
+ type = check_typedef (value_type (arg1));
+ return value_ind (value_add (arg1, arg2));
+ }
+ else
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ {
+ if (TYPE_NAME (type))
+ error (_("cannot subscript something of type `%s'"),
+ TYPE_NAME (type));
+ 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, arg2);
+
+ default:
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+ }
+
+ nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
/* FIXME: This is a copy of c_create_fundamental_type(), before
all the non-C types were stripped from it. Needs to be fixed
- by an experienced Modula programmer. */
+ by an experienced Modula programmer. */
static struct type *
m2_create_fundamental_type (struct objfile *objfile, int typeid)
@@ -204,7 +294,7 @@
/* FIXME: For now, if we are asked to produce a type not in this
language, create the equivalent of a C integer type with the
name "<?type?>". When all the dust settles from the type
- reconstruction work, this should probably become an error. */
+ reconstruction work, this should probably become an error. */
type = init_type (TYPE_CODE_INT,
gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
0, "<?type?>", objfile);
@@ -428,6 +518,15 @@
= builtin->builtin_bool;
}
+const struct exp_descriptor exp_descriptor_modula2 =
+{
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_modula2
+};
+
const struct language_defn m2_language_defn =
{
"modula-2",
@@ -437,7 +536,7 @@
type_check_on,
case_sensitive_on,
array_row_major,
- &exp_descriptor_standard,
+ &exp_descriptor_modula2,
m2_parse, /* parser */
m2_error, /* parser error function */
null_post_parser,
--- gdb-cvs/src/gdb/m2-exp.y 2007-01-09 17:58:51.000000000 +0000
+++ gdb-cvs-modified/src/gdb/m2-exp.y 2007-07-25 21:16:14.000000000 +0100
@@ -174,6 +174,7 @@
%token <sval> TYPENAME
%token SIZE CAP ORD HIGH ABS MIN_FUNC MAX_FUNC FLOAT_FUNC VAL CHR ODD TRUNC
+%token TSIZE
%token INC DEC INCL EXCL
/* The GDB scope operator */
@@ -288,6 +289,10 @@
{ write_exp_elt_opcode (UNOP_TRUNC); }
;
+exp : TSIZE '(' exp ')'
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
+ ;
+
exp : SIZE exp %prec UNARY
{ write_exp_elt_opcode (UNOP_SIZEOF); }
;
@@ -353,6 +358,10 @@
write_exp_elt_opcode (MULTI_SUBSCRIPT); }
;
+exp : exp '[' exp ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ ;
+
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
@@ -809,6 +818,7 @@
{"SIZE", SIZE },
{"FLOAT", FLOAT_FUNC },
{"TRUNC", TRUNC },
+ {"TSIZE", SIZE },
};
--- gdb-cvs/src/gdb/testsuite/configure.ac 2007-01-23 17:11:55.000000000 +0000
+++ gdb-cvs-modified/src/gdb/testsuite/configure.ac 2007-07-26 14:25:33.000000000 +0100
@@ -114,7 +114,7 @@
gdb.ada/Makefile \
gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile \
gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile \
- gdb.fortran/Makefile gdb.server/Makefile \
+ gdb.fortran/Makefile gdb.modula2/Makefile gdb.server/Makefile \
gdb.java/Makefile gdb.mi/Makefile \
gdb.objc/Makefile gdb.threads/Makefile gdb.trace/Makefile \
gdb.xml/Makefile])
and here are the new Modula-2 dejagnu files:
[-- Attachment #2: Modula-2 GDB dejagnu tests --]
[-- Type: application/octet-stream, Size: 1853 bytes --]
[-- Attachment #3: Type: text/plain, Size: 16 bytes --]
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-26 22:58 ` Pierre Muller
@ 2007-07-27 13:17 ` Gaius Mulley
2007-07-27 13:28 ` Pierre Muller
2007-07-28 0:59 ` Jim Blandy
1 sibling, 1 reply; 18+ messages in thread
From: Gaius Mulley @ 2007-07-27 13:17 UTC (permalink / raw)
To: Pierre Muller; +Cc: gdb-patches
Hi Pierre,
"Pierre Muller" <muller@ics.u-strasbg.fr> writes:
> Could you explain why you need to add
> TSIZE as a synonym of SIZE?
> Is it just a matter of parser shift/reduce conflicts?
> Is TSIZE a modula-2 function?
yes a Modula-2 function in PIM-2 it was later replaced by SIZE
in PIM-4. But GNU Modula-2 supports, PIM-[234] and users might
expect TSIZE to exist in the debugger.
> Is your change in gdb.texinfo in a modula-2 specific
> area?
yes - in the Modula-2 example session.
> Modula-2 is not the only language supporting unbounded arrays, I
> would be interested in using the same kind of code for pascal
> language support.
sure, I'm all for refactoring code..
> Maybe a more general approach would be useful?
maybe - although I suspect the devil is in the detail. Basically
Modula-2 assumes that all unbounded arrays start at index 0 and the
caller can be legally access all indices 0..HIGH(a). GNU Modula-2
implements unbounded arrays by creating a structure whose first field
is a pointer to type, and the second structure is the HIGH value
(unsigned int). So the patches basically detect if the array
declaration matches a GNU Modula-2 unbounded structure (testing field
names and types and language). If so then it maps any reference to
a[i] onto a->_m2_contents[i] and HIGH(a) onto a->_m2_high. How does
GNU Pascal implement unbounded arrays?
> One more remark: in m2_unbounded_array function, it would probably
> be better to honor the value of the show argument, and to only
> output something if show is non-zero.
many thanks for the spotting this - it is now implemented this in the
latest patch.
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-27 13:17 ` Gaius Mulley
@ 2007-07-27 13:28 ` Pierre Muller
0 siblings, 0 replies; 18+ messages in thread
From: Pierre Muller @ 2007-07-27 13:28 UTC (permalink / raw)
To: 'Gaius Mulley'; +Cc: gdb-patches, gpc
> > Modula-2 is not the only language supporting unbounded arrays, I
> > would be interested in using the same kind of code for pascal
> > language support.
>
> sure, I'm all for refactoring code..
>
> > Maybe a more general approach would be useful?
>
> maybe - although I suspect the devil is in the detail. Basically
> Modula-2 assumes that all unbounded arrays start at index 0 and the
> caller can be legally access all indices 0..HIGH(a). GNU Modula-2
> implements unbounded arrays by creating a structure whose first field
> is a pointer to type, and the second structure is the HIGH value
> (unsigned int). So the patches basically detect if the array
> declaration matches a GNU Modula-2 unbounded structure (testing field
> names and types and language). If so then it maps any reference to
> a[i] onto a->_m2_contents[i] and HIGH(a) onto a->_m2_high. How does
> GNU Pascal implement unbounded arrays?
This is basically also the case for parameter unbounded arrays:
the valid indexes are from 0 to high(a) and high(a)
is passed as an additional hidden parameter,
called
highA (high in lower case followed by the uppercase name of the parameter)
for free pascal
and
open_array_length_0 (or _x for the X+1 open array parameter) for GNU
pascal.
The open array type can be recongnized by the fact that the
lower bound is 0, while the higher bound is -1.
Free pascal now also supports global open array variables
which are allocated by using SetLength function. They are
basically hidden pointers.
The high values is at offset -4 (or size of pointer more generally) relative
to
the pointer address. I don't know if GPC supports this
syntax. Maybe someone from GPC team can answer this question.
Pierre Muller
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-27 12:26 ` Gaius Mulley
@ 2007-07-27 20:22 ` Eli Zaretskii
2007-07-30 8:29 ` Gaius Mulley
0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2007-07-27 20:22 UTC (permalink / raw)
To: Gaius Mulley; +Cc: deuling, gdb-patches
> From: Gaius Mulley <gaius@glam.ac.uk>
> Cc: gdb-patches@sources.redhat.com
> Date: Fri, 27 Jul 2007 13:08:31 +0100
>
> 2004-07-26 Gaius Mulley <gaius@glam.ac.uk>
>
> * doc/gdb.texinfo: Add TSIZE definition, removed
> statement about unbounded arrays being unimplemented.
The patch for gdb.texinfo is okay with me.
Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-26 22:58 ` Pierre Muller
2007-07-27 13:17 ` Gaius Mulley
@ 2007-07-28 0:59 ` Jim Blandy
2007-07-30 6:29 ` Gaius Mulley
1 sibling, 1 reply; 18+ messages in thread
From: Jim Blandy @ 2007-07-28 0:59 UTC (permalink / raw)
To: Pierre Muller; +Cc: 'Gaius Mulley', gdb-patches
"Pierre Muller" <muller@ics.u-strasbg.fr> writes:
> Modula-2 is not the only language supporting unbounded
> arrays, I would be interested in using the same kind of code for
> pascal language support.
In C, there are ABI documents that specify how each type is
represented in memory for a given processor, the goal being to specify
things enough that one can link code from different vendor's compilers
together when they implement the same ABI. It sounds like the 'PIM'
documents are the equivalent for Modula-2; is that right? Are there
equivalent documents for Pascal?
I'm not sure it actually would be a good idea to unify Pascal and
Modula-2 code if they are meant to follow different specifications.
Bugs in that common code might have the same fix for both languages,
or they might not. People would hesitate to fix things, for fear of
breaking the other language they're not familiar with.
I don't think we should require Gaius's patch to unify the
Pascal/Modula-2 support.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-28 0:59 ` Jim Blandy
@ 2007-07-30 6:29 ` Gaius Mulley
0 siblings, 0 replies; 18+ messages in thread
From: Gaius Mulley @ 2007-07-30 6:29 UTC (permalink / raw)
To: Jim Blandy; +Cc: Pierre Muller, gdb-patches
Jim Blandy <jimb@codesourcery.com> writes:
> "Pierre Muller" <muller@ics.u-strasbg.fr> writes:
>> Modula-2 is not the only language supporting unbounded
>> arrays, I would be interested in using the same kind of code for
>> pascal language support.
>
> In C, there are ABI documents that specify how each type is
> represented in memory for a given processor, the goal being to specify
> things enough that one can link code from different vendor's compilers
> together when they implement the same ABI. It sounds like the 'PIM'
> documents are the equivalent for Modula-2; is that right?
Hi Jim,
ah alas, the PIM (Programming in Modula-2 books by N. Wirth) ed2, ed3
and ed4 don't say how unbounded arrays should be implemented or
anything about parameter ordering etc - they really concentrate on the
semantics of the language itself and to a lesser extent the libraries.
The ISO standard doesn't say much about unbounded array implementation
either - although it does tidy up many other loose ends.
> Are there equivalent documents for Pascal?
>
> I'm not sure it actually would be a good idea to unify Pascal and
> Modula-2 code if they are meant to follow different specifications.
> Bugs in that common code might have the same fix for both languages,
> or they might not. People would hesitate to fix things, for fear of
> breaking the other language they're not familiar with.
>
> I don't think we should require Gaius's patch to unify the
> Pascal/Modula-2 support.
I agree :-) the amount of shared code would be fairly small anyhow and
many blocks would have to be predicated by testing whether we were in
Modula-2 language mode or Pascal language mode. At which point it
begs the question whether these sections of code would be better
separately placed into m2-valprint.c, p-valprint.c, m2-typeprint.c and
p-typeprint.c etc.
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-27 20:22 ` Eli Zaretskii
@ 2007-07-30 8:29 ` Gaius Mulley
2007-07-30 23:34 ` Jim Blandy
2007-07-31 3:01 ` Jim Blandy
0 siblings, 2 replies; 18+ messages in thread
From: Gaius Mulley @ 2007-07-30 8:29 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: deuling, gdb-patches
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Gaius Mulley <gaius@glam.ac.uk>
>> Cc: gdb-patches@sources.redhat.com
>> Date: Fri, 27 Jul 2007 13:08:31 +0100
>>
>> 2004-07-26 Gaius Mulley <gaius@glam.ac.uk>
>>
>> * doc/gdb.texinfo: Add TSIZE definition, removed
>> statement about unbounded arrays being unimplemented.
>
> The patch for gdb.texinfo is okay with me.
>
> Thanks.
thanks Eli,
will check it in when I get approval for the code..
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-30 8:29 ` Gaius Mulley
@ 2007-07-30 23:34 ` Jim Blandy
2007-07-31 3:01 ` Jim Blandy
1 sibling, 0 replies; 18+ messages in thread
From: Jim Blandy @ 2007-07-30 23:34 UTC (permalink / raw)
To: Gaius Mulley; +Cc: Eli Zaretskii, deuling, gdb-patches
Gaius Mulley <gaius@glam.ac.uk> writes:
> Eli Zaretskii <eliz@gnu.org> writes:
>
>>> From: Gaius Mulley <gaius@glam.ac.uk>
>>> Cc: gdb-patches@sources.redhat.com
>>> Date: Fri, 27 Jul 2007 13:08:31 +0100
>>>
>>> 2004-07-26 Gaius Mulley <gaius@glam.ac.uk>
>>>
>>> * doc/gdb.texinfo: Add TSIZE definition, removed
>>> statement about unbounded arrays being unimplemented.
>>
>> The patch for gdb.texinfo is okay with me.
>>
>> Thanks.
>
> thanks Eli,
>
> will check it in when I get approval for the code..
Technically, you don't need approval for the code, since all the
changes fall within Modula-2 files, and you're an Authorized Committer
for Modula-2 support.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-30 8:29 ` Gaius Mulley
2007-07-30 23:34 ` Jim Blandy
@ 2007-07-31 3:01 ` Jim Blandy
2007-07-31 16:47 ` Gaius Mulley
1 sibling, 1 reply; 18+ messages in thread
From: Jim Blandy @ 2007-07-31 3:01 UTC (permalink / raw)
To: Gaius Mulley; +Cc: Eli Zaretskii, deuling, gdb-patches
I'd like to see the tests go in, too. I'm not sure the approach they
take is one we'd like to follow in future code, though.
I'm inferring from the test and from the Modula-2 code in GDB that
the debugging information GCC emits for unbounded arrays claims that
they're a structure of the form:
struct {
char *_m2_contents;
int _m2_high;
};
Then, GDB's Modula-2 code recognizes this structure as a special case,
and treats it as an array.
It seems to me the tests should go ahead and require a Modula-2
compiler, compile a real Modula-2 program, and exit with 'unsupported'
if there's no Modula-2 compiler present.
It's a shame that the debugging info doesn't actually treat these
Modula-2 arrays as arrays. The 'proper' DWARF representation would be
a DW_TAG_array_type die with a DW_TAG_subrange_type for the variable
index whose a DW_AT_upper_bound attribute is some DWARF expression
like:
DW_OP_push_object_address DW_OP_lit4 DW_OP_plus DW_OP_deref
to compute the upper bound of the array.
Then GDB would need to learn to understand these things. In a
quick-and-dirty implementation, the DWARF reader would turn the DWARF
above into arrays whose index subrange types used a new
BOUND_BY_DESCRIPTOR value for 'enum array_bound_type', ignoring the
DWARF expression. Then language-specific code would have to handle
those as a special case.
The best implementation would be to have a new BOUND_COMPUTED style of
bound, and have the 'loc' union in 'struct field' point to a structure
like this:
struct computed_bound {
/* Return the value of a computed bound. V is the array value whose
bound we're computing; CB is a pointer to this structure. */
LONGEST (*compute_bound (struct computed_bound *cb, struct value *v));
/* Data to be used by the COMPUTE_BOUND function. */
void *data;
};
The DWARF reader would create these when it sees arrays with upper
bounds that are expressions, making DATA point to the expression and
COMPUTE_BOUND point to a function that uses dwarf2expr.h to evaluate
the expression.
Then the generic GDB array code could handle Modula-2 variable arrays
(or anything else that the DWARF described accurately).
This isn't exactly a one-weekend project, though.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-31 3:01 ` Jim Blandy
@ 2007-07-31 16:47 ` Gaius Mulley
2007-07-31 16:48 ` Jim Blandy
2007-07-31 19:18 ` Jim Blandy
0 siblings, 2 replies; 18+ messages in thread
From: Gaius Mulley @ 2007-07-31 16:47 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eli Zaretskii, deuling, gdb-patches
Jim Blandy <jimb@codesourcery.com> writes:
> I'd like to see the tests go in, too. I'm not sure the approach they
> take is one we'd like to follow in future code, though.
>
> I'm inferring from the test and from the Modula-2 code in GDB that
> the debugging information GCC emits for unbounded arrays claims that
> they're a structure of the form:
>
> struct {
> char *_m2_contents;
> int _m2_high;
> };
>
> Then, GDB's Modula-2 code recognizes this structure as a special case,
> and treats it as an array.
>
> It seems to me the tests should go ahead and require a Modula-2
> compiler, compile a real Modula-2 program, and exit with 'unsupported'
> if there's no Modula-2 compiler present.
>
> It's a shame that the debugging info doesn't actually treat these
> Modula-2 arrays as arrays. The 'proper' DWARF representation would be
> a DW_TAG_array_type die with a DW_TAG_subrange_type for the variable
> index whose a DW_AT_upper_bound attribute is some DWARF expression
> like:
>
> DW_OP_push_object_address DW_OP_lit4 DW_OP_plus DW_OP_deref
>
> to compute the upper bound of the array.
>
> Then GDB would need to learn to understand these things. In a
> quick-and-dirty implementation, the DWARF reader would turn the DWARF
> above into arrays whose index subrange types used a new
> BOUND_BY_DESCRIPTOR value for 'enum array_bound_type', ignoring the
> DWARF expression. Then language-specific code would have to handle
> those as a special case.
>
> The best implementation would be to have a new BOUND_COMPUTED style of
> bound, and have the 'loc' union in 'struct field' point to a structure
> like this:
>
> struct computed_bound {
> /* Return the value of a computed bound. V is the array value whose
> bound we're computing; CB is a pointer to this structure. */
> LONGEST (*compute_bound (struct computed_bound *cb, struct value *v));
>
> /* Data to be used by the COMPUTE_BOUND function. */
> void *data;
> };
>
> The DWARF reader would create these when it sees arrays with upper
> bounds that are expressions, making DATA point to the expression and
> COMPUTE_BOUND point to a function that uses dwarf2expr.h to evaluate
> the expression.
>
> Then the generic GDB array code could handle Modula-2 variable arrays
> (or anything else that the DWARF described accurately).
>
> This isn't exactly a one-weekend project, though.
Hi Jim,
thank you for the various pointers (re: dwarf2 opcodes, subranges and
unbounded arrays - I also note your --fixme-- in the dwarf2read code)
- I wonder whether it might be better to hold off applying the patch
and attempt to solve the problem properly using the COMPUTE_BOUND
method explained above. I'm willing to attempt this - its always more
satisfying solving a problem correctly :-) and in theory this method
might be useful for Pascal as well. It should also mean ISO M2
multidimensional unbounded arrays will be easier to implement.
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-31 16:47 ` Gaius Mulley
@ 2007-07-31 16:48 ` Jim Blandy
2007-08-01 14:01 ` Gaius Mulley
2007-07-31 19:18 ` Jim Blandy
1 sibling, 1 reply; 18+ messages in thread
From: Jim Blandy @ 2007-07-31 16:48 UTC (permalink / raw)
To: Gaius Mulley; +Cc: Eli Zaretskii, deuling, gdb-patches
Gaius Mulley <gaius@glam.ac.uk> writes:
> thank you for the various pointers (re: dwarf2 opcodes, subranges and
> unbounded arrays - I also note your --fixme-- in the dwarf2read code)
> - I wonder whether it might be better to hold off applying the patch
> and attempt to solve the problem properly using the COMPUTE_BOUND
> method explained above. I'm willing to attempt this - its always more
> satisfying solving a problem correctly :-) and in theory this method
> might be useful for Pascal as well. It should also mean ISO M2
> multidimensional unbounded arrays will be easier to implement.
Wonderful! I admire your readiness to take this on; I'll be happy to
help as much as I can. Yes, I think this would work for Pascal as
well.
I don't know how much work this is, but if there were some way you
could get GNU Modula-2 into Fedora Core or Fedora Extras, I think that
might increase your audience a bit. These days, if I can't install
something by typing 'sudo yum install foo', I move on to something
else.
(By the way, what's entailed in getting GNU Modula-2 into the main GCC
sources?)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-31 16:47 ` Gaius Mulley
2007-07-31 16:48 ` Jim Blandy
@ 2007-07-31 19:18 ` Jim Blandy
2007-10-16 16:59 ` Gaius Mulley
1 sibling, 1 reply; 18+ messages in thread
From: Jim Blandy @ 2007-07-31 19:18 UTC (permalink / raw)
To: Gaius Mulley; +Cc: Eli Zaretskii, deuling, gdb-patches
Gaius Mulley <gaius@glam.ac.uk> writes:
> - I wonder whether it might be better to hold off applying the patch
> and attempt to solve the problem properly using the COMPUTE_BOUND
> method explained above.
You're the Modula-2 maintainer, so it's your call, but for what it's
worth, if you think the full DWARF implementation --- both the GCC and
GDB sides --- will take more than a few weeks, and if these unbounded
arrays are a reasonably widely used language construct, I'd counsel
you to go ahead and commit the current patch. The work is already
done; there's no reason to make the perfect the enemy of the good.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-31 16:48 ` Jim Blandy
@ 2007-08-01 14:01 ` Gaius Mulley
0 siblings, 0 replies; 18+ messages in thread
From: Gaius Mulley @ 2007-08-01 14:01 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eli Zaretskii, deuling, gdb-patches
Jim Blandy <jimb@codesourcery.com> writes:
> I don't know how much work this is, but if there were some way you
> could get GNU Modula-2 into Fedora Core or Fedora Extras, I think that
> might increase your audience a bit. These days, if I can't install
> something by typing 'sudo yum install foo', I move on to something
> else.
yes true, I'm currently (when I'm near a fast machine) trying to build
GNU Modula-2 as a cross compiler for the avr as a Debian package.
Debian's package build mechanism is pretty awesome - but it eats dual
core, sata II machines for breakfast.. I've recently looked at the
Debian host GCC package - and I'm aiming to release gm2 grafted onto a
gcc-4.1.2. Although it will probably be a much simplified package
build as opposed to the GCC Debian package - just to reduce time to
market etc. I'm hoping Debian's 'alien' package should turn it into a
RPM successfully.
> (By the way, what's entailed in getting GNU Modula-2 into the main GCC
> sources?)
truthfully I'm not sure of the exact procedure to get it into the
main GCC trunk. However I know that I can place gm2 into the GCC svn
tree as a branch and then attempt to keep pack-porting the new patches
from the trunk to the gm2 branch. I suppose if enough people found it
useful and interesting maybe it would make it into the main truck..
Also I suspect that as patches get submitted to GCC for support for
various gm2 features (unbounded arrays, set types) this might provide
a little leverage to integrate the two.
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-07-31 19:18 ` Jim Blandy
@ 2007-10-16 16:59 ` Gaius Mulley
2007-10-16 22:04 ` Jim Blandy
0 siblings, 1 reply; 18+ messages in thread
From: Gaius Mulley @ 2007-10-16 16:59 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eli Zaretskii, deuling, gdb-patches
Jim Blandy <jimb@codesourcery.com> writes:
> Gaius Mulley <gaius@glam.ac.uk> writes:
> > - I wonder whether it might be better to hold off applying the patch
> > and attempt to solve the problem properly using the COMPUTE_BOUND
> > method explained above.
>
> You're the Modula-2 maintainer, so it's your call, but for what it's
> worth, if you think the full DWARF implementation --- both the GCC and
> GDB sides --- will take more than a few weeks, and if these unbounded
> arrays are a reasonably widely used language construct, I'd counsel
> you to go ahead and commit the current patch. The work is already
> done; there's no reason to make the perfect the enemy of the good.
Hi Jim,
Just a small note to say that I'm going to follow your advice and
commit these original patches (and test codes) before too much time
elapses. I've re-tested the code on the current CVS snapshot and it
doesn't cause any extra regression failures. I guess I'd just like to
flag this as about to happen..
regards,
Gaius
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] Unbounded array support implemented (for Modula-2)
2007-10-16 16:59 ` Gaius Mulley
@ 2007-10-16 22:04 ` Jim Blandy
0 siblings, 0 replies; 18+ messages in thread
From: Jim Blandy @ 2007-10-16 22:04 UTC (permalink / raw)
To: Gaius Mulley; +Cc: Eli Zaretskii, deuling, gdb-patches
Gaius Mulley <gaius at glam.ac.uk> writes:
> Jim Blandy <jimb@codesourcery.com> writes:
>
>> Gaius Mulley <gaius@glam.ac.uk> writes:
>> > - I wonder whether it might be better to hold off applying the patch
>> > and attempt to solve the problem properly using the COMPUTE_BOUND
>> > method explained above.
>>
>> You're the Modula-2 maintainer, so it's your call, but for what it's
>> worth, if you think the full DWARF implementation --- both the GCC and
>> GDB sides --- will take more than a few weeks, and if these unbounded
>> arrays are a reasonably widely used language construct, I'd counsel
>> you to go ahead and commit the current patch. The work is already
>> done; there's no reason to make the perfect the enemy of the good.
>
> Hi Jim,
>
> Just a small note to say that I'm going to follow your advice and
> commit these original patches (and test codes) before too much time
> elapses. I've re-tested the code on the current CVS snapshot and it
> doesn't cause any extra regression failures. I guess I'd just like to
> flag this as about to happen..
Sounds great.
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2007-10-16 20:29 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-26 7:07 [PATCH] Unbounded array support implemented (for Modula-2) Gaius Mulley
2007-07-26 7:36 ` Markus Deuling
2007-07-27 12:26 ` Gaius Mulley
2007-07-27 20:22 ` Eli Zaretskii
2007-07-30 8:29 ` Gaius Mulley
2007-07-30 23:34 ` Jim Blandy
2007-07-31 3:01 ` Jim Blandy
2007-07-31 16:47 ` Gaius Mulley
2007-07-31 16:48 ` Jim Blandy
2007-08-01 14:01 ` Gaius Mulley
2007-07-31 19:18 ` Jim Blandy
2007-10-16 16:59 ` Gaius Mulley
2007-10-16 22:04 ` Jim Blandy
2007-07-26 22:58 ` Pierre Muller
2007-07-27 13:17 ` Gaius Mulley
2007-07-27 13:28 ` Pierre Muller
2007-07-28 0:59 ` Jim Blandy
2007-07-30 6:29 ` Gaius Mulley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox