decl.c (make_implicit_typename): Rewrite removed code.
authorJason Merrill <jason@yorick.cygnus.com>
Fri, 20 Mar 1998 11:43:36 +0000 (11:43 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 20 Mar 1998 11:43:36 +0000 (06:43 -0500)
* decl.c (make_implicit_typename): Rewrite removed code.
(make_typename_type): Call it if the type we look up comes from
a base that uses template parms.

From-SVN: r18725

gcc/cp/ChangeLog
gcc/cp/decl.c

index 6c7d567addde5068a91594c04e3114ccf38d626e..f8862c0644af1922c5926f13cee7f5ac25b7a52f 100644 (file)
@@ -1,5 +1,9 @@
 Fri Mar 20 10:42:07 1998  Jason Merrill  <jason@yorick.cygnus.com>
 
+       * decl.c (make_implicit_typename): Rewrite removed code.
+       (make_typename_type): Call it if the type we look up comes from
+       a base that uses template parms.
+
        * pt.c (complete_template_args): Rewrite.
        (tsubst, FUNCTION_DECL): Use it.
 
index 98ffff9d70f7b491a1613a4a526e8ee2b4c1d351..434d84c3cdc65dfc352702b9d3eab8b56f011ee7 100644 (file)
@@ -179,6 +179,7 @@ static void record_builtin_type PROTO((enum rid, char *, tree));
 static int member_function_or_else PROTO((tree, tree, char *));
 static void bad_specifiers PROTO((tree, char *, int, int, int, int,
                                  int));
+static tree make_implicit_typename PROTO((tree, tree));
 
 /* a node which has tree code ERROR_MARK, and whose type is itself.
    All erroneous expressions are replaced with this node.  All functions
@@ -4553,6 +4554,15 @@ make_typename_type (context, name)
              cp_error ("no type named `%#T' in `%#T'", name, context);
              return error_mark_node;
            }
+
+         /* If this is really from a base that uses template parms,
+            push the TYPENAME_TYPE down.  */
+         if (processing_template_decl
+             && context == current_class_type
+             && DECL_CONTEXT (t) != context
+             && uses_template_parms (DECL_CONTEXT (t)))
+           return make_implicit_typename (context, t);
+
          return TREE_TYPE (t);
        }
     }
@@ -4575,7 +4585,8 @@ make_typename_type (context, name)
 }
 
 /* Given a TYPE_DECL T looked up in CONTEXT, return a TYPENAME_TYPE
-   where the scope is CONTEXT.  Also remember what type T refers to.
+   where the scope is the first class along the inheritance chain to T
+   that is not current_class_type.
 
    Called from lookup_name_real to implement the implicit typename
    extension.  */
@@ -4584,7 +4595,32 @@ static tree
 make_implicit_typename (context, t)
      tree context, t;
 {
-  tree retval = make_typename_type (context, DECL_NAME (t));
+  tree retval;
+
+  if (context == current_class_type)
+    {
+      tree binfos = TYPE_BINFO_BASETYPES (context);
+      int n_baselinks = TREE_VEC_LENGTH (binfos);
+      int i;
+
+      /* We can't use DECL_CONTEXT (t) to help us here, because it refers
+        to the uninstantiated template type that t comes from, which is
+        probably not a base of ours.  This happens because we don't
+         actually do partial instantiation of types in
+         instantiate_class_template.  */
+
+      for (i = 0; i < n_baselinks; ++i)
+       {
+         tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
+         if (lookup_field (basetype, DECL_NAME (t), 0, 1))
+           {
+             context = basetype;
+             break;
+           }
+       }
+    }
+
+  retval = make_typename_type (context, DECL_NAME (t));
 
   if (TREE_CODE (retval) == TYPENAME_TYPE)
     TREE_TYPE (retval) = TREE_TYPE (t);