diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40ca684ba3e..8426f00efa3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-04-11 Mark Mitchell + + * dwarf2out.c (modified_type_die): Don't create new types here. + * tree.h (get_qualified_type): New function. + (build_qualified_type): Adjust comment. + * tree.c (get_qualified_type): New function. + (build_qualified_type): Use it. + 2001-04-11 Kaveh R. Ghazi * cpp.texi (-Wtraditional): Update description. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 6f04c753c26..9be55d8ff6d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6812,22 +6812,35 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die) if (code != ERROR_MARK) { - type = build_type_variant (type, is_const_type, is_volatile_type); + tree qualified_type; - mod_type_die = lookup_type_die (type); - if (mod_type_die) - return mod_type_die; + /* See if we already have the appropriately qualified variant of + this type. */ + qualified_type + = get_qualified_type (type, + ((is_const_type ? TYPE_QUAL_CONST : 0) + | (is_volatile_type + ? TYPE_QUAL_VOLATILE : 0))); + /* If we do, then we can just use its DIE, if it exists. */ + if (qualified_type) + { + mod_type_die = lookup_type_die (qualified_type); + if (mod_type_die) + return mod_type_die; + } /* Handle C typedef types. */ - if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) + if (qualified_type && TYPE_NAME (qualified_type) + && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL + && DECL_ORIGINAL_TYPE (TYPE_NAME (qualified_type))) { - tree dtype = TREE_TYPE (TYPE_NAME (type)); - if (type == dtype) + tree type_name = TYPE_NAME (qualified_type); + tree dtype = TREE_TYPE (type_name); + if (qualified_type == dtype) { /* For a named type, use the typedef. */ - gen_type_die (type, context_die); - mod_type_die = lookup_type_die (type); + gen_type_die (qualified_type, context_die); + mod_type_die = lookup_type_die (qualified_type); } else if (is_const_type < TYPE_READONLY (dtype) @@ -6835,7 +6848,7 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die) /* cv-unqualified version of named type. Just use the unnamed type to which it refers. */ mod_type_die - = modified_type_die (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), + = modified_type_die (DECL_ORIGINAL_TYPE (type_name), is_const_type, is_volatile_type, context_die); /* Else cv-qualified version of named type; fall through. */ diff --git a/gcc/testsuite/g++.old-deja/g++.other/debug8.C b/gcc/testsuite/g++.old-deja/g++.other/debug8.C new file mode 100644 index 00000000000..2b78be2911f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/debug8.C @@ -0,0 +1,21 @@ +// Build don't link: +// Special g++ Options: -g + +struct X { + const int x[4]; +}; + +struct A { + A(); + A(const A&); +}; + +struct B { + A a; + int b[4]; +}; + +struct C { + A a; + C() { B b=B(); }; +}; diff --git a/gcc/tree.c b/gcc/tree.c index c4334ce3062..1d880d78b7e 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2993,31 +2993,47 @@ set_type_quals (type, type_quals) TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0; } -/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for - the same kind of data as TYPE describes. Variants point to the - "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT, - and it points to a chain of other variants so that duplicate - variants are never made. Only main variants should ever appear as - types of expressions. */ +/* Return a version of the TYPE, qualified as indicated by the + TYPE_QUALS, if one exists. If no qualified version exists yet, + return NULL_TREE. */ + +tree +get_qualified_type (type, type_quals) + tree type; + int type_quals; +{ + tree t; + + /* Search the chain of variants to see if there is already one there just + like the one we need to have. If so, use that existing one. We must + preserve the TYPE_NAME, since there is code that depends on this. */ + for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type)) + return t; + + return NULL_TREE; +} + +/* Like get_qualified_type, but creates the type if it does not + exist. This function never returns NULL_TREE. */ tree build_qualified_type (type, type_quals) tree type; int type_quals; { - register tree t; + tree t; - /* Search the chain of variants to see if there is already one there just - like the one we need to have. If so, use that existing one. We must - preserve the TYPE_NAME, since there is code that depends on this. */ + /* See if we already have the appropriate qualified variant. */ + t = get_qualified_type (type, type_quals); - for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type)) - return t; + /* If not, build it. */ + if (!t) + { + t = build_type_copy (type); + set_type_quals (t, type_quals); + } - /* We need a new one. */ - t = build_type_copy (type); - set_type_quals (t, type_quals); return t; } diff --git a/gcc/tree.h b/gcc/tree.h index a394a31f396..fe5a75fc44f 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2060,12 +2060,14 @@ extern tree lookup_attribute PARAMS ((const char *, tree)); extern tree merge_attributes PARAMS ((tree, tree)); -/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for - the same kind of data as TYPE describes. Variants point to the - "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT, - and it points to a chain of other variants so that duplicate - variants are never made. Only main variants should ever appear as - types of expressions. */ +/* Return a version of the TYPE, qualified as indicated by the + TYPE_QUALS, if one exists. If no qualified version exists yet, + return NULL_TREE. */ + +extern tree get_qualified_type PARAMS ((tree, int)); + +/* Like get_qualified_type, but creates the type if it does not + exist. This function never returns NULL_TREE. */ extern tree build_qualified_type PARAMS ((tree, int));