+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/109
+ * decl.c (grokdeclarator): Allow friend declarations from
+ dependant types.
+ * decl2.c (handle_class_head): Don't push into template parm contexts.
+ * pt.c (push_template_decl_real): Template parm contexts are never
+ being defined.
+
2002-02-05 Alexandre Oliva <aoliva@redhat.com>
* class.c: Include target.h.
int explicit_char = 0;
int defaulted_int = 0;
int extern_langp = 0;
+ tree dependant_name = NULL_TREE;
tree typedef_decl = NULL_TREE;
const char *name;
else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
|| TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
- error ("`%T::%D' is not a valid declarator", cname,
- TREE_OPERAND (decl, 1));
- error (" perhaps you want `typename %T::%D' to make it a type",
- cname, TREE_OPERAND (decl, 1));
- return void_type_node;
+ /* This might be declaring a member of a template
+ parm to be a friend. */
+ ctype = cname;
+ dependant_name = TREE_OPERAND (decl, 1);
}
else if (ctype == NULL_TREE)
ctype = cname;
friendp = RIDBIT_SETP (RID_FRIEND, specbits);
RIDBIT_RESET (RID_FRIEND, specbits);
+ if (dependant_name && !friendp)
+ {
+ error ("`%T::%D' is not a valid declarator", ctype, dependant_name);
+ return void_type_node;
+ }
+
/* Warn if two storage classes are given. Default to `auto'. */
if (RIDBIT_ANY_SET (specbits))
is different to the current scope. */
tree context = CP_DECL_CONTEXT (decl);
- *new_type_p = current != context;
+ *new_type_p = (current != context
+ && TREE_CODE (context) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
if (*new_type_p)
push_scope (context);
if (!ctx
|| TREE_CODE (ctx) == FUNCTION_DECL
- || TYPE_BEING_DEFINED (ctx)
+ || (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM
+ && TYPE_BEING_DEFINED (ctx))
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
{
if (DECL_LANG_SPECIFIC (decl)
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.dg/template/friend4.C: New test.
+
2002-02-07 David Billinghurst <David.Billinghurst@riotinto.com>
PR fortran/3743
--- /dev/null
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 18 Dec 2001 <nathan@codesourcery.com>
+
+// PR 109, dependant member friends
+
+struct B
+{
+ static int foo ();
+ struct N
+ {
+ static int bar ();
+ };
+};
+
+
+template <class T>
+class A
+{
+ friend int T::foo ();
+ friend int T::N::bar ();
+
+ private:
+ static int m;
+};
+
+template <class T>
+class C
+{
+ friend struct T::N;
+
+ private:
+ static int m;
+};
+
+
+int B::foo ()
+{
+ return A<B>::m;
+}
+
+int B::N::bar ()
+{
+ return A<B>::m + C<B>::m;
+}