aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h59
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/name-lookup.c14
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/friend45.C17
8 files changed, 88 insertions, 39 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 50f8381..a5848b8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2006-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28025
+ * cp-tree.h (LOOKUP_HIDDEN): New macro. Reformat comments.
+ * name-lookup.c (unqualified_namespace_lookup): There is no way to
+ have a hidden name in non-namespace scopes.
+ * pt.c (tsubst_friend_class): Look for hidden names.
+ * decl.c (lookup_and_check_tag): Fix typo in comment.
+
+ * semantics.c (finish_compound_literal): Fix typo in comment.
+
2006-07-21 Jason Merrill <jason@redhat.com>
* decl2.c (determine_visibility): Don't propagate visibility from
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 20e704c..e02d3d7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3380,46 +3380,51 @@ extern GTY(()) tree static_dtors;
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
-/* These are uses as bits in flags passed to build_new_method_call
- to control its error reporting behavior.
-
- LOOKUP_PROTECT means flag access violations.
- LOOKUP_COMPLAIN mean complain if no suitable member function
- matching the arguments is found.
- LOOKUP_NORMAL is just a combination of these two.
- LOOKUP_NONVIRTUAL means make a direct call to the member function found
- LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
- DIRECT_BIND means that if a temporary is created, it should be created so
- that it lives as long as the current variable bindings; otherwise it
- only lives until the end of the complete-expression. It also forces
- direct-initialization in cases where other parts of the compiler have
- already generated a temporary, such as reference initialization and the
- catch parameter.
- LOOKUP_NO_CONVERSION means that user-defined conversions are not
- permitted. Built-in conversions are permitted.
- LOOKUP_DESTRUCTOR means explicit call to destructor.
- LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
-
- These are used in global lookup to support elaborated types and
- qualifiers.
-
- LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
- LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
- LOOKUP_PREFER_BOTH means class-or-namespace-name. */
-
+/* These are uses as bits in flags passed to various functions to
+ control their behavior. Despite the LOOKUP_ prefix, many of these
+ do not control name lookup. ??? Functions using these flags should
+ probably be modified to accept explicit boolean flags for the
+ behaviors relevant to them. */
+/* Check for access violations. */
#define LOOKUP_PROTECT (1 << 0)
+/* Complain if no suitable member function matching the arguments is
+ found. */
#define LOOKUP_COMPLAIN (1 << 1)
#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+/* Even if the function found by lookup is a virtual function, it
+ should be called directly. */
#define LOOKUP_NONVIRTUAL (1 << 2)
+/* Non-converting (i.e., "explicit") constructors are not tried. */
#define LOOKUP_ONLYCONVERTING (1 << 3)
+/* If a temporary is created, it should be created so that it lives
+ as long as the current variable bindings; otherwise it only lives
+ until the end of the complete-expression. It also forces
+ direct-initialization in cases where other parts of the compiler
+ have already generated a temporary, such as reference
+ initialization and the catch parameter. */
#define DIRECT_BIND (1 << 4)
+/* User-defined conversions are not permitted. (Built-in conversions
+ are permitted.) */
#define LOOKUP_NO_CONVERSION (1 << 5)
+/* The user has explicitly called a destructor. (Therefore, we do
+ not need to check that the object is non-NULL before calling the
+ destructor.) */
#define LOOKUP_DESTRUCTOR (1 << 6)
+/* Do not permit references to bind to temporaries. */
#define LOOKUP_NO_TEMP_BIND (1 << 7)
+/* Do not accept objects, and possibly namespaces. */
#define LOOKUP_PREFER_TYPES (1 << 8)
+/* Do not accept objects, and possibly types. */
#define LOOKUP_PREFER_NAMESPACES (1 << 9)
+/* Accept types or namespaces. */
#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+/* We are checking that a constructor can be called -- but we do not
+ actually plan to call it. */
#define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
+/* Return friend decarations and un-declared builtin functions.
+ (Normally, these entities are registered in the symbol table, but
+ not found by lookup.) */
+#define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 78838b0..1497749 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9503,7 +9503,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
/* 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.
+ scope. So lookup again but not ignoring hidden names.
If we find one, that name will be made visible rather than
creating a new tag. */
if (!decl)
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 7cc2fee..cdf9ccf 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3681,10 +3681,8 @@ unqualified_namespace_lookup (tree name, int flags)
if (b)
{
- if (b->value && hidden_name_p (b->value))
- /* Ignore anticipated built-in functions and friends. */
- ;
- else
+ if (b->value
+ && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
binding.value = b->value;
binding.type = b->type;
}
@@ -3987,18 +3985,18 @@ 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)
- && !hidden_name_p (iter->value))
+ if (qualify_lookup (iter->value, flags))
binding = iter->value;
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (iter->type, flags)
- && !hidden_name_p (iter->type))
+ && qualify_lookup (iter->type, flags))
binding = iter->type;
else
binding = NULL_TREE;
if (binding)
{
+ /* Only namespace-scope bindings can be hidden. */
+ gcc_assert (!hidden_name_p (binding));
val = binding;
break;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 76deddd..e76ad2d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5408,8 +5408,21 @@ tsubst_friend_class (tree friend_tmpl, tree args)
push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
}
- /* First, we look for a class template. */
- tmpl = lookup_name (DECL_NAME (friend_tmpl));
+ /* Look for a class template declaration. We look for hidden names
+ because two friend declarations of the same template are the
+ same. For example, in:
+
+ struct A {
+ template <typename> friend class F;
+ };
+ template <typename> struct B {
+ template <typename> friend class F;
+ };
+
+ both F templates are the same. */
+ tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
+ /*block_p=*/true, 0,
+ LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
/* But, if we don't find one, it might be because we're in a
situation like this:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c739d61..e96ba68 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2058,7 +2058,7 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
DECL_NAME (var) = make_anon_name ();
}
/* We must call pushdecl, since the gimplifier complains if the
- variable hase been declared via a BIND_EXPR. */
+ variable has not been declared via a BIND_EXPR. */
pushdecl (var);
/* Initialize the variable as we would any other variable with a
brace-enclosed initializer. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b38a1ef..c1a42d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28025
+ * g++.dg/template/friend45.C: New test.
+
2006-07-21 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/28339
diff --git a/gcc/testsuite/g++.dg/template/friend45.C b/gcc/testsuite/g++.dg/template/friend45.C
new file mode 100644
index 0000000..61c3656
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend45.C
@@ -0,0 +1,17 @@
+// PR c++/28025
+
+class BaseSubmit
+{
+ template<class T> friend class PeriodicSubmit;
+};
+
+template<class ID>
+class ValuesSubmit
+{
+ template<class T> friend class PeriodicSubmit;
+};
+
+class A;
+class MultiSubmit : public ValuesSubmit<A>
+{
+};