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);
}
}
return t;
}
-/* Given a TYPE_DECL T looked up in CONTEXT, return a TYPENAME_TYPE
- 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. */
-
-static tree
-make_implicit_typename (context, t)
- tree context, 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);
- return retval;
-}
-
/* Look up NAME in the current binding level and its superiors in the
namespace of variables, functions and typedefs. Return a ..._DECL
node of some kind representing its definition if there is only one
else
val = NULL_TREE;
- /* Add implicit 'typename' to scoped types from other classes. */
- if (got_scope && processing_template_decl
- && got_scope != current_class_type
- && uses_template_parms (got_scope)
- && val && TREE_CODE (val) == TYPE_DECL
- && ! DECL_ARTIFICIAL (val))
- {
- tree t = make_implicit_typename (got_scope, val);
- val = TYPE_MAIN_DECL (t);
- }
-
if (got_scope)
goto done;
else if (got_object && val)
if (classval == NULL_TREE)
classval = lookup_nested_field (name, ! yylex);
- /* Add implicit 'typename' to types from base classes. */
+ /* Add implicit 'typename' to types from template bases. lookup_field
+ will do this for us. */
if (processing_template_decl
&& classval && TREE_CODE (classval) == TYPE_DECL
&& DECL_CONTEXT (classval) != current_class_type
- && uses_template_parms (DECL_CONTEXT (classval))
+ && uses_template_parms (current_class_type)
&& ! DECL_ARTIFICIAL (classval))
- {
- tree t = make_implicit_typename (current_class_type, classval);
- classval = TYPE_MAIN_DECL (t);
- }
+ classval = lookup_field (current_class_type, name, 0, 1);
}
if (locval && classval)
}
}
- if (entry)
- {
- if (errstr)
- {
- /* This depends on behavior of lookup_field_1! */
- tree error_string = my_build_string (errstr);
- TREE_TYPE (entry) = error_string;
- }
- else
- {
- /* Let entry know there is no problem with this access. */
- TREE_TYPE (entry) = NULL_TREE;
- }
- TREE_VALUE (entry) = rval;
- }
-
- if (errstr && protect)
- {
- cp_error (errstr, name, type);
- return error_mark_node;
- }
- return rval;
+ rval_binfo = basetype_path;
+ goto out;
}
basetype_chain = build_expr_list (NULL_TREE, basetype_path);
: "member `%D' is from protected base class";
}
+ out:
if (entry)
{
if (errstr)
cp_error (errstr, name, type);
rval = error_mark_node;
}
+
+ /* Do implicit typename stuff. */
+ if (rval && TREE_CODE (rval) == TYPE_DECL
+ && ! DECL_ARTIFICIAL (rval)
+ && processing_template_decl
+ && BINFO_TYPE (rval_binfo) != current_class_type
+ && uses_template_parms (type))
+ {
+ binfo = rval_binfo;
+ for (; ; binfo = BINFO_INHERITANCE_CHAIN (binfo))
+ if (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE
+ || (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo))
+ == current_class_type))
+ break;
+
+ entry = make_typename_type (BINFO_TYPE (binfo), name);
+ TREE_TYPE (entry) = TREE_TYPE (rval);
+ rval = TYPE_MAIN_DECL (entry);
+ }
+
return rval;
}