cp-tree.h (TYPE_BINFO): Update comment.
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Sat, 13 Oct 2001 13:24:34 +0000 (13:24 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Sat, 13 Oct 2001 13:24:34 +0000 (13:24 +0000)
* 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
gcc/cp/cp-tree.h
gcc/cp/lex.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/testsuite/g++.dg/template/ttp1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typename1.C [new file with mode: 0644]

index 58e1f98..2b1b453 100644 (file)
@@ -1,5 +1,21 @@
 2001-10-12  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
+       * 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  <lerdsuwa@users.sourceforge.net>
+
        * pt.c (determine_specialization): Ignore functions without
        DECL_TEMPLATE_INFO.
 
index 4f6bcab..34ef95a 100644 (file)
@@ -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<T>'.  */
-#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 *, ...))
index 57daab4..ec44566 100644 (file)
@@ -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;
index 229bccc..cd68629 100644 (file)
@@ -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);
index f543f0d..4c3249b 100644 (file)
@@ -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 (file)
index 0000000..7b32302
--- /dev/null
@@ -0,0 +1,9 @@
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+// { dg-do compile }
+
+template <template <typename T> class A >
+class B : virtual A<void>
+{
+       typedef int INT;
+       INT i;
+};
diff --git a/gcc/testsuite/g++.dg/template/typename1.C b/gcc/testsuite/g++.dg/template/typename1.C
new file mode 100644 (file)
index 0000000..86658c5
--- /dev/null
@@ -0,0 +1,9 @@
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+// { dg-do compile }
+
+template <class T>
+class B : virtual T::A
+{
+       typedef int INT;
+       INT i;
+};