Implement using decls inside template functions.

cp:
	Implement using decls inside template functions.
	* decl2.c (validate_nonmember_using_decl): Don't special case
	fake_std_node in the global namespace. Don't reject early when
	processing a template.
	(do_local_using_decl): Add to statement tree. Don't do further
	processing when building a template.
	* pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
testsuite:
	* g++.old-deja/g++.pt/using1.C: New test.

From-SVN: r40151
This commit is contained in:
Nathan Sidwell 2001-03-01 14:01:39 +00:00 committed by Nathan Sidwell
parent 4d24a88965
commit fbfe8c9e5a
5 changed files with 66 additions and 11 deletions

View File

@ -1,3 +1,13 @@
2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
Implement using decls inside template functions.
* decl2.c (validate_nonmember_using_decl): Don't special case
fake_std_node in the global namespace. Don't reject early when
processing a template.
(do_local_using_decl): Add to statement tree. Don't do further
processing when building a template.
* pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
* decl2.c (do_nonmember_using_decl): Don't complain if we find

View File

@ -5032,16 +5032,6 @@ validate_nonmember_using_decl (decl, scope, name)
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == fake_std_node)
{
if (namespace_bindings_p ()
&& current_namespace == global_namespace)
/* There's no need for a using declaration at all, here,
since `std' is the same as `::'. We can't just pass this
on because we'll complain later about declaring something
in the same scope as a using declaration with the same
name. We return NULL_TREE which indicates to the caller
that there's no need to do any further processing. */
return NULL_TREE;
*scope = global_namespace;
*name = TREE_OPERAND (decl, 1);
}
@ -5054,7 +5044,8 @@ validate_nonmember_using_decl (decl, scope, name)
A using-declaration for a class member shall be a
member-declaration. */
if (TREE_CODE (*scope) != NAMESPACE_DECL)
if (!processing_template_decl
&& TREE_CODE (*scope) != NAMESPACE_DECL)
{
if (TYPE_P (*scope))
cp_error ("`%T' is not a namespace", *scope);
@ -5212,6 +5203,12 @@ do_local_using_decl (decl)
if (decl == NULL_TREE)
return;
if (building_stmt_tree ()
&& at_function_scope_p ())
add_decl_stmt (decl);
if (processing_template_decl)
return;
oldval = lookup_name_current_level (name);
oldtype = lookup_type_current_level (name);

View File

@ -7299,6 +7299,14 @@ tsubst_expr (t, args, complain, in_decl)
decl = DECL_STMT_DECL (t);
if (TREE_CODE (decl) == LABEL_DECL)
finish_label_decl (DECL_NAME (decl));
else if (TREE_CODE (decl) == USING_DECL)
{
tree scope = DECL_INITIAL (decl);
tree name = DECL_NAME (decl);
scope = tsubst_expr (scope, args, complain, in_decl);
do_local_using_decl (build_nt (SCOPE_REF, scope, name));
}
else
{
init = DECL_INITIAL (decl);

View File

@ -1,3 +1,7 @@
2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/using1.C: New test.
2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/using9.C: New test.

View File

@ -0,0 +1,36 @@
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 26 Feb 2001 <nathan@codesourcery.com>
// Bug 1981. using declarations in namespace scope were not remembered.
namespace A
{
void swap () {}
};
template <class T> void f()
{
using A::swap;
}
template void f<float> ();
namespace B
{
int foo (int) { return 1;}
template <class T> int baz ()
{
using ::foo;
return foo (1);
}
template int baz<float> ();
};
int foo (int) { return 0;}
int main ()
{
return B::baz<float> ();
}