From 11e74ea6c6c709e8e6329bdfe7d121bfa100cf29 Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Sat, 13 Oct 2001 13:24:34 +0000 Subject: [PATCH] cp-tree.h (TYPE_BINFO): Update comment. * cp-tree.h (TYPE_BINFO): Update comment. (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro. (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info. (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS. (copy_type): Prototype new function. * lex.c (copy_lang_decl): Gather tree node statistics. (copy_lang_type): New function. (copy_type): Likewise. (cp_make_lang_type): Create lang_type for BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE and BOUND_TEMPLATE_TEMPLATE_PARM. * pt.c (tsubst): Use copy_type instead of copy_node. * search.c (lookup_field_1): Ignore TYPENAME_TYPE. From-SVN: r46244 --- gcc/cp/ChangeLog | 16 ++++++ gcc/cp/cp-tree.h | 20 ++++--- gcc/cp/lex.c | 65 ++++++++++++++++++++--- gcc/cp/pt.c | 2 +- gcc/cp/search.c | 9 ++-- gcc/testsuite/g++.dg/template/ttp1.C | 9 ++++ gcc/testsuite/g++.dg/template/typename1.C | 9 ++++ 7 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ttp1.C create mode 100644 gcc/testsuite/g++.dg/template/typename1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 58e1f98b78c..2b1b453526c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2001-10-12 Kriang Lerdsuwanakij + + * cp-tree.h (TYPE_BINFO): Update comment. + (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro. + (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info. + (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS. + (copy_type): Prototype new function. + * lex.c (copy_lang_decl): Gather tree node statistics. + (copy_lang_type): New function. + (copy_type): Likewise. + (cp_make_lang_type): Create lang_type for + BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE + and BOUND_TEMPLATE_TEMPLATE_PARM. + * pt.c (tsubst): Use copy_type instead of copy_node. + * search.c (lookup_field_1): Ignore TYPENAME_TYPE. + 2001-10-12 Kriang Lerdsuwanakij * pt.c (determine_specialization): Ignore functions without diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4f6bcabd788..34ef95a493a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -114,9 +114,6 @@ Boston, MA 02111-1307, USA. */ TYPE_BINFO For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO. - For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME. - For a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM, - this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS BINFO_VIRTUALS @@ -193,6 +190,14 @@ Boston, MA 02111-1307, USA. */ __FUNCTION__); \ __t; }) +#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \ +({ const tree __t = NODE; \ + enum tree_code __c = TREE_CODE(__t); \ + if (__c != BOUND_TEMPLATE_TEMPLATE_PARM) \ + tree_check_failed (__t, BOUND_TEMPLATE_TEMPLATE_PARM, \ + __FILE__, __LINE__, __FUNCTION__); \ + __t; }) + #else /* not ENABLE_TREE_CHECKING, or not gcc */ #define VAR_OR_FUNCTION_DECL_CHECK(NODE) NODE @@ -2147,8 +2152,10 @@ struct lang_decl non-type template parameters. */ #define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE))) -/* Template information for a bound template template parameter. */ -#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) +/* Template information for a template template parameter. */ +#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \ + (TYPE_LANG_SPECIFIC(BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \ + ->template_info) /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ #define TYPE_TEMPLATE_INFO(NODE) \ @@ -2311,7 +2318,7 @@ struct lang_decl this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the corresponding TYPE_DECL. However, this may also be a TEMPLATE_ID_EXPR if we had something like `typename X::Y'. */ -#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE) +#define TYPENAME_TYPE_FULLNAME(NODE) (TYPE_FIELDS (NODE)) /* Nonzero if NODE is an implicit typename. */ #define IMPLICIT_TYPENAME_P(NODE) \ @@ -3859,6 +3866,7 @@ extern tree identifier_typedecl_value PARAMS ((tree)); extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree)); extern void retrofit_lang_decl PARAMS ((tree)); extern tree copy_decl PARAMS ((tree)); +extern tree copy_type PARAMS ((tree)); extern tree cp_make_lang_type PARAMS ((enum tree_code)); extern tree make_aggr_type PARAMS ((enum tree_code)); extern void compiler_error PARAMS ((const char *, ...)) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 57daab4e338..ec445663ddf 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1552,6 +1552,11 @@ copy_lang_decl (node) ld = (struct lang_decl *) ggc_alloc (size); memcpy (ld, DECL_LANG_SPECIFIC (node), size); DECL_LANG_SPECIFIC (node) = ld; + +#ifdef GATHER_STATISTICS + tree_node_counts[(int)lang_decl] += 1; + tree_node_sizes[(int)lang_decl] += size; +#endif } /* Copy DECL, including any language-specific parts. */ @@ -1567,14 +1572,51 @@ copy_decl (decl) return copy; } +/* Replace the shared language-specific parts of NODE with a new copy. */ + +void +copy_lang_type (node) + tree node; +{ + int size; + struct lang_type *lt; + + if (! TYPE_LANG_SPECIFIC (node)) + return; + + size = sizeof (struct lang_type); + lt = (struct lang_type *) ggc_alloc (size); + memcpy (lt, TYPE_LANG_SPECIFIC (node), size); + TYPE_LANG_SPECIFIC (node) = lt; + +#ifdef GATHER_STATISTICS + tree_node_counts[(int)lang_type] += 1; + tree_node_sizes[(int)lang_type] += size; +#endif +} + +/* Copy TYPE, including any language-specific parts. */ + +tree +copy_type (type) + tree type; +{ + tree copy; + + copy = copy_node (type); + copy_lang_type (copy); + return copy; +} + tree cp_make_lang_type (code) enum tree_code code; { register tree t = make_node (code); - /* Set up some flags that give proper default behavior. */ - if (IS_AGGR_TYPE_CODE (code)) + /* Create lang_type structure. */ + if (IS_AGGR_TYPE_CODE (code) + || code == BOUND_TEMPLATE_TEMPLATE_PARM) { struct lang_type *pi; @@ -1582,6 +1624,16 @@ cp_make_lang_type (code) ggc_alloc_cleared (sizeof (struct lang_type))); TYPE_LANG_SPECIFIC (t) = pi; + +#ifdef GATHER_STATISTICS + tree_node_counts[(int)lang_type] += 1; + tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); +#endif + } + + /* Set up some flags that give proper default behavior. */ + if (IS_AGGR_TYPE_CODE (code)) + { SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); CLASSTYPE_INTERFACE_ONLY (t) = interface_only; @@ -1589,11 +1641,6 @@ cp_make_lang_type (code) presence of parse errors, the normal was of assuring this might not ever get executed, so we lay it out *immediately*. */ build_pointer_type (t); - -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); -#endif } else /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, @@ -1605,7 +1652,9 @@ cp_make_lang_type (code) since they can be virtual base types, and we then need a canonical binfo for them. Ideally, this would be done lazily for all types. */ - if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM) + if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM + || code == BOUND_TEMPLATE_TEMPLATE_PARM + || code == TYPENAME_TYPE) TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE); return t; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 229bccc88c2..cd68629ab92 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6429,7 +6429,7 @@ tsubst (t, args, complain, in_decl) } else { - r = copy_node (t); + r = copy_type (t); TEMPLATE_TYPE_PARM_INDEX (r) = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), r, levels); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index f543f0dad0e..4c3249b2fff 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -564,11 +564,14 @@ lookup_field_1 (type, name) register tree field; if (TREE_CODE (type) == TEMPLATE_TYPE_PARM - || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) - /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all; + || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM + || TREE_CODE (type) == TYPENAME_TYPE) + /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM and + BOUND_TEMPLATE_TEMPLATE_PARM are not fields at all; instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously, the code often worked even when we treated the index as a list - of fields!) */ + of fields!) + The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */ return NULL_TREE; if (TYPE_NAME (type) diff --git a/gcc/testsuite/g++.dg/template/ttp1.C b/gcc/testsuite/g++.dg/template/ttp1.C new file mode 100644 index 00000000000..7b323028ec5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp1.C @@ -0,0 +1,9 @@ +// Origin: Volker Reichelt +// { dg-do compile } + +template