diff options
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 40 |
2 files changed, 42 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c7d567addd..f8862c0644a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 98ffff9d70f..434d84c3cdc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); |