diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2005-03-14 14:33:54 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2005-03-14 14:33:54 +0000 |
commit | bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d (patch) | |
tree | 3d599413959c98f204efab81966efde722599232 | |
parent | a21309013c3bf59f796c2d92a50a85bd0597243c (diff) | |
download | gcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.zip gcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.tar.gz gcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.tar.bz2 |
Friend class name lookup 5/n PR c++/1016
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.
* 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.
From-SVN: r96430
30 files changed, 371 insertions, 51 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fefffd8..e2a7de3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index aef5637..640d4dd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dee5c46..4e350c3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e861a66..4a5429c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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); diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index e443319..451e6ec 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6fb9fca..2b6c03b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c9d2f96..1147f79 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a08a3ee..45f0b08 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2daff6f..15762cb 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b6603f..993b95b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..fc71e96 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class1.C @@ -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 index 0000000..19287a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class2.C @@ -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 index 0000000..50a7e33 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class3.C @@ -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 index 0000000..c407692 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class4.C @@ -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 index 0000000..1cf06bc --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class5.C @@ -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 index 0000000..9642535 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class6.C @@ -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 index 0000000..f681cd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class7.C @@ -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 index 0000000..ea4e2f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class8.C @@ -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 index 0000000..de86b12 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class9.C @@ -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 index 0000000..c92b7f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C @@ -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 index 0000000..2134635 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C @@ -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 index 0000000..6e8cbdb --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C @@ -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 index 0000000..56ba76b --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C @@ -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 index 0000000..3f96622 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C @@ -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 index 0000000..02dc9c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C @@ -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 index 0000000..e6b30b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C @@ -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 index 0000000..2072695 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C @@ -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 index 0000000..22804d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C @@ -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 index 0000000..247c78c --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C @@ -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 index 0000000..783139b --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C @@ -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" } +}; |