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:
parent
4d24a88965
commit
fbfe8c9e5a
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
36
gcc/testsuite/g++.old-deja/g++.pt/using1.C
Normal file
36
gcc/testsuite/g++.old-deja/g++.pt/using1.C
Normal 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> ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user