Rework the Parse-Sema interaction for friends to better support friend
class templates. We now treat friend class templates much more like
normal class templates, except that they still get special name lookup
rules. Fixes PR5057 and eliminates a bunch of spurious diagnostics in
<iostream>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82848 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CXX/class/class.friend/p2.cpp b/test/CXX/class/class.friend/p2.cpp
index f130beb..98be204 100644
--- a/test/CXX/class/class.friend/p2.cpp
+++ b/test/CXX/class/class.friend/p2.cpp
@@ -1,8 +1,10 @@
// RUN: clang-cc -fsyntax-only -verify %s
+struct B0;
+
class A {
friend class B {}; // expected-error {{cannot define a type in a friend declaration}}
friend int; // expected-error {{friends can only be classes or functions}}
- friend B; // expected-error {{must specify 'class' in a friend class declaration}}
+ friend B0; // expected-error {{must specify 'struct' to befriend}}
friend class C; // okay
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
index 89f938d..657cf20 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
@@ -13,7 +13,8 @@
friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
// FIXME: a better error would be something like 'enum types cannot be friends'
- friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}}
+ friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
+ // expected-error{{classes or functions}}
};
template <class T> struct B { // expected-note {{previous use is here}}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
index dd856e9..4615beb 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
@@ -7,5 +7,7 @@
class B {
template <class T> friend class A;
template <class T> friend class Undeclared;
- template <class T> friend typename A<T>::Member; // expected-error {{friend type templates must use an elaborated type}}
+
+ // FIXME: Diagnostic below could be (and was) better.
+ template <class T> friend typename A<T>::Member; // expected-error {{classes or functions}}
};
diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp
index 3978947..14b31af 100644
--- a/test/Parser/cxx-friend.cpp
+++ b/test/Parser/cxx-friend.cpp
@@ -21,8 +21,8 @@
// 'A' here should refer to the declaration above.
friend class A;
- friend C; // expected-error {{must specify 'class' in a friend class declaration}}
- friend U; // expected-error {{must specify 'union' in a friend union declaration}}
+ friend C; // expected-error {{must specify 'class' to befriend}}
+ friend U; // expected-error {{must specify 'union' to befriend}}
friend int; // expected-error {{friends can only be classes or functions}}
friend void myfunc();
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
new file mode 100644
index 0000000..6268cd8
--- /dev/null
+++ b/test/SemaTemplate/friend-template.cpp
@@ -0,0 +1,17 @@
+// RUN: clang-cc -fsyntax-only %s
+
+// PR5057
+namespace std {
+ class X {
+ public:
+ template<typename T>
+ friend struct Y;
+ };
+}
+
+namespace std {
+ template<typename T>
+ struct Y
+ {
+ };
+}