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>
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.
* class.c (pushclass): Remove unneeded MODIFY parm. Adjust.
(push_nested_class): Adjust pushclass call.
......
......@@ -5457,7 +5457,21 @@ pushclass (tree type)
pushlevel_class ();
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
{
tree item;
......
......@@ -195,7 +195,9 @@ DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0)
DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
/* 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)
/* A using directive. The operand is USING_STMT_NAMESPACE. */
......
......@@ -11632,7 +11632,8 @@ grokdeclarator (tree declarator,
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;
int publicp = 0;
......
......@@ -4045,8 +4045,8 @@ do_local_using_decl (tree decl)
tree
do_class_using_decl (tree decl)
{
tree name, value;
tree name, value, scope, type;
if (TREE_CODE (decl) != SCOPE_REF
|| !TREE_OPERAND (decl, 0)
|| !TYPE_P (TREE_OPERAND (decl, 0)))
......@@ -4054,50 +4054,44 @@ do_class_using_decl (tree decl)
error ("using-declaration for non-member at class scope");
return NULL_TREE;
}
scope = TREE_OPERAND (decl, 0);
name = TREE_OPERAND (decl, 1);
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
error ("using-declaration for destructor");
error ("using-declaration cannot name destructor");
return NULL_TREE;
}
else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
name = TREE_OPERAND (name, 0);
error ("a using-declaration cannot specify a template-id. Try `using %T::%D'", TREE_OPERAND (decl, 0), name);
template_id_error:;
error ("a using-declaration cannot specify a template-id");
return NULL_TREE;
}
if (TREE_CODE (name) == TYPE_DECL)
{
tree type = TREE_TYPE (name);
if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name)))
{
name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
error ("a using-declaration cannot specify a template-id.");
return NULL_TREE;
}
goto template_id_error;
name = DECL_NAME (name);
}
else if (TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name);
else if (BASELINK_P (name))
{
tree fns;
fns = BASELINK_FUNCTIONS (name);
tree fns = BASELINK_FUNCTIONS (name);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
{
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)));
}
goto template_id_error;
name = DECL_NAME (get_first_fn (fns));
}
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
value = build_lang_decl (USING_DECL, name, NULL_TREE);
DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
/* Dependent using decls have a NULL type, non-dependent ones have a
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;
}
......
......@@ -6093,6 +6093,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
case USING_DECL:
{
r = copy_node (t);
/* It is not a dependent using decl any more. */
TREE_TYPE (r) = void_type_node;
DECL_INITIAL (r)
= tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
TREE_CHAIN (r) = NULL_TREE;
......@@ -6403,15 +6405,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
type = TREE_TYPE (t);
my_friendly_assert (type != unknown_type_node
|| TREE_CODE (t) == USING_DECL, 20030716);
my_friendly_assert (type != unknown_type_node, 20030716);
if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE
&& TREE_CODE (t) != TEMPLATE_DECL
&& TREE_CODE (t) != IDENTIFIER_NODE
&& TREE_CODE (t) != FUNCTION_TYPE
&& TREE_CODE (t) != USING_DECL
&& TREE_CODE (t) != METHOD_TYPE)
type = tsubst (type, args, complain, in_decl);
if (type == error_mark_node)
......@@ -11623,8 +11623,6 @@ type_dependent_expression_p (tree expression)
if (TREE_TYPE (expression) == unknown_type_node)
{
if (TREE_CODE (expression) == USING_DECL)
return true;
if (TREE_CODE (expression) == ADDR_EXPR)
return type_dependent_expression_p (TREE_OPERAND (expression, 0));
if (TREE_CODE (expression) == BASELINK)
......
......@@ -2099,8 +2099,7 @@ finish_member_declaration (tree decl)
/*friend_p=*/0);
}
/* Enter the DECL into the scope of the class. */
else if ((TREE_CODE (decl) == USING_DECL && !processing_template_decl
&& !dependent_type_p (DECL_INITIAL (decl)))
else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))
|| pushdecl_class_level (decl))
{
/* 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>
* 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