From: Tom Tromey Date: Tue, 23 Jun 2009 16:26:05 +0000 (+0000) Subject: gdb X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=85e306ed0eb2fb5032d459a13cfd345edf1bb2aa;p=binutils-gdb.git gdb PR gdb/10309: * c-lang.c (classify_type): Iterate over typedefs. * c-valprint.c (textual_element_type): Iterate over typedefs. gdb/testsuite * gdb.base/charset.exp (test_combination): Regression test. * gdb.base/charset.c (my_wchar_t): New typedef. (myvar): New global. (main): Set myvar. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ecb49bb6049..e6d9f2ee9ca 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2009-06-23 Tom Tromey + + PR gdb/10309: + * c-lang.c (classify_type): Iterate over typedefs. + * c-valprint.c (textual_element_type): Iterate over typedefs. + 2009-06-22 Jan Kratochvil PR gdb/9988: diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 898ae8ddb8b..57181433a5a 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -77,9 +77,12 @@ classify_type (struct type *elttype, const char **encoding) struct type *saved_type; enum c_string_type result; - /* We do one or two passes -- one on ELTTYPE, and then maybe a - second one on a typedef target. */ - do + /* We loop because ELTTYPE may be a typedef, and we want to + successively peel each typedef until we reach a type we + understand. We don't use CHECK_TYPEDEF because that will strip + all typedefs at once -- but in C, wchar_t is itself a typedef, so + that would do the wrong thing. */ + while (elttype) { char *name = TYPE_NAME (elttype); @@ -107,10 +110,22 @@ classify_type (struct type *elttype, const char **encoding) goto done; } - saved_type = elttype; - CHECK_TYPEDEF (elttype); + if (TYPE_CODE (elttype) != TYPE_CODE_TYPEDEF) + break; + + /* Call for side effects. */ + check_typedef (elttype); + + if (TYPE_TARGET_TYPE (elttype)) + elttype = TYPE_TARGET_TYPE (elttype); + else + { + /* Perhaps check_typedef did not update the target type. In + this case, force the lookup again and hope it works out. + It never will for C, but it might for C++. */ + CHECK_TYPEDEF (elttype); + } } - while (elttype != saved_type); /* Punt. */ result = C_CHAR; diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 3433da22f65..b2020f3c1ed 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -81,23 +81,42 @@ textual_name (const char *name) static int textual_element_type (struct type *type, char format) { - struct type *true_type = check_typedef (type); + struct type *true_type, *iter_type; if (format != 0 && format != 's') return 0; + /* We also rely on this for its side effect of setting up all the + typedef pointers. */ + true_type = check_typedef (type); + /* TYPE_CODE_CHAR is always textual. */ if (TYPE_CODE (true_type) == TYPE_CODE_CHAR) return 1; + /* Any other character-like types must be integral. */ if (TYPE_CODE (true_type) != TYPE_CODE_INT) return 0; - /* Check the names of the type and the typedef. */ - if (TYPE_NAME (type) && textual_name (TYPE_NAME (type))) - return 1; - if (TYPE_NAME (true_type) && textual_name (TYPE_NAME (true_type))) - return 1; + /* We peel typedefs one by one, looking for a match. */ + iter_type = type; + while (iter_type) + { + /* Check the name of the type. */ + if (TYPE_NAME (iter_type) && textual_name (TYPE_NAME (iter_type))) + return 1; + + if (TYPE_CODE (iter_type) != TYPE_CODE_TYPEDEF) + break; + + /* Peel a single typedef. If the typedef doesn't have a target + type, we use check_typedef and hope the result is ok -- it + might be for C++, where wchar_t is a built-in type. */ + if (TYPE_TARGET_TYPE (iter_type)) + iter_type = TYPE_TARGET_TYPE (iter_type); + else + iter_type = check_typedef (iter_type); + } if (format == 's') { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f7572b34306..1a442a5d59a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-06-23 Tom Tromey + + * gdb.base/charset.exp (test_combination): Regression test. + * gdb.base/charset.c (my_wchar_t): New typedef. + (myvar): New global. + (main): Set myvar. + 2009-06-18 Pierre Muller * lib/gdb.exp (gdb_compile): Also force unbuffered mode for DJGPP diff --git a/gdb/testsuite/gdb.base/charset.c b/gdb/testsuite/gdb.base/charset.c index 55a50ce57b2..b61e047e954 100644 --- a/gdb/testsuite/gdb.base/charset.c +++ b/gdb/testsuite/gdb.base/charset.c @@ -65,6 +65,10 @@ typedef unsigned int char32_t; char16_t uvar; char32_t Uvar; +/* A typedef to a typedef should also work. */ +typedef wchar_t my_wchar_t; +my_wchar_t myvar; + void init_string (char string[], char x, @@ -169,5 +173,7 @@ int main () init_ucs4 (); + myvar = ucs_4_string[7]; + return 0; /* all strings initialized */ } diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp index 8c238489d70..85885c8e25c 100644 --- a/gdb/testsuite/gdb.base/charset.exp +++ b/gdb/testsuite/gdb.base/charset.exp @@ -599,6 +599,9 @@ if {$wchar_ok && $ucs2_ok} { } if {$wchar_ok && $ucs4_ok} { test_combination L wide U UCS-4 + # Regression test for a typedef to a typedef. + gdb_test "print myvar" "= \[0-9\]+ L'A'" \ + "typedef to wchar_t" } if {$ucs2_ok && $ucs4_ok} { test_combination u UCS-2 U UCS-4