gdb/
PR exp/12117 * gdbtypes.c (check_typedef): Clean up function comment. Keep track of instance flags as we strip typedefs and create a new type to preserve them if necessary. * gdbtypes.h (type) <instance_flags>: Extend the comment. gdb/testsuite/ PR exp/12117 * gdb.cp/ptype-cv-cp.cc: New file. * gdb.cp/ptype-cv-cp.exp: New file.
This commit is contained in:
parent
3917d5d5ca
commit
92163a10dc
6 changed files with 159 additions and 28 deletions
|
@ -1,3 +1,12 @@
|
|||
2010-10-15 Doug Evans <dje@google.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR exp/12117
|
||||
* gdbtypes.c (check_typedef): Clean up function comment.
|
||||
Keep track of instance flags as we strip typedefs and create a new
|
||||
type to preserve them if necessary.
|
||||
* gdbtypes.h (type) <instance_flags>: Extend the comment.
|
||||
|
||||
2010-10-15 Pierre Muller <muller@ics.u-strasbg.fr>
|
||||
|
||||
* p-lang.c (is_pascal_string_type): Use TYPE_FIELD_NAME accessor.
|
||||
|
|
|
@ -1347,7 +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.
|
||||
/* 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.
|
||||
|
||||
Instance flags (e.g. const/volatile) are preserved as typedefs are
|
||||
stripped. If necessary a new qualified form of the underlying type
|
||||
is created.
|
||||
|
||||
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
|
||||
|
@ -1355,26 +1369,15 @@ stub_noname_complaint (void)
|
|||
(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.
|
||||
|
||||
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. */
|
||||
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;
|
||||
/* While we're removing typedefs, we don't want to lose qualifiers.
|
||||
E.g., const/volatile. */
|
||||
int instance_flags = TYPE_INSTANCE_FLAGS (type);
|
||||
|
||||
gdb_assert (type);
|
||||
|
||||
|
@ -1388,7 +1391,7 @@ check_typedef (struct type *type)
|
|||
/* It is dangerous to call lookup_symbol if we are currently
|
||||
reading a symtab. Infinite recursion is one danger. */
|
||||
if (currently_reading_symtab)
|
||||
return type;
|
||||
return make_qualified_type (type, instance_flags, NULL);
|
||||
|
||||
name = type_name_no_tag (type);
|
||||
/* FIXME: shouldn't we separately check the TYPE_NAME and
|
||||
|
@ -1398,7 +1401,7 @@ check_typedef (struct type *type)
|
|||
if (name == NULL)
|
||||
{
|
||||
stub_noname_complaint ();
|
||||
return type;
|
||||
return make_qualified_type (type, instance_flags, NULL);
|
||||
}
|
||||
sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
|
||||
if (sym)
|
||||
|
@ -1407,10 +1410,33 @@ check_typedef (struct type *type)
|
|||
TYPE_TARGET_TYPE (type) = alloc_type_arch (get_type_arch (type));
|
||||
}
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
}
|
||||
|
||||
is_const = TYPE_CONST (type);
|
||||
is_volatile = TYPE_VOLATILE (type);
|
||||
/* Preserve the instance flags as we traverse down the typedef chain.
|
||||
|
||||
Handling address spaces/classes is nasty, what do we do if there's a
|
||||
conflict?
|
||||
E.g., what if an outer typedef marks the type as class_1 and an inner
|
||||
typedef marks the type as class_2?
|
||||
This is the wrong place to do such error checking. We leave it to
|
||||
the code that created the typedef in the first place to flag the
|
||||
error. We just pick the outer address space (akin to letting the
|
||||
outer cast in a chain of casting win), instead of assuming
|
||||
"it can't happen". */
|
||||
{
|
||||
const int ALL_SPACES = (TYPE_INSTANCE_FLAG_CODE_SPACE
|
||||
| TYPE_INSTANCE_FLAG_DATA_SPACE);
|
||||
const int ALL_CLASSES = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL;
|
||||
int new_instance_flags = TYPE_INSTANCE_FLAGS (type);
|
||||
|
||||
/* Treat code vs data spaces and address classes separately. */
|
||||
if ((instance_flags & ALL_SPACES) != 0)
|
||||
new_instance_flags &= ~ALL_SPACES;
|
||||
if ((instance_flags & ALL_CLASSES) != 0)
|
||||
new_instance_flags &= ~ALL_CLASSES;
|
||||
|
||||
instance_flags |= new_instance_flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a struct/class/union with no fields, then check
|
||||
whether a full definition exists somewhere else. This is for
|
||||
|
@ -1428,7 +1454,7 @@ check_typedef (struct type *type)
|
|||
if (name == NULL)
|
||||
{
|
||||
stub_noname_complaint ();
|
||||
return type;
|
||||
return make_qualified_type (type, instance_flags, NULL);
|
||||
}
|
||||
newtype = lookup_transparent_type (name);
|
||||
|
||||
|
@ -1445,7 +1471,9 @@ check_typedef (struct type *type)
|
|||
move over any other types NEWTYPE refers to, which could
|
||||
be an unbounded amount of stuff. */
|
||||
if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))
|
||||
make_cv_type (is_const, is_volatile, newtype, &type);
|
||||
type = make_qualified_type (newtype,
|
||||
TYPE_INSTANCE_FLAGS (type),
|
||||
type);
|
||||
else
|
||||
type = newtype;
|
||||
}
|
||||
|
@ -1464,17 +1492,18 @@ check_typedef (struct type *type)
|
|||
if (name == NULL)
|
||||
{
|
||||
stub_noname_complaint ();
|
||||
return type;
|
||||
return make_qualified_type (type, instance_flags, NULL);
|
||||
}
|
||||
sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
|
||||
if (sym)
|
||||
{
|
||||
/* Same as above for opaque types, we can replace the stub
|
||||
with the complete type only if they are int the same
|
||||
with the complete type only if they are in the same
|
||||
objfile. */
|
||||
if (TYPE_OBJFILE (SYMBOL_TYPE(sym)) == TYPE_OBJFILE (type))
|
||||
make_cv_type (is_const, is_volatile,
|
||||
SYMBOL_TYPE (sym), &type);
|
||||
type = make_qualified_type (SYMBOL_TYPE (sym),
|
||||
TYPE_INSTANCE_FLAGS (type),
|
||||
type);
|
||||
else
|
||||
type = SYMBOL_TYPE (sym);
|
||||
}
|
||||
|
@ -1534,8 +1563,12 @@ check_typedef (struct type *type)
|
|||
TYPE_TARGET_STUB (type) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
type = make_qualified_type (type, instance_flags, NULL);
|
||||
|
||||
/* Cache TYPE_LENGTH for future use. */
|
||||
TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -623,7 +623,14 @@ struct type
|
|||
struct type *chain;
|
||||
|
||||
/* Flags specific to this instance of the type, indicating where
|
||||
on the ring we are. */
|
||||
on the ring we are.
|
||||
|
||||
For TYPE_CODE_TYPEDEF the flags of the typedef type should be binary
|
||||
or-ed with the target type, with a special case for address class and
|
||||
space class. For example if this typedef does not specify any new
|
||||
qualifiers, TYPE_INSTANCE_FLAGS is 0 and the instance flags are
|
||||
completely inherited from the target type. No qualifiers can be cleared
|
||||
by the typedef. See also check_typedef. */
|
||||
int instance_flags;
|
||||
|
||||
/* Length of storage for a value of this type. This is what
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2010-10-13 Doug Evans <dje@google.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR exp/12117
|
||||
* gdb.cp/ptype-cv-cp.cc: New file.
|
||||
* gdb.cp/ptype-cv-cp.exp: New file.
|
||||
|
||||
2010-10-14 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdb.cp/converts.cc: New test program.
|
||||
|
|
34
gdb/testsuite/gdb.cp/ptype-cv-cp.cc
Normal file
34
gdb/testsuite/gdb.cp/ptype-cv-cp.cc
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* 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/>. */
|
||||
|
||||
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;
|
||||
}
|
41
gdb/testsuite/gdb.cp/ptype-cv-cp.exp
Normal file
41
gdb/testsuite/gdb.cp/ptype-cv-cp.exp
Normal file
|
@ -0,0 +1,41 @@
|
|||
# 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/>.
|
||||
|
||||
# This file is part of the gdb testsuite.
|
||||
|
||||
if { [skip_cplus_tests] } { continue }
|
||||
|
||||
set testfile "ptype-cv-cp"
|
||||
set srcfile ${testfile}.cc
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test "whatis v_my_int" "type = my_int"
|
||||
gdb_test "ptype v_my_int" "type = int"
|
||||
|
||||
gdb_test "whatis v_const_my_int" "type = const_my_int"
|
||||
gdb_test "ptype v_const_my_int" "type = const int"
|
||||
|
||||
gdb_test "whatis v_volatile_my_int" "type = volatile_my_int"
|
||||
gdb_test "ptype v_volatile_my_int" "type = volatile int"
|
||||
|
||||
gdb_test "whatis v_const_volatile_my_int" "type = const_volatile_my_int"
|
||||
gdb_test "ptype v_const_volatile_my_int" "type = const volatile int"
|
||||
|
||||
gdb_test "whatis v_volatile_const_my_int" "type = volatile_const_my_int"
|
||||
setup_kfail "gcc/45997" *-*-*
|
||||
gdb_test "ptype v_volatile_const_my_int" "type = const volatile int"
|
Loading…
Reference in a new issue