re PR c++/8355 (befriending a template specialization in another namespace)
PR c++/8355 * decl.c (grokfndecl): Set up DECL_TEMPLATE_INFO before calling set_decl_namespace. * name-lookup.c (set_decl_namespace): PR c++/8355 * g++.dg/template/friend39.C: New test. From-SVN: r107207
This commit is contained in:
parent
817f9ef2e5
commit
abc088aad7
5 changed files with 87 additions and 68 deletions
|
@ -1,3 +1,10 @@
|
|||
2005-11-18 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/8355
|
||||
* decl.c (grokfndecl): Set up DECL_TEMPLATE_INFO before calling
|
||||
set_decl_namespace.
|
||||
* name-lookup.c (set_decl_namespace):
|
||||
|
||||
2005-11-18 Mike Stump <mrs@apple.com>
|
||||
|
||||
* cp-objcp-common.h (LANG_HOOKS_LOOKUP_NAME): Add.
|
||||
|
|
129
gcc/cp/decl.c
129
gcc/cp/decl.c
|
@ -5696,7 +5696,6 @@ grokfndecl (tree ctype,
|
|||
{
|
||||
tree decl;
|
||||
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
|
||||
int has_default_arg = 0;
|
||||
tree t;
|
||||
|
||||
if (raises)
|
||||
|
@ -5708,6 +5707,67 @@ grokfndecl (tree ctype,
|
|||
if (TYPE_VOLATILE (type))
|
||||
TREE_THIS_VOLATILE (decl) = 1;
|
||||
|
||||
if (friendp
|
||||
&& TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
if (funcdef_flag)
|
||||
error
|
||||
("defining explicit specialization %qD in friend declaration",
|
||||
orig_declarator);
|
||||
else
|
||||
{
|
||||
tree fns = TREE_OPERAND (orig_declarator, 0);
|
||||
tree args = TREE_OPERAND (orig_declarator, 1);
|
||||
|
||||
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
|
||||
{
|
||||
/* Something like `template <class T> friend void f<T>()'. */
|
||||
error ("invalid use of template-id %qD in declaration "
|
||||
"of primary template",
|
||||
orig_declarator);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
||||
/* A friend declaration of the form friend void f<>(). Record
|
||||
the information in the TEMPLATE_ID_EXPR. */
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (decl);
|
||||
|
||||
if (TREE_CODE (fns) == COMPONENT_REF)
|
||||
{
|
||||
/* Due to bison parser ickiness, we will have already looked
|
||||
up an operator_name or PFUNCNAME within the current class
|
||||
(see template_id in parse.y). If the current class contains
|
||||
such a name, we'll get a COMPONENT_REF here. Undo that. */
|
||||
|
||||
gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
|
||||
== current_class_type);
|
||||
fns = TREE_OPERAND (fns, 1);
|
||||
}
|
||||
gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (fns) == OVERLOAD);
|
||||
DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
|
||||
|
||||
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
|
||||
if (TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
|
||||
{
|
||||
error ("default arguments are not allowed in declaration "
|
||||
"of friend template specialization %qD",
|
||||
decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (inlinep)
|
||||
{
|
||||
error ("%<inline%> is not allowed in declaration of friend "
|
||||
"template specialization %qD",
|
||||
decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If this decl has namespace scope, set that up. */
|
||||
if (in_namespace)
|
||||
set_decl_namespace (decl, in_namespace, friendp);
|
||||
|
@ -5828,73 +5888,6 @@ grokfndecl (tree ctype,
|
|||
if (ctype && decl_function_context (decl))
|
||||
DECL_NO_STATIC_CHAIN (decl) = 1;
|
||||
|
||||
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
|
||||
if (TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
|
||||
{
|
||||
has_default_arg = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (friendp
|
||||
&& TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
if (funcdef_flag)
|
||||
error
|
||||
("defining explicit specialization %qD in friend declaration",
|
||||
orig_declarator);
|
||||
else
|
||||
{
|
||||
tree fns = TREE_OPERAND (orig_declarator, 0);
|
||||
tree args = TREE_OPERAND (orig_declarator, 1);
|
||||
|
||||
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
|
||||
{
|
||||
/* Something like `template <class T> friend void f<T>()'. */
|
||||
error ("invalid use of template-id %qD in declaration "
|
||||
"of primary template",
|
||||
orig_declarator);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
||||
/* A friend declaration of the form friend void f<>(). Record
|
||||
the information in the TEMPLATE_ID_EXPR. */
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (decl);
|
||||
|
||||
if (TREE_CODE (fns) == COMPONENT_REF)
|
||||
{
|
||||
/* Due to bison parser ickiness, we will have already looked
|
||||
up an operator_name or PFUNCNAME within the current class
|
||||
(see template_id in parse.y). If the current class contains
|
||||
such a name, we'll get a COMPONENT_REF here. Undo that. */
|
||||
|
||||
gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
|
||||
== current_class_type);
|
||||
fns = TREE_OPERAND (fns, 1);
|
||||
}
|
||||
gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (fns) == OVERLOAD);
|
||||
DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
|
||||
|
||||
if (has_default_arg)
|
||||
{
|
||||
error ("default arguments are not allowed in declaration "
|
||||
"of friend template specialization %qD",
|
||||
decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (inlinep)
|
||||
{
|
||||
error ("%<inline%> is not allowed in declaration of friend "
|
||||
"template specialization %qD",
|
||||
decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (funcdef_flag)
|
||||
/* Make the init_value nonzero so pushdecl knows this is not
|
||||
tentative. error_mark_node is replaced later with the BLOCK. */
|
||||
|
|
|
@ -2880,6 +2880,10 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
|||
match. But, we'll check later, when we construct the
|
||||
template. */
|
||||
return;
|
||||
/* Instantiations or specializations of templates may be declared as
|
||||
friends in any namespace. */
|
||||
if (friendp && DECL_USE_TEMPLATE (decl))
|
||||
return;
|
||||
if (is_overloaded_fn (old))
|
||||
{
|
||||
for (; old; old = OVL_NEXT (old))
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
<<<<<<< .mine
|
||||
2005-11-18 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/8355
|
||||
* g++.dg/template/friend39.C: New test.
|
||||
|
||||
=======
|
||||
2005-11-18 James E Wilson <wilson@specifix.com>
|
||||
|
||||
* gcc.dg/builtin-strstr.c: New.
|
||||
|
||||
>>>>>>> .r107206
|
||||
2005-11-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.target/ia64/20010423-1.c, gcc.target/ia64/20020313-1.c,
|
||||
|
|
7
gcc/testsuite/g++.dg/template/friend39.C
Normal file
7
gcc/testsuite/g++.dg/template/friend39.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
// PR c++/8355
|
||||
|
||||
namespace Foo { template <typename T> void foo();}
|
||||
struct Bar
|
||||
{
|
||||
friend void Foo::foo<int>();
|
||||
};
|
Loading…
Add table
Reference in a new issue