aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-11-19 02:25:55 +0000
committerMark Mitchell <mark@codesourcery.com>2005-11-19 02:25:55 +0000
commitca87cba0796a5eb92a7d608f77781a40e335b58b (patch)
tree8bd4a3b77c67b5c91f1aed77d26b1a55d7c5ba5d /gcc/cp
parent02a60f10a0f48660b0f05018c65ff637d0147c68 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@107207 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c129
-rw-r--r--gcc/cp/name-lookup.c4
3 files changed, 72 insertions, 68 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42e44da26ba..bd711f3aac1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 30d81a727f5..55e26b97ff6 100644
--- a/gcc/cp/decl.c
+++ b/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. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4302ca6194e..382a8a3a3ea 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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))