From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24721 invoked by alias); 13 Oct 2010 17:53:23 -0000 Received: (qmail 24689 invoked by uid 22791); 13 Oct 2010 17:53:20 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.35) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Oct 2010 17:53:12 +0000 Received: from hpaq13.eem.corp.google.com (hpaq13.eem.corp.google.com [172.25.149.13]) by smtp-out.google.com with ESMTP id o9DHrAXF003354 for ; Wed, 13 Oct 2010 10:53:10 -0700 Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.18.118.116]) by hpaq13.eem.corp.google.com with ESMTP id o9DHr8GN014795 for ; Wed, 13 Oct 2010 10:53:09 -0700 Received: by ruffy.mtv.corp.google.com (Postfix, from userid 67641) id 17B772461AE; Wed, 13 Oct 2010 10:53:08 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [patch] fix exp/12117 Message-Id: <20101013175308.17B772461AE@ruffy.mtv.corp.google.com> Date: Wed, 13 Oct 2010 17:53:00 -0000 From: dje@google.com (Doug Evans) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-10/txt/msg00225.txt.bz2 Hi. This patch fixes pr exp/12117. http://sourceware.org/bugzilla/show_bug.cgi?id=12117 I will check this in in two days if there are no objections. 2010-10-13 Doug Evans PR exp/12117 * c-typeprint.c (c_print_type): Call CHECK_TYPEDEF after calling c_type_print_base. (c_type_print_modifier_flags): New function. (c_type_print_modifier): Call it. (c_type_print_base): Collect instance_flags while we're stripping typedefs. Change calls to c_type_print_modifier to call c_type_print_modifier_flags instead. (c_type_print_base, case TYPE_CODE_TYPEDEF): Verify assumptions of when this case happens. Print "". * gdbtypes.h (strip_typedefs): Declare. * gdbtypes.c (strip_typedefs): New function. (check_typedef): Call it. testsuite/ * gdb.cp/pr12117.cc: New file. * gdb.cp/pr12117.exp: New file. Index: c-typeprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-typeprint.c,v retrieving revision 1.62 diff -u -p -r1.62 c-typeprint.c --- c-typeprint.c 13 Oct 2010 15:10:10 -0000 1.62 +++ c-typeprint.c 13 Oct 2010 17:29:30 -0000 @@ -53,10 +53,13 @@ c_print_type (struct type *type, const c int demangled_args; int need_post_space; + c_type_print_base (type, stream, show, level); + + /* Do this *after* calling c_type_print_base so that it can see any + const/volatile flags that may be encoded in a typedef. */ if (show > 0) CHECK_TYPEDEF (type); - c_type_print_base (type, stream, show, level); code = TYPE_CODE (type); if ((varstring != NULL && *varstring != '\0') /* Need a space if going to print stars or brackets; @@ -313,23 +316,20 @@ c_type_print_varspec_prefix (struct type /* Print out "const" and "volatile" attributes, and address space id if present. - TYPE is a pointer to the type being printed out. + FLAGS is the TYPE_INSTANCE_FLAGS flags of the type. STREAM is the output destination. NEED_PRE_SPACE = 1 indicates an initial white space is needed. NEED_POST_SPACE = 1 indicates a final white space is needed. */ static void -c_type_print_modifier (struct type *type, struct ui_file *stream, - int need_pre_space, int need_post_space) +c_type_print_modifier_flags (int flags, struct ui_file *stream, + struct gdbarch *gdbarch, + int need_pre_space, int need_post_space) { int did_print_modifier = 0; const char *address_space_id; - /* We don't print `const' qualifiers for references --- since all - operators affect the thing referenced, not the reference itself, - every reference is `const'. */ - if (TYPE_CONST (type) - && TYPE_CODE (type) != TYPE_CODE_REF) + if (flags & TYPE_INSTANCE_FLAG_CONST) { if (need_pre_space) fprintf_filtered (stream, " "); @@ -337,7 +337,7 @@ c_type_print_modifier (struct type *type did_print_modifier = 1; } - if (TYPE_VOLATILE (type)) + if (flags & TYPE_INSTANCE_FLAG_VOLATILE) { if (did_print_modifier || need_pre_space) fprintf_filtered (stream, " "); @@ -345,8 +345,7 @@ c_type_print_modifier (struct type *type did_print_modifier = 1; } - address_space_id = address_space_int_to_name (get_type_arch (type), - TYPE_INSTANCE_FLAGS (type)); + address_space_id = address_space_int_to_name (gdbarch, flags); if (address_space_id) { if (did_print_modifier || need_pre_space) @@ -359,6 +358,24 @@ c_type_print_modifier (struct type *type fprintf_filtered (stream, " "); } +/* Wrapper for c_type_print_modifier_flags. + Print the modifier flags for TYPE. */ + +static void +c_type_print_modifier (struct type *type, struct ui_file *stream, + int need_pre_space, int need_post_space) +{ + int instance_flags = TYPE_INSTANCE_FLAGS (type); + + /* We don't print `const' qualifiers for references --- since all + operators affect the thing referenced, not the reference itself, + every reference is `const'. */ + if (TYPE_CODE (type) == TYPE_CODE_REF) + instance_flags &= ~TYPE_INSTANCE_FLAG_CONST; + + c_type_print_modifier_flags (instance_flags, stream, get_type_arch (type), + need_pre_space, need_post_space); +} /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" @@ -678,6 +695,8 @@ c_type_print_base (struct type *type, st section_type; int need_access_label = 0; int j, len2; + int instance_flags; + struct gdbarch *gdbarch; QUIT; @@ -702,11 +721,33 @@ c_type_print_base (struct type *type, st return; } + /* Handle typedefs specially because we want to strip them, but as we're + stripping them we need to keep track of any instance-related flags, + e.g., const/volatile. Furthermore, we would like to print the flags + once, and in a consistent order, so just accumulate them as we're + stripping. */ + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + type = strip_typedefs (type, &instance_flags); + else + instance_flags = 0; + + /* We've already stripped typedefs, but we still need to try to + update stubbed structs, etc. */ CHECK_TYPEDEF (type); + instance_flags |= TYPE_INSTANCE_FLAGS (type); + gdbarch = get_type_arch (type); + switch (TYPE_CODE (type)) { case TYPE_CODE_TYPEDEF: + /* If we get here, the typedef doesn't have a name, and we couldn't + resolve TYPE_TARGET_TYPE. Not much we can do. */ + gdb_assert (TYPE_NAME (type) == NULL); + gdb_assert (TYPE_TARGET_TYPE (type) == NULL); + fprintf_filtered (stream, _("")); + break; + case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: case TYPE_CODE_MEMBERPTR: @@ -718,7 +759,7 @@ c_type_print_base (struct type *type, st break; case TYPE_CODE_STRUCT: - c_type_print_modifier (type, stream, 0, 1); + c_type_print_modifier_flags (instance_flags, stream, gdbarch, 0, 1); if (TYPE_DECLARED_CLASS (type)) fprintf_filtered (stream, "class "); else @@ -726,7 +767,7 @@ c_type_print_base (struct type *type, st goto struct_union; case TYPE_CODE_UNION: - c_type_print_modifier (type, stream, 0, 1); + c_type_print_modifier_flags (instance_flags, stream, gdbarch, 0, 1); fprintf_filtered (stream, "union "); struct_union: @@ -1083,7 +1124,7 @@ c_type_print_base (struct type *type, st break; case TYPE_CODE_ENUM: - c_type_print_modifier (type, stream, 0, 1); + c_type_print_modifier_flags (instance_flags, stream, gdbarch, 0, 1); fprintf_filtered (stream, "enum "); /* Print the tag name if it exists. The aCC compiler emits a spurious @@ -1157,7 +1198,7 @@ c_type_print_base (struct type *type, st is no type name, then complain. */ if (TYPE_NAME (type) != NULL) { - c_type_print_modifier (type, stream, 0, 1); + c_type_print_modifier_flags (instance_flags, stream, gdbarch, 0, 1); fputs_filtered (TYPE_NAME (type), stream); } else Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.201 diff -u -p -r1.201 gdbtypes.c --- gdbtypes.c 12 Oct 2010 20:58:17 -0000 1.201 +++ gdbtypes.c 13 Oct 2010 17:29:30 -0000 @@ -1347,36 +1347,21 @@ stub_noname_complaint (void) complaint (&symfile_complaints, _("stub type has NULL name")); } -/* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989. +/* Strip all typedefs from TYPE. + Return the real type if possible. - If this is a stubbed struct (i.e. declared as struct foo *), see if - we can find a full definition in some other file. If so, copy this - definition, so we can use it in future. There used to be a comment - (but not any code) that if we don't find a full definition, we'd - set a flag so we don't spend time in the future checking the same - type. That would be a mistake, though--we might load in more - symbols which contain a full definition for the type. + NOTE: This will return a typedef if TYPE_TARGET_TYPE for the typedef has + not been computed and we're either in the middle of reading symbols, or + there was no name for the typedef in the debug info. - This used to be coded as a macro, but I don't think it is called - often enough to merit such treatment. - - Find the real type of TYPE. This function returns the real type, - after removing all layers of typedefs and completing opaque or stub - types. Completion changes the TYPE argument, but stripping of - typedefs does not. - - If TYPE is a TYPE_CODE_TYPEDEF, its length is (also) set to the length of - the target type instead of zero. However, in the case of TYPE_CODE_TYPEDEF - check_typedef can still return different type than the original TYPE - pointer. */ + Any instance flags (e.g. const/volatile/address-space) that were stripped + away are stored in *INSTANCE_FLAGSP if non-NULL. */ struct type * -check_typedef (struct type *type) +strip_typedefs (struct type *type, int *instance_flagsp) { - struct type *orig_type = type; - int is_const, is_volatile; - - gdb_assert (type); + if (instance_flagsp != NULL) + *instance_flagsp = 0; while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) { @@ -1406,9 +1391,50 @@ check_typedef (struct type *type) else /* TYPE_CODE_UNDEF */ TYPE_TARGET_TYPE (type) = alloc_type_arch (get_type_arch (type)); } + + if (instance_flagsp != NULL) + *instance_flagsp |= TYPE_INSTANCE_FLAGS (type); + type = TYPE_TARGET_TYPE (type); } + return type; +} + +/* Find the real type of TYPE. This function returns the real type, + after removing all layers of typedefs and completing opaque or stub + types. Completion changes the TYPE argument, but stripping of + typedefs does not. + + NOTE: This will return a typedef if TYPE_TARGET_TYPE for the typedef has + not been computed and we're either in the middle of reading symbols, or + there was no name for the typedef in the debug info. + + If TYPE is a TYPE_CODE_TYPEDEF, its length is updated to the length of + the target type. + + If this is a stubbed struct (i.e. declared as struct foo *), see if + we can find a full definition in some other file. If so, copy this + definition, so we can use it in future. There used to be a comment + (but not any code) that if we don't find a full definition, we'd + set a flag so we don't spend time in the future checking the same + type. That would be a mistake, though--we might load in more + symbols which contain a full definition for the type. */ + +struct type * +check_typedef (struct type *type) +{ + struct type *orig_type = type; + int is_const, is_volatile; + + gdb_assert (type); + + type = strip_typedefs (type, NULL); + + /* If we still have a typedef, there's nothing more we can do. */ + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + return type; + is_const = TYPE_CONST (type); is_volatile = TYPE_VOLATILE (type); Index: gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.135 diff -u -p -r1.135 gdbtypes.h --- gdbtypes.h 6 Oct 2010 08:44:14 -0000 1.135 +++ gdbtypes.h 13 Oct 2010 17:29:30 -0000 @@ -1361,6 +1361,8 @@ extern struct type *check_typedef (struc (TYPE) = check_typedef (TYPE); \ } while (0) +extern struct type *strip_typedefs (struct type *, int *); + extern void check_stub_method_group (struct type *, int); extern char *gdb_mangle_name (struct type *, int, int); Index: testsuite/gdb.cp/pr12117.cc =================================================================== RCS file: testsuite/gdb.cp/pr12117.cc diff -N testsuite/gdb.cp/pr12117.cc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/pr12117.cc 13 Oct 2010 17:29:31 -0000 @@ -0,0 +1,17 @@ +typedef int my_int; +typedef const my_int const_my_int; +typedef volatile my_int volatile_my_int; +typedef volatile const_my_int volatile_const_my_int; +typedef const volatile_my_int const_volatile_my_int; + +my_int v_my_int (0); +const_my_int v_const_my_int (1); +volatile_my_int v_volatile_my_int (2); +const_volatile_my_int v_const_volatile_my_int (3); +volatile_const_my_int v_volatile_const_my_int (4); + +int +main () +{ + return 0; +} Index: testsuite/gdb.cp/pr12117.exp =================================================================== RCS file: testsuite/gdb.cp/pr12117.exp diff -N testsuite/gdb.cp/pr12117.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.cp/pr12117.exp 13 Oct 2010 17:29:31 -0000 @@ -0,0 +1,55 @@ +# 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 . + +# This file is part of the gdb testsuite. + +if { [skip_cplus_tests] } { continue } + +load_lib "cp-support.exp" + +set testfile "pr12117" +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested ${testfile}.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "couldn't run to breakpoint" + continue +} + +gdb_test "whatis v_my_int" "my_int" +gdb_test "ptype v_my_int" "int" + +gdb_test "whatis v_const_my_int" "const_my_int" +gdb_test "ptype v_const_my_int" "const int" + +gdb_test "whatis v_volatile_my_int" "volatile_my_int" +gdb_test "ptype v_volatile_my_int" "volatile int" + +gdb_test "whatis v_const_volatile_my_int" "const_volatile_my_int" +gdb_test "ptype v_const_volatile_my_int" "const volatile int" + +gdb_test "whatis v_volatile_const_my_int" "volatile_const_my_int" +setup_kfail "gcc/45997" *-*-* +gdb_test "ptype v_volatile_const_my_int" "const volatile int"