* pt.c (tsubst_friend_class): Handle templates with explicit
nested names.
PR c++/6331:
* typeck.c (merge_types): Remember the cv-qualification of pointer
types when merging them.
PR c++/6256:
* g++.dg/template/friend5.C: New test.
PR c++/6331:
* g++.dg/template/qual1.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52661
138bc75d-0d04-0410-961f-
82ee72b054a4
+2002-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6256:
+ * pt.c (tsubst_friend_class): Handle templates with explicit
+ nested names.
+
+ PR c++/6331:
+ * typeck.c (merge_types): Remember the cv-qualification of pointer
+ types when merging them.
+
2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
tree tmpl;
/* First, we look for a class template. */
- tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
-
- /* But, if we don't find one, it might be because we're in a
- situation like this:
+ if (DECL_CONTEXT (friend_tmpl))
+ tmpl = friend_tmpl;
+ else
+ {
+ tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
- template <class T>
- struct S {
- template <class U>
- friend struct S;
- };
+ /* But, if we don't find one, it might be because we're in a
+ situation like this:
- Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
- for `S<int>', not the TEMPLATE_DECL. */
- if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
- {
- tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
- tmpl = maybe_get_template_decl_from_type_decl (tmpl);
+ template <class T>
+ struct S {
+ template <class U>
+ friend struct S;
+ };
+
+ Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
+ for `S<int>', not the TEMPLATE_DECL. */
+ if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
+ {
+ tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
+ tmpl = maybe_get_template_decl_from_type_decl (tmpl);
+ }
}
if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
/* For two pointers, do this recursively on the target type. */
{
tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
+ int quals = cp_type_quals (t1);
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
else
t1 = build_reference_type (target);
t1 = build_type_attribute_variant (t1, attributes);
+ t1 = cp_build_qualified_type (t1, quals);
if (TREE_CODE (target) == METHOD_TYPE)
t1 = build_ptrmemfunc_type (t1);
+2002-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6256:
+ * g++.dg/template/friend5.C: New test.
+
+ PR c++/6331:
+ * g++.dg/template/qual1.C: Likewise.
+
2002-04-22 Zack Weinberg <zack@codesourcery.com>
* gcc.c-torture/execute/980707-1.c: Don't use isspace().
--- /dev/null
+// { dg-do compile }
+
+namespace NS { template <typename number> class C; }
+
+template <typename T> class X {
+ template <typename N> friend class NS::C;
+};
+
+template class X<int>;
--- /dev/null
+// { dg-do compile }
+
+template<class T>
+class Link_array
+{
+public:
+ void sort (int (*compare) (T *const&,T *const&));
+};
+
+int shift_compare (int *const &, int *const &) {};
+
+template<class T> void
+Link_array<T>::sort (int (*compare) (T *const&,T *const&))
+{
+}
+
+void f ()
+{
+ Link_array<int> clashes;
+ clashes.sort (shift_compare);
+}