Commit fd9aef9d by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/9447 (using Base<T>::member does not work)

cp:
	PR c++/9447
	* cp-tree.def (USING_DECL): Document its type.
	* class.c (pushclass): If we're entering a template, push any
	dependent using decls it has.
	* decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
	a dependent scope.
	* pt.c (tsubst_decl) <USING_DECL case>: Set type.
	(tsubst): Remove USING_DECL checks.
	(type_dependent_expression_p): Remove USING_DECL case.
	* semantics.c (finish_member_declaration): A USING_DECL's type
	indicates whether it is dependent.
testsuite:
	PR c++/9447
	* g++.dg/template/using7.C: New test.

From-SVN: r70107
parent 49634b3a
2003-08-02 Nathan Sidwell <nathan@codesourcery.com> 2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
PR c++/9447
* cp-tree.def (USING_DECL): Document its type.
* class.c (pushclass): If we're entering a template, push any
dependent using decls it has.
* decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
a dependent scope.
* pt.c (tsubst_decl) <USING_DECL case>: Set type.
(tsubst): Remove USING_DECL checks.
(type_dependent_expression_p): Remove USING_DECL case.
* semantics.c (finish_member_declaration): A USING_DECL's type
indicates whether it is dependent.
2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (pushclass): Remove unneeded parameter. * cp-tree.h (pushclass): Remove unneeded parameter.
* class.c (pushclass): Remove unneeded MODIFY parm. Adjust. * class.c (pushclass): Remove unneeded MODIFY parm. Adjust.
(push_nested_class): Adjust pushclass call. (push_nested_class): Adjust pushclass call.
......
...@@ -5457,7 +5457,21 @@ pushclass (tree type) ...@@ -5457,7 +5457,21 @@ pushclass (tree type)
pushlevel_class (); pushlevel_class ();
if (type != previous_class_type || current_class_depth > 1) if (type != previous_class_type || current_class_depth > 1)
push_class_decls (type); {
push_class_decls (type);
if (CLASSTYPE_IS_TEMPLATE (type))
{
/* If we are entering the scope of a template (not a
specialization), we need to push all the using decls with
dependent scope too. */
tree fields;
for (fields = TYPE_FIELDS (type);
fields; fields = TREE_CHAIN (fields))
if (TREE_CODE (fields) == USING_DECL && !TREE_TYPE (fields))
pushdecl_class_level (fields);
}
}
else else
{ {
tree item; tree item;
......
...@@ -195,7 +195,9 @@ DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0) ...@@ -195,7 +195,9 @@ DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0)
DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0) DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
/* A using declaration. DECL_INITIAL contains the specified scope. /* A using declaration. DECL_INITIAL contains the specified scope.
This is not an alias, but is later expanded into multiple aliases. */ This is not an alias, but is later expanded into multiple aliases.
The decl will have a NULL_TYPE iff the scope is a dependent scope,
otherwise it will have a void type. */
DEFTREECODE (USING_DECL, "using_decl", 'd', 0) DEFTREECODE (USING_DECL, "using_decl", 'd', 0)
/* A using directive. The operand is USING_STMT_NAMESPACE. */ /* A using directive. The operand is USING_STMT_NAMESPACE. */
......
...@@ -11632,7 +11632,8 @@ grokdeclarator (tree declarator, ...@@ -11632,7 +11632,8 @@ grokdeclarator (tree declarator,
inlinep, friendp, raises != NULL_TREE); inlinep, friendp, raises != NULL_TREE);
} }
} }
else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) else if (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
{ {
tree original_name; tree original_name;
int publicp = 0; int publicp = 0;
......
...@@ -4045,8 +4045,8 @@ do_local_using_decl (tree decl) ...@@ -4045,8 +4045,8 @@ do_local_using_decl (tree decl)
tree tree
do_class_using_decl (tree decl) do_class_using_decl (tree decl)
{ {
tree name, value; tree name, value, scope, type;
if (TREE_CODE (decl) != SCOPE_REF if (TREE_CODE (decl) != SCOPE_REF
|| !TREE_OPERAND (decl, 0) || !TREE_OPERAND (decl, 0)
|| !TYPE_P (TREE_OPERAND (decl, 0))) || !TYPE_P (TREE_OPERAND (decl, 0)))
...@@ -4054,50 +4054,44 @@ do_class_using_decl (tree decl) ...@@ -4054,50 +4054,44 @@ do_class_using_decl (tree decl)
error ("using-declaration for non-member at class scope"); error ("using-declaration for non-member at class scope");
return NULL_TREE; return NULL_TREE;
} }
scope = TREE_OPERAND (decl, 0);
name = TREE_OPERAND (decl, 1); name = TREE_OPERAND (decl, 1);
if (TREE_CODE (name) == BIT_NOT_EXPR) if (TREE_CODE (name) == BIT_NOT_EXPR)
{ {
error ("using-declaration for destructor"); error ("using-declaration cannot name destructor");
return NULL_TREE; return NULL_TREE;
} }
else if (TREE_CODE (name) == TEMPLATE_ID_EXPR) else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{ {
name = TREE_OPERAND (name, 0); template_id_error:;
error ("a using-declaration cannot specify a template-id. Try `using %T::%D'", TREE_OPERAND (decl, 0), name);
error ("a using-declaration cannot specify a template-id");
return NULL_TREE; return NULL_TREE;
} }
if (TREE_CODE (name) == TYPE_DECL) if (TREE_CODE (name) == TYPE_DECL)
{ {
tree type = TREE_TYPE (name);
if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name))) if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name)))
{ goto template_id_error;
name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
error ("a using-declaration cannot specify a template-id.");
return NULL_TREE;
}
name = DECL_NAME (name); name = DECL_NAME (name);
} }
else if (TREE_CODE (name) == TEMPLATE_DECL) else if (TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name); name = DECL_NAME (name);
else if (BASELINK_P (name)) else if (BASELINK_P (name))
{ {
tree fns; tree fns = BASELINK_FUNCTIONS (name);
fns = BASELINK_FUNCTIONS (name);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
{ goto template_id_error;
fns = TREE_OPERAND (fns, 0);
error ("a using-declaration cannot specify a template-id. Try `using %T::%D'",
BASELINK_ACCESS_BINFO (name),
DECL_NAME (get_first_fn (fns)));
}
name = DECL_NAME (get_first_fn (fns)); name = DECL_NAME (get_first_fn (fns));
} }
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
value = build_lang_decl (USING_DECL, name, NULL_TREE); /* Dependent using decls have a NULL type, non-dependent ones have a
DECL_INITIAL (value) = TREE_OPERAND (decl, 0); void type. */
type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
value = build_lang_decl (USING_DECL, name, type);
DECL_INITIAL (value) = scope;
return value; return value;
} }
......
...@@ -6093,6 +6093,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) ...@@ -6093,6 +6093,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
case USING_DECL: case USING_DECL:
{ {
r = copy_node (t); r = copy_node (t);
/* It is not a dependent using decl any more. */
TREE_TYPE (r) = void_type_node;
DECL_INITIAL (r) DECL_INITIAL (r)
= tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
TREE_CHAIN (r) = NULL_TREE; TREE_CHAIN (r) = NULL_TREE;
...@@ -6403,15 +6405,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -6403,15 +6405,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else else
type = TREE_TYPE (t); type = TREE_TYPE (t);
my_friendly_assert (type != unknown_type_node my_friendly_assert (type != unknown_type_node, 20030716);
|| TREE_CODE (t) == USING_DECL, 20030716);
if (type && TREE_CODE (t) != FUNCTION_DECL if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE && TREE_CODE (t) != TYPENAME_TYPE
&& TREE_CODE (t) != TEMPLATE_DECL && TREE_CODE (t) != TEMPLATE_DECL
&& TREE_CODE (t) != IDENTIFIER_NODE && TREE_CODE (t) != IDENTIFIER_NODE
&& TREE_CODE (t) != FUNCTION_TYPE && TREE_CODE (t) != FUNCTION_TYPE
&& TREE_CODE (t) != USING_DECL
&& TREE_CODE (t) != METHOD_TYPE) && TREE_CODE (t) != METHOD_TYPE)
type = tsubst (type, args, complain, in_decl); type = tsubst (type, args, complain, in_decl);
if (type == error_mark_node) if (type == error_mark_node)
...@@ -11623,8 +11623,6 @@ type_dependent_expression_p (tree expression) ...@@ -11623,8 +11623,6 @@ type_dependent_expression_p (tree expression)
if (TREE_TYPE (expression) == unknown_type_node) if (TREE_TYPE (expression) == unknown_type_node)
{ {
if (TREE_CODE (expression) == USING_DECL)
return true;
if (TREE_CODE (expression) == ADDR_EXPR) if (TREE_CODE (expression) == ADDR_EXPR)
return type_dependent_expression_p (TREE_OPERAND (expression, 0)); return type_dependent_expression_p (TREE_OPERAND (expression, 0));
if (TREE_CODE (expression) == BASELINK) if (TREE_CODE (expression) == BASELINK)
......
...@@ -2099,8 +2099,7 @@ finish_member_declaration (tree decl) ...@@ -2099,8 +2099,7 @@ finish_member_declaration (tree decl)
/*friend_p=*/0); /*friend_p=*/0);
} }
/* Enter the DECL into the scope of the class. */ /* Enter the DECL into the scope of the class. */
else if ((TREE_CODE (decl) == USING_DECL && !processing_template_decl else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))
&& !dependent_type_p (DECL_INITIAL (decl)))
|| pushdecl_class_level (decl)) || pushdecl_class_level (decl))
{ {
/* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
......
2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
PR c++/9447
* g++.dg/template/using7.C: New test.
2003-08-02 Neil Booth <neil@daikokuya.co.uk> 2003-08-02 Neil Booth <neil@daikokuya.co.uk>
* import1.c, import2.c: New tests. * import1.c, import2.c: New tests.
......
// { dg-do compile }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 Aug 2003 <nathan@codesourcery.com>
// PR 9447. Using decls in reopened template classes.
template <typename> struct A { int i; };
template <typename T> struct B : public A<T>
{
using A<T>::i;
int foo() const;
};
struct C {};
template <typename T> int B<T>::foo() const
{
return i;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment