OSDN Git Service

Friend class name lookup 5/n
authorlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Mar 2005 14:33:54 +0000 (14:33 +0000)
committerlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Mar 2005 14:33:54 +0000 (14:33 +0000)
PR c++/1016
* cp-tree.h (pushtag): Adjust declaration.
* decl.c (lookup_and_check_tag): Call lookup_type_scope if
lookup_name fails.
(xref_tag): Adjust call to pushtag.  Make hidden class visible.
(start_enum): Adjust call to pushtag.
* name-lookup.c (ambiguous_decl): Ignore hidden names.
(qualify_lookup): Change return type to bool.
(hidden_name_p): New function.
(lookup_namespace_name, unqualified_namespace_lookup,
lookup_name_real): Use it.
(lookup_type_scope): Update comments.
(maybe_process_template_type_declaration): Change parameter name
from globalize to is_friend.
(pushtag): Change globalize parameter of type int to tag_scope.
Hide name if introduced by friend declaration.
* name-lookup.h (hidden_name_p): Add declaration.
* parser.c (cp_parser_lookup_name): Don't deal with hidden name
here.
* pt.c (push_template_decl_real): Make hidden class template
visible.
(lookup_template_class, instantiate_class_template): Adjust call
to pushtag.
* semantics.c (begin_class_definition): Likewise.
* rtti.c (init_rtti_processing, build_dynamic_cast_1,
tinfo_base_init, emit_support_tinfos): Use ts_current instead of
ts_global.

* g++.dg/lookup/hidden-class1.C: New test.
* g++.dg/lookup/hidden-class2.C: Likewise.
* g++.dg/lookup/hidden-class3.C: Likewise.
* g++.dg/lookup/hidden-class4.C: Likewise.
* g++.dg/lookup/hidden-class5.C: Likewise.
* g++.dg/lookup/hidden-class6.C: Likewise.
* g++.dg/lookup/hidden-class7.C: Likewise.
* g++.dg/lookup/hidden-class8.C: Likewise.
* g++.dg/lookup/hidden-class9.C: Likewise.
* g++.dg/lookup/hidden-temp-class1.C: Likewise.
* g++.dg/lookup/hidden-temp-class2.C: Likewise.
* g++.dg/lookup/hidden-temp-class3.C: Likewise.
* g++.dg/lookup/hidden-temp-class4.C: Likewise.
* g++.dg/lookup/hidden-temp-class5.C: Likewise.
* g++.dg/lookup/hidden-temp-class6.C: Likewise.
* g++.dg/lookup/hidden-temp-class7.C: Likewise.
* g++.dg/lookup/hidden-temp-class8.C: Likewise.
* g++.dg/lookup/hidden-temp-class9.C: Likewise.
* g++.dg/lookup/hidden-temp-class10.C: Likewise.
* g++.dg/lookup/hidden-temp-class11.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96430 138bc75d-0d04-0410-961f-82ee72b054a4

30 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/hidden-class1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-class9.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C [new file with mode: 0644]

index fefffd8..e2a7de3 100644 (file)
@@ -1,3 +1,34 @@
+2005-03-14  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       Friend class name lookup 5/n
+       PR c++/1016
+       * cp-tree.h (pushtag): Adjust declaration.
+       * decl.c (lookup_and_check_tag): Call lookup_type_scope if
+       lookup_name fails.
+       (xref_tag): Adjust call to pushtag.  Make hidden class visible.
+       (start_enum): Adjust call to pushtag.
+       * name-lookup.c (ambiguous_decl): Ignore hidden names.
+       (qualify_lookup): Change return type to bool.
+       (hidden_name_p): New function.
+       (lookup_namespace_name, unqualified_namespace_lookup,
+       lookup_name_real): Use it.
+       (lookup_type_scope): Update comments.
+       (maybe_process_template_type_declaration): Change parameter name
+       from globalize to is_friend.
+       (pushtag): Change globalize parameter of type int to tag_scope.
+       Hide name if introduced by friend declaration.
+       * name-lookup.h (hidden_name_p): Add declaration.
+       * parser.c (cp_parser_lookup_name): Don't deal with hidden name
+       here.
+       * pt.c (push_template_decl_real): Make hidden class template
+       visible.
+       (lookup_template_class, instantiate_class_template): Adjust call
+       to pushtag.
+       * semantics.c (begin_class_definition): Likewise.
+       * rtti.c (init_rtti_processing, build_dynamic_cast_1, 
+       tinfo_base_init, emit_support_tinfos): Use ts_current instead of
+       ts_global.
+
 2005-03-13  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/20157
index aef5637..640d4dd 100644 (file)
@@ -3761,7 +3761,7 @@ extern void maybe_push_cleanup_level (tree);
 extern void finish_scope                        (void);
 extern void push_switch                                (tree);
 extern void pop_switch                         (void);
-extern tree pushtag                            (tree, tree, int);
+extern tree pushtag                            (tree, tree, tag_scope);
 extern tree make_anon_name                     (void);
 extern int decls_match                         (tree, tree);
 extern tree duplicate_decls                    (tree, tree);
index dee5c46..4e350c3 100644 (file)
@@ -9082,7 +9082,6 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           void f(class C);             // No template header here
 
         then the required template argument is missing.  */
-
       error ("template argument required for %<%s %T%>",
             tag_name (tag_code),
             DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
@@ -9104,7 +9103,19 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
   tree t;
   tree decl;
   if (scope == ts_global)
-    decl = lookup_name (name, 2);
+    {
+      /* First try ordinary name lookup, ignoring hidden class name
+        injected via friend declaration.  */
+      decl = lookup_name (name, 2);
+      /* If that fails, the name will be placed in the smallest
+        non-class, non-function-prototype scope according to 3.3.1/5.
+        We may already have a hidden name declared as friend in this
+        scope.  So lookup again but not ignoring hidden name.
+        If we find one, that name will be made visible rather than
+        creating a new tag.  */
+      if (!decl)
+       decl = lookup_type_scope (name, ts_within_enclosing_non_class);
+    }
   else
     decl = lookup_type_scope (name, scope);
 
@@ -9264,8 +9275,7 @@ xref_tag (enum tag_types tag_code, tree name,
        {
          t = make_aggr_type (code);
          TYPE_CONTEXT (t) = context;
-         /* pushtag only cares whether SCOPE is zero or not.  */
-         t = pushtag (name, t, scope != ts_current);
+         t = pushtag (name, t, scope);
        }
     }
   else
@@ -9279,6 +9289,20 @@ xref_tag (enum tag_types tag_code, tree name,
          error ("redeclaration of %qT as a non-template", t);
          t = error_mark_node;
        }
+
+      /* Make injected friend class visible.  */
+      if (scope != ts_within_enclosing_non_class
+         && hidden_name_p (TYPE_NAME (t)))
+       {
+         DECL_ANTICIPATED (TYPE_NAME (t)) = 0;
+         DECL_FRIEND_P (TYPE_NAME (t)) = 0;
+
+         if (TYPE_TEMPLATE_INFO (t))
+           {
+             DECL_ANTICIPATED (TYPE_TI_TEMPLATE (t)) = 0;
+             DECL_FRIEND_P (TYPE_TI_TEMPLATE (t)) = 0;
+           }
+       }
     }
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
@@ -9520,7 +9544,7 @@ start_enum (tree name)
        name = make_anon_name ();
 
       enumtype = make_node (ENUMERAL_TYPE);
-      enumtype = pushtag (name, enumtype, 0);
+      enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
   return enumtype;
index e861a66..4a5429c 100644 (file)
@@ -3296,12 +3296,13 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
       case TEMPLATE_DECL:
         /* If we expect types or namespaces, and not templates,
            or this is not a template class.  */
-        if (LOOKUP_QUALIFIERS_ONLY (flags)
-            && !DECL_CLASS_TEMPLATE_P (val))
+        if ((LOOKUP_QUALIFIERS_ONLY (flags)
+            && !DECL_CLASS_TEMPLATE_P (val))
+           || hidden_name_p (val))
           val = NULL_TREE;
         break;
       case TYPE_DECL:
-        if (LOOKUP_NAMESPACES_ONLY (flags))
+        if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
           val = NULL_TREE;
         break;
       case NAMESPACE_DECL:
@@ -3310,7 +3311,7 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
         break;
       case FUNCTION_DECL:
         /* Ignore built-in functions that are still anticipated.  */
-        if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
+        if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
           val = NULL_TREE;
         break;
       default:
@@ -3382,21 +3383,35 @@ lookup_flags (int prefer_type, int namespaces_only)
 }
 
 /* Given a lookup that returned VAL, use FLAGS to decide if we want to
-   ignore it or not.  Subroutine of lookup_name_real.  */
+   ignore it or not.  Subroutine of lookup_name_real and
+   lookup_type_scope.  */
 
-static tree
+static bool
 qualify_lookup (tree val, int flags)
 {
   if (val == NULL_TREE)
-    return val;
+    return false;
   if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
-    return val;
+    return true;
   if ((flags & LOOKUP_PREFER_TYPES)
       && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
-    return val;
+    return true;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
-    return NULL_TREE;
-  return val;
+    return false;
+  return true;
+}
+
+/* Given a lookup that returned VAL, decide if we want to ignore it or 
+   not based on DECL_ANTICIPATED_P.  */
+
+bool
+hidden_name_p (tree val)
+{
+  if (DECL_P (val)
+      && DECL_LANG_SPECIFIC (val)
+      && DECL_ANTICIPATED (val))
+    return true;
+  return false;
 }
 
 /* Look up NAME in the NAMESPACE.  */
@@ -3467,10 +3482,9 @@ lookup_namespace_name (tree namespace, tree name)
       if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
        val = OVL_FUNCTION (val);
 
-      /* Ignore built-in functions that haven't been prototyped yet.  */
-      if (!val || !DECL_P(val)
-          || !DECL_LANG_SPECIFIC(val)
-          || !DECL_ANTICIPATED (val))
+      /* Ignore built-in functions and friends that haven't been declared
+        yet.  */
+      if (!val || !hidden_name_p (val))
         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
     }
 
@@ -3529,10 +3543,8 @@ unqualified_namespace_lookup (tree name, int flags)
 
       if (b)
        {
-         if (b->value && DECL_P (b->value)
-             && DECL_LANG_SPECIFIC (b->value) 
-             && DECL_ANTICIPATED (b->value))
-           /* Ignore anticipated built-in functions.  */
+         if (b->value && hidden_name_p (b->value))
+           /* Ignore anticipated built-in functions and friends.  */
            ;
          else
            binding.value = b->value;
@@ -3773,6 +3785,8 @@ innermost_non_namespace_value (tree name)
    node of some kind representing its definition if there is only one
    such declaration, or return a TREE_LIST with all the overloaded
    definitions if there are many, or return 0 if it is undefined.
+   Hidden name, either friend declaration or built-in function, are
+   not ignored.
 
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
    If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
@@ -3837,10 +3851,12 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
          continue;
        
        /* If this is the kind of thing we're looking for, we're done.  */
-       if (qualify_lookup (iter->value, flags))
+       if (qualify_lookup (iter->value, flags)
+           && !hidden_name_p (iter->value))
          binding = iter->value;
        else if ((flags & LOOKUP_PREFER_TYPES)
-                && qualify_lookup (iter->type, flags))
+                && qualify_lookup (iter->type, flags)
+                && !hidden_name_p (iter->type))
          binding = iter->type;
        else
          binding = NULL_TREE;
@@ -3898,7 +3914,8 @@ lookup_name (tree name, int prefer_type)
    Unlike lookup_name_real, we make sure that NAME is actually
    declared in the desired scope, not from inheritance, nor using
    directive.  For using declaration, there is DR138 still waiting
-   to be resolved.
+   to be resolved.  Hidden name coming from earlier an friend 
+   declaration is also returned.
 
    A TYPE_DECL best matching the NAME is returned.  Catching error
    and issuing diagnostics are caller's responsibility.  */
@@ -3948,9 +3965,7 @@ lookup_type_scope (tree name, tag_scope scope)
 
       if (iter)
        {
-         /* If this is the kind of thing we're looking for, we're done.
-            Ignore names found via using declaration.  See DR138 for
-            current status.  */
+         /* If this is the kind of thing we're looking for, we're done.  */
          if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
            val = iter->type;
          else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
@@ -4500,7 +4515,7 @@ push_using_directive (tree used)
    processing.  */
 
 static tree
-maybe_process_template_type_declaration (tree type, int globalize,
+maybe_process_template_type_declaration (tree type, int is_friend,
                                          cxx_scope *b)
 {
   tree decl = TYPE_NAME (type);
@@ -4523,7 +4538,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
             push_template_decl_real, but we want the original value.  */
          tree name = DECL_NAME (decl);
 
-         decl = push_template_decl_real (decl, globalize);
+         decl = push_template_decl_real (decl, is_friend);
          /* If the current binding level is the binding level for the
             template parameters (see the comment in
             begin_template_parm_list) and the enclosing level is a class
@@ -4532,7 +4547,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
             friend case, push_template_decl will already have put the
             friend into global scope, if appropriate.  */
          if (TREE_CODE (type) != ENUMERAL_TYPE
-             && !globalize && b->kind == sk_template_parms
+             && !is_friend && b->kind == sk_template_parms
              && b->level_chain->kind == sk_class)
            {
              finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
@@ -4563,7 +4578,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
    Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
 
 tree
-pushtag (tree name, tree type, int globalize)
+pushtag (tree name, tree type, tag_scope scope)
 {
   struct cp_binding_level *b;
 
@@ -4580,7 +4595,7 @@ pushtag (tree name, tree type, int globalize)
            template is instantiated.  */
         || (b->kind == sk_template_parms && b->explicit_spec_p)
         || (b->kind == sk_class
-            && (globalize
+            && (scope != ts_current
                 /* We may be defining a new type in the initializer
                    of a static member variable. We allow this when
                    not pedantic, and it is particularly useful for
@@ -4601,7 +4616,7 @@ pushtag (tree name, tree type, int globalize)
            {
              tree cs = current_scope ();
 
-             if (! globalize)
+             if (scope == ts_current)
                context = cs;
              else if (cs != NULL_TREE && TYPE_P (cs))
                /* When declaring a friend class of a local class, we want
@@ -4622,11 +4637,21 @@ pushtag (tree name, tree type, int globalize)
 
          d = create_implicit_typedef (name, type);
          DECL_CONTEXT (d) = FROB_CONTEXT (context);
+         if (scope == ts_within_enclosing_non_class)
+           {
+             /* This is a friend.  Make this TYPE_DECL node hidden from
+                ordinary name lookup.  Its corresponding TEMPLATE_DECL
+                will be marked in push_template_decl_real.  */
+             retrofit_lang_decl (d);
+             DECL_ANTICIPATED (d) = 1;
+             DECL_FRIEND_P (d) = 1;
+           }
+
          if (! in_class)
            set_identifier_type_value_with_scope (name, d, b);
 
-         d = maybe_process_template_type_declaration (type,
-                                                      globalize, b);
+         d = maybe_process_template_type_declaration
+               (type, scope == ts_within_enclosing_non_class, b);
          if (d == error_mark_node)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
index e443319..451e6ec 100644 (file)
@@ -315,6 +315,7 @@ extern tree lookup_name_real (tree, int, int, bool, int, int);
 extern tree lookup_type_scope (tree, tag_scope);
 extern tree namespace_binding (tree, tree);
 extern void set_namespace_binding (tree, tree, tree);
+extern bool hidden_name_p (tree);
 extern tree lookup_namespace_name (tree, tree);
 extern tree lookup_qualified_name (tree, tree, bool, bool);
 extern tree lookup_name_nonclass (tree);
index 6fb9fca..2b6c03b 100644 (file)
@@ -14382,10 +14382,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
     }
 
   /* If the lookup failed, let our caller know.  */
-  if (!decl
-      || decl == error_mark_node
-      || (TREE_CODE (decl) == FUNCTION_DECL
-         && DECL_ANTICIPATED (decl)))
+  if (!decl || decl == error_mark_node)
     return error_mark_node;
 
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
index c9d2f96..1147f79 100644 (file)
@@ -3132,6 +3132,13 @@ push_template_decl_real (tree decl, int is_friend)
       tmpl = pushdecl_namespace_level (tmpl);
       if (tmpl == error_mark_node)
        return error_mark_node;
+
+      /* Hide template friend classes that haven't been declared yet.  */
+      if (is_friend && TREE_CODE (decl) == TYPE_DECL)
+       {
+         DECL_ANTICIPATED (tmpl) = 1;
+         DECL_FRIEND_P (tmpl) = 1;
+       }
     }
 
   if (primary)
@@ -4629,7 +4636,7 @@ lookup_template_class (tree d1,
 
          /* A local class.  Make sure the decl gets registered properly.  */
          if (context == current_function_decl)
-           pushtag (DECL_NAME (template), t, 0);
+           pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current);
        }
 
       /* If we called start_enum or pushtag above, this information
@@ -5679,7 +5686,7 @@ instantiate_class_template (tree type)
                     tsubst_enum.  */
                  if (name)
                    SET_IDENTIFIER_TYPE_VALUE (name, newtag);
-                 pushtag (name, newtag, /*globalize=*/0);
+                 pushtag (name, newtag, /*tag_scope=*/ts_current);
                }
            }
          else if (TREE_CODE (t) == FUNCTION_DECL 
index a08a3ee..45f0b08 100644 (file)
@@ -113,7 +113,7 @@ init_rtti_processing (void)
   
   push_namespace (std_identifier);
   type_info_type = xref_tag (class_type, get_identifier ("type_info"),
-                            /*tag_scope=*/ts_global, false);
+                            /*tag_scope=*/ts_current, false);
   pop_namespace ();
   const_type_info_type_node
     = build_qualified_type (type_info_type, TYPE_QUAL_CONST);
@@ -624,7 +624,7 @@ build_dynamic_cast_1 (tree type, tree expr)
              push_nested_namespace (ns);
              tinfo_ptr = xref_tag (class_type,
                                    get_identifier ("__class_type_info"),
-                                   /*tag_scope=*/ts_global, false);
+                                   /*tag_scope=*/ts_current, false);
              
              tinfo_ptr = build_pointer_type
                (build_qualified_type
@@ -805,7 +805,7 @@ tinfo_base_init (tree desc, tree target)
   
       push_nested_namespace (abi_node);
       real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
-                           /*tag_scope=*/ts_global, false);
+                           /*tag_scope=*/ts_current, false);
       pop_nested_namespace (abi_node);
   
       if (!COMPLETE_TYPE_P (real_type))
@@ -1337,7 +1337,7 @@ emit_support_tinfos (void)
   push_nested_namespace (abi_node);
   bltn_type = xref_tag (class_type,
                        get_identifier ("__fundamental_type_info"), 
-                       /*tag_scope=*/ts_global, false);
+                       /*tag_scope=*/ts_current, false);
   pop_nested_namespace (abi_node);
   if (!COMPLETE_TYPE_P (bltn_type))
     return;
index 2daff6f..15762cb 100644 (file)
@@ -2122,7 +2122,7 @@ begin_class_definition (tree t)
   if (t == error_mark_node || ! IS_AGGR_TYPE (t))
     {
       t = make_aggr_type (RECORD_TYPE);
-      pushtag (make_anon_name (), t, 0);
+      pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
     }
 
   /* Update the location of the decl.  */
@@ -2131,7 +2131,7 @@ begin_class_definition (tree t)
   if (TYPE_BEING_DEFINED (t))
     {
       t = make_aggr_type (TREE_CODE (t));
-      pushtag (TYPE_IDENTIFIER (t), t, 0);
+      pushtag (TYPE_IDENTIFIER (t), t, /*tag_scope=*/ts_current);
     }
   maybe_process_partial_specialization (t);
   pushclass (t);
index 1b6603f..993b95b 100644 (file)
@@ -1,3 +1,28 @@
+2005-03-14  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       Friend class name lookup 5/n
+       PR c++/1016
+       * g++.dg/lookup/hidden-class1.C: New test.
+       * g++.dg/lookup/hidden-class2.C: Likewise.
+       * g++.dg/lookup/hidden-class3.C: Likewise.
+       * g++.dg/lookup/hidden-class4.C: Likewise.
+       * g++.dg/lookup/hidden-class5.C: Likewise.
+       * g++.dg/lookup/hidden-class6.C: Likewise.
+       * g++.dg/lookup/hidden-class7.C: Likewise.
+       * g++.dg/lookup/hidden-class8.C: Likewise.
+       * g++.dg/lookup/hidden-class9.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class1.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class2.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class3.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class4.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class5.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class6.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class7.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class8.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class9.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class10.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class11.C: Likewise.
+
 2005-03-13  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/20157
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-class1.C
new file mode 100644 (file)
index 0000000..fc71e96
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+  B *b;                // { dg-error "no type|expected" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class2.C b/gcc/testsuite/g++.dg/lookup/hidden-class2.C
new file mode 100644 (file)
index 0000000..19287a5
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+};
+
+class B* b;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class3.C b/gcc/testsuite/g++.dg/lookup/hidden-class3.C
new file mode 100644 (file)
index 0000000..50a7e33
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+
+  class B;
+  B *b;
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class4.C b/gcc/testsuite/g++.dg/lookup/hidden-class4.C
new file mode 100644 (file)
index 0000000..c407692
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+};
+
+class B *b;
+B *c;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class5.C b/gcc/testsuite/g++.dg/lookup/hidden-class5.C
new file mode 100644 (file)
index 0000000..1cf06bc
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+};
+
+B* b;          // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class6.C b/gcc/testsuite/g++.dg/lookup/hidden-class6.C
new file mode 100644 (file)
index 0000000..9642535
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+// Origin: Jay Cox <jaycox@gimp.org>
+
+// PR c++/1016: Name lookup for injected friend class
+
+class B;
+
+namespace N {
+  class A {
+    friend class B;
+    B* b;
+  };
+}
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-class7.C
new file mode 100644 (file)
index 0000000..f681cd6
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+};
+
+class C {
+  friend class B;
+};
+
+B *b;          // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class8.C b/gcc/testsuite/g++.dg/lookup/hidden-class8.C
new file mode 100644 (file)
index 0000000..ea4e2f1
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+  class A {
+    friend class B;
+  };
+}
+
+class N::B {   // { dg-error "not name a class" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class9.C b/gcc/testsuite/g++.dg/lookup/hidden-class9.C
new file mode 100644 (file)
index 0000000..de86b12
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+  class A {
+    friend class B;
+  };
+}
+
+using N::B;    // { dg-error "declared" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
new file mode 100644 (file)
index 0000000..c92b7f6
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+  B<int> *b;   // { dg-error "no type|expected" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C
new file mode 100644 (file)
index 0000000..2134635
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+  class A {
+    template <class T> friend class B;
+  };
+}
+
+template <class T> class N::B {        // { dg-error "not name a class" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C
new file mode 100644 (file)
index 0000000..6e8cbdb
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+  class A {
+    template <class T> friend class B;
+  };
+}
+
+using N::B;    // { dg-error "declared" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C
new file mode 100644 (file)
index 0000000..56ba76b
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+};
+
+class B* b;    // { dg-error "argument required|invalid" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C
new file mode 100644 (file)
index 0000000..3f96622
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+  template <class T> class B;
+  B<int> *b;
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
new file mode 100644 (file)
index 0000000..02dc9c3
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+};
+
+B<int> *b;     // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C
new file mode 100644 (file)
index 0000000..e6b30b2
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+};
+
+template <class T> class B;
+B<int>* b;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C
new file mode 100644 (file)
index 0000000..2072695
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class B;
+namespace N {
+  class A {
+    template <class T> friend class B;
+    B* b;
+  };
+}
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
new file mode 100644 (file)
index 0000000..22804d7
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+};
+
+class C {
+  template <class T> friend class B;
+};
+
+B<int> *b;     // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C
new file mode 100644 (file)
index 0000000..247c78c
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  template <class T> friend class B;
+};
+
+class C {
+  friend class B;      // { dg-error "argument required|friend" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C
new file mode 100644 (file)
index 0000000..783139b
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+  friend class B;
+};
+
+class C {
+  template <class T> friend class B;   // { dg-error "not a template" }
+};