Re: pr 11067 patch

Jan Kratochvil
2010-02-19T18:50:40Z

On Fri, 19 Feb 2010 15:53:45 +0100, Chris Moller wrote:
> The problem is that I don't know any way to change the enum
> formatting for CLI but leave it alone for MI-.
...
> some way to distinguish between running under CLI vs. MI if that's the right
> thing to do.

After I wrote the patch below according to Tom Tromey the Python pretty
printing applies even to the MI protocol values, therefore IMO it should also
apply to this new enum printing which is also some form of pretty printing.

Therefore my MI / CLI suggestion has been already rejected by the Python
pretty printing precedence and the patch below should be dropped.

Thanks,
Jan

ChangeLogged only changes to the patch:

gdb/
* c-valprint.c (c_val_print) <TYPE_CODE_ENUM>: Add conditional
!ENUM_NUMERIC_PRINT.
* mi/mi-main.c (mi_cmd_data_evaluate_expression): Clear
ENUM_NUMERIC_PRINT.
* valprint.c (user_print_options) <enum_numeric_print>: New.
(get_raw_print_options): Clear ENUM_NUMERIC_PRINT.
(show_enum_numeric_print): New.
(_initialize_valprint): Call add_setshow_boolean_cmd for
"enum-numeric-print"..
* valprint.h (struct value_print_options) <enum_numeric_print>: New.
* varobj.c (value_get_print_value): Clear OPTS.ENUM_NUMERIC_PRINT.

Gdb/testsuite/
* gdb.mi/basics.c (E): New.
* gdb.mi/mi2-eval.exp (eval E): New.

--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -412,9 +412,30 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
}
}
if (i < len)
- {
+ /*
+ When printing a simple enum value, the following code includes, in
+ addition to the symbolic value, the numeric value and the enum tag.
+ Under other-than-simple circumstances--in structs, arrays, etc.--
+ it does what's always done and prints just the symbolic value.
+ */
+ if (!options->enum_numeric_print || options->summary || recurse != 0)
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
- }
+ else
+ {
+ char *enum_name;
+
+ if (TYPE_NAME (type))
+ enum_name = TYPE_NAME (type);
+ else if (TYPE_TAG_NAME(type))
+ enum_name = TYPE_TAG_NAME(type);
+ else
+ enum_name = "<anonymous>";
+
+ fprintf_filtered (stream, "%s = (enum %s)%s",
+ TYPE_FIELD_NAME (type, i),
+ enum_name,
+ plongest (val));
+ }
else
{
print_longest (stream, 'd', 0, val);
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1122,6 +1122,7 @@ mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
/* Print the result of the expression evaluation. */
get_user_print_options (&opts);
opts.deref_ref = 0;
+ opts.enum_numeric_print = 0;
val_print (value_type (val), value_contents (val),
value_embedded_offset (val), value_address (val),
stb->stream, 0, &opts, current_language);
--- a/gdb/testsuite/gdb.base/Makefile.in
+++ b/gdb/testsuite/gdb.base/Makefile.in
@@ -12,7 +12,8 @@ EXECUTABLES = all-types annota1 bitfields break \
scope section_command setshow setvar shmain sigall signals \
solib solib_sl so-impl-ld so-indr-cl \
step-line step-test structs structs2 \
- twice-tmp varargs vforked-prog watchpoint whatis catch-syscall
+ twice-tmp varargs vforked-prog watchpoint whatis catch-syscall \
+ pr11067

MISCELLANEOUS = coremmap.data ../foobar.baz \
shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pr11067.c
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+enum E {
+ Val1 = 56,
+ Val2
+};
+
+struct Es {
+ int v;
+ enum E e;
+};
+
+enum E e = Val1;
+
+enum E ea[] = { Val1, Val2, Val1 };
+
+struct Es es = { 5, Val2 };
+
+int main() {
+ /*
+ The following is a fake-out for linkers (such as, apparently, the AIX
+ linker) that optimises out unreference variables.
+ */
+
+ e = Val2;
+
+ ea[0] = Val2;
+
+ es.v = 99;
+
+ return 0;
+}
+
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pr11067.exp
@@ -0,0 +1,31 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile "pr11067"
+set srcfile ${testfile}.c
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_test "print e" "Val1 = \\(enum E\\)56"
+
+gdb_test "print ea" "{Val1, Val2, Val1}"
+
+gdb_test "print es" "v = 5, e = Val2}"
--- a/gdb/testsuite/gdb.base/setvar.exp
+++ b/gdb/testsuite/gdb.base/setvar.exp
@@ -399,18 +399,22 @@ set timeout $prev_timeout
# GNU C supports them, some other compilers don't.

if {$gcc_compiled} then {
- gdb_test "print sef.field=sm1" ".*.\[0-9\]* = sm1"
- gdb_test "print sef.field" ".*.\[0-9\]* = sm1" "print sef.field (sm1)"
- gdb_test "print sef.field=s1" ".*.\[0-9\]* = s1"
- gdb_test "print sef.field" ".*.\[0-9\]* = s1" "print sef.field (s1)"
- gdb_test "print uef.field=u2" ".*.\[0-9\]* = u2"
- gdb_test "print uef.field" ".*.\[0-9\]* = u2" "print uef.field (u2)"
- gdb_test "print uef.field=u1" ".*.\[0-9\]* = u1"
- gdb_test "print uef.field" ".*.\[0-9\]* = u1" "print uef.field (u1)"
+ gdb_test "print sef.field=sm1" ".*.\[0-9\]* = sm1 = \\(enum senum\\)-1"
+ gdb_test "print sef.field" ".*.\[0-9\]* = sm1 = \\(enum senum\\)-1" \
+ "print sef.field (sm1)"
+ gdb_test "print sef.field=s1" ".*.\[0-9\]* = s1 = \\(enum senum\\)1"
+ gdb_test "print sef.field" ".*.\[0-9\]* = s1 = \\(enum senum\\)1" \
+ "print sef.field (s1)"
+ gdb_test "print uef.field=u2" ".*.\[0-9\]* = u2 = \\(enum uenum\\)2"
+ gdb_test "print uef.field" ".*.\[0-9\]* = u2 = \\(enum uenum\\)2" \
+ "print uef.field (u2)"
+ gdb_test "print uef.field=u1" ".*.\[0-9\]* = u1 = \\(enum uenum\\)1"
+ gdb_test "print uef.field" ".*.\[0-9\]* = u1 = \\(enum uenum\\)1" \
+ "print uef.field (u1)"

# Test for truncation when assigning invalid values to bitfields.
gdb_test "print sef.field=7" \
- ".*warning: Value does not fit in 2 bits.*\[0-9\]* = sm1"
+ ".*warning: Value does not fit in 2 bits.*\[0-9\]* = sm1 = \\(enum senum\\)-1"
gdb_test "print uef.field=6" \
- ".*warning: Value does not fit in 2 bits.*\[0-9\]* = u2"
+ ".*warning: Value does not fit in 2 bits.*\[0-9\]* = u2 = \\(enum uenum\\)2"
}
--- a/gdb/testsuite/gdb.cp/classes.exp
+++ b/gdb/testsuite/gdb.cp/classes.exp
@@ -413,7 +413,7 @@ proc test_enums {} {

# print the enum member

- gdb_test "print obj_with_enum.priv_enum" "\\$\[0-9\]+ = (ClassWithEnum::)?green"
+ gdb_test "print obj_with_enum.priv_enum" "\\$\[0-9\]+ = (ClassWithEnum::)?green = \\(enum ClassWithEnum::PrivEnum\\)1"

# ptype on the enum member

@@ -482,7 +482,7 @@ proc test_enums {} {
}

gdb_test_multiple "print ('ClassWithEnum::PrivEnum') 42" "print ('ClassWithEnum::PrivEnum') 42" {
- -re "\\$\[0-9\]+ = (ClassWithEnum::)?yellow$nl$gdb_prompt $" {
+ -re "\\$\[0-9\]+ = (ClassWithEnum::)?yellow = \\(enum ClassWithEnum::PrivEnum\\)42$nl$gdb_prompt $" {
# gcc 3.3.2 -gstabs+
# gcc HEAD 2003-12-28 21:08:30 UTC -gstabs+
pass "print ('ClassWithEnum::PrivEnum') 42"
--- a/gdb/testsuite/gdb.cp/m-data.exp
+++ b/gdb/testsuite/gdb.cp/m-data.exp
@@ -71,7 +71,7 @@ gdb_test "print test1.key1" "\\$\[0-9\]* = 5" "simple object, const int"
gdb_test "print test1.key2" "\\$\[0-9\]* = 4589" "simple object, long"

# simple object, enum
-gdb_test "print test1.value" "\\$\[0-9\]* = egyptian" "simple object, enum"
+gdb_test "print test1.value" "\\$\[0-9\]* = egyptian = \\(enum region\\)1" "simple object, enum"

# Two.

@@ -85,10 +85,10 @@ gdb_test "print test2.key1" "\\$\[0-9\]* = 5" "derived template object, base con
gdb_test "print test2.key2" "\\$\[0-9\]* = 7" "derived template object, base long"

# derived template object, base enum
-gdb_test "print test2.value" "\\$\[0-9\]* = oriental" "derived template object, base enum"
+gdb_test "print test2.value" "\\$\[0-9\]* = oriental = \\(enum region\\)0" "derived template object, base enum"

# derived template object, enum
-gdb_test "print test2.value_derived" "\\$\[0-9\]* = roman" "derived template object, derived enum"
+gdb_test "print test2.value_derived" "\\$\[0-9\]* = roman = \\(enum region\\)4" "derived template object, derived enum"

# Three.

@@ -102,10 +102,10 @@ gdb_test "print test3.data.key1" "\\$\[0-9\]* = 5" "template object, const int"
gdb_test "print test3.data.key2" "\\$\[0-9\]* = 7" "template object, long"

# template object, derived template data member's base enum
-gdb_test "print test3.data.value" "\\$\[0-9\]* = oriental" "template object, base enum"
+gdb_test "print test3.data.value" "\\$\[0-9\]* = oriental = \\(enum region\\)0" "template object, base enum"

# template object, derived template data member's enum
-gdb_test "print test3.data.value_derived" "\\$\[0-9]\* = etruscan" "template object, derived enum"
+gdb_test "print test3.data.value_derived" "\\$\[0-9]\* = etruscan = \\(enum region\\)3" "template object, derived enum"

# Now some tests for shadowing (see PR gdb/804):

--- a/gdb/testsuite/gdb.cp/m-static.exp
+++ b/gdb/testsuite/gdb.cp/m-static.exp
@@ -82,7 +82,7 @@ gdb_test "print test1.key1" "\\$\[0-9\]* = 5" "simple object, static const int"
gdb_test "print test1.key2" "\\$\[0-9\]* = 77" "simple object, static long"

# simple object, static enum
-gdb_test "print test1.value" "\\$\[0-9\]* = oriental" "simple object, static enum"
+gdb_test "print test1.value" "\\$\[0-9\]* = oriental = \\(enum region\\)0" "simple object, static enum"

# Two.

@@ -96,10 +96,10 @@ gdb_test "print test2.key1" "\\$\[0-9\]* = 5" "derived template object, base sta
gdb_test "print test2.key2" "\\$\[0-9\]* = 77" "derived template object, base static long"

# derived template object, base static enum
-gdb_test "print test2.value" "\\$\[0-9\].* = oriental" "derived template object, base static enum"
+gdb_test "print test2.value" "\\$\[0-9\].* = oriental = \\(enum region\\)0" "derived template object, base static enum"

# derived template object, static enum
-gdb_test "print test2.value_derived" "\\$\[0-9\].* = etruscan" "derived template object, static enum"
+gdb_test "print test2.value_derived" "\\$\[0-9\].* = etruscan = \\(enum region\\)3" "derived template object, static enum"

# Three.

@@ -113,10 +113,10 @@ gdb_test "print test3.data.key1" "\\$\[0-9\].* = 5" "template object, static con
gdb_test "print test3.data.key2" "\\$\[0-9\].* = 77" "template object, static long"

# template object, static derived template data member's base static enum
-gdb_test "print test3.data.value" "\\$\[0-9\].* = oriental" "template object, static enum"
+gdb_test "print test3.data.value" "\\$\[0-9\].* = oriental = \\(enum region\\)0" "template object, static enum"

# template object, static derived template data member's static enum
-gdb_test "print test3.data.value_derived" "\\$\[0-9\].* = etruscan" "template object, static derived enum"
+gdb_test "print test3.data.value_derived" "\\$\[0-9\].* = etruscan = \\(enum region\\)3" "template object, static derived enum"

# 2002-08-16
# Four.
--- a/gdb/testsuite/gdb.cp/namespace.exp
+++ b/gdb/testsuite/gdb.cp/namespace.exp
@@ -273,4 +273,4 @@ gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context."
gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context."

# Enum tests.
-gdb_test "print AAA::ALPHA" "\\$\[0-9\].* = AAA::ALPHA"
+gdb_test "print AAA::ALPHA" "\\$\[0-9\].* = AAA::ALPHA = \\(enum AAA::SomeEnum\\)0"
--- a/gdb/testsuite/gdb.mi/basics.c
+++ b/gdb/testsuite/gdb.mi/basics.c
@@ -24,6 +24,8 @@ Free Software Foundation, Inc.
#include <stdio.h>
#include <unistd.h>

+static enum enum_name { enumerator } E = enumerator;
+
int callee4 (void)
{
int A=1;
--- a/gdb/testsuite/gdb.mi/mi2-eval.exp
+++ b/gdb/testsuite/gdb.mi/mi2-eval.exp
@@ -58,6 +58,8 @@ mi_gdb_test "411-data-evaluate-expression A+3" "411\\^done,value=\"4\"" "eval A+

mi_gdb_test "511-data-evaluate-expression \"A + 3\"" "511\\^done,value=\"4\"" "eval A + 3"

+mi_gdb_test "611-data-evaluate-expression \"E\"" "611\\^done,value=\"enumerator\"" "eval E"
+

mi_gdb_exit
return 0
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -115,7 +115,7 @@ proc test_value_numeric_ops {} {
gdb_test "python print 'result = ' + str(1.5+f)" " = 2.75" "add python float with double value"

# Conversion test.
- gdb_test "print evalue" " = TWO"
+ gdb_test "print evalue" " = TWO = \\(enum e\\)2"
gdb_test "python evalue = gdb.history (0)" ""
gdb_test "python print int (evalue)" "2"

--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -83,7 +83,8 @@ struct value_print_options user_print_options =
1, /* static_field_print */
1, /* pascal_static_field_print */
0, /* raw */
- 0 /* summary */
+ 0, /* summary */
+ 1 /* enum_numeric_print */
};

/* Initialize *OPTS to be a copy of the user print options. */
@@ -100,6 +101,7 @@ get_raw_print_options (struct value_print_options *opts)
{
*opts = user_print_options;
opts->pretty = Val_no_prettyprint;
+ opts->enum_numeric_print = 0;
}

/* Initialize *OPTS to be a copy of the user print options, but using
@@ -154,6 +156,17 @@ show_print_array_indexes (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
}

+/* If nonzero print also the numeric value of enum elements. */
+
+static void
+show_enum_numeric_print (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Printing of enum values with their numerical values is %s.\n"),
+ value);
+}
+
/* Print repeat counts if there are more than this many repetitions of an
element in an array. Referenced by the low level language dependent
print routines. */
@@ -1734,4 +1747,12 @@ Use 'show input-radix' or 'show output-radix' to independently show each."),
Set printing of array indexes."), _("\
Show printing of array indexes"), NULL, NULL, show_print_array_indexes,
&setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("enum-numeric-print", class_support,
+ &user_print_options.enum_numeric_print, _("\
+Set printing of enum values with their numerical values."), _("\
+Show printing of enum values with their numerical values."), NULL,
+ NULL,
+ show_enum_numeric_print,
+ &setprintlist, &showprintlist);
}
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -90,6 +90,9 @@ struct value_print_options

/* If nonzero, print the value in "summary" form. */
int summary;
+
+ /* If nonzero print also the numeric value of enum elements. */
+ int enum_numeric_print;
};

/* The global print options set by the user. In general this should
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2544,6 +2544,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
get_formatted_print_options (&opts, format_code[(int) format]);
opts.deref_ref = 0;
opts.raw = 1;
+ opts.enum_numeric_print = 0;
if (thevalue)
{
make_cleanup (xfree, thevalue);