p3.cpp revision 9cc7807e1622c2f945b607bdd39dd283df5e7bb5
1// RUN: clang-cc -fsyntax-only -verify %s
2
3class A {}; // expected-note 3 {{previous use is here}}
4
5void a1(struct A);
6void a2(class A);
7void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
8void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
9
10class A1 {
11  friend struct A;
12  friend class A;
13  friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
14
15  // FIXME: a better error would be something like 'enum types cannot be friends'
16  friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}}
17};
18
19template <class T> struct B { // expected-note {{previous use is here}}
20  class Member {}; // expected-note 2 {{previous use is here}}
21};
22
23template <> class B<int> {
24  // no type Member
25};
26
27template <> struct B<A> {
28  // FIXME: the error here should be associated with the use at "void foo..."
29  union Member { // expected-note 4 {{previous use is here}} expected-error {{tag type that does not match previous declaration}}
30    void* a;
31  };
32};
33
34void b1(struct B<float>);
35void b2(class B<float>);
36void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}}
37//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly
38
39void c1(struct B<float>::Member);
40void c2(class B<float>::Member);
41void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
42void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
43
44void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
45void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
46void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
47void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
48
49void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
50void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
51void e3(union B<A>::Member);
52void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
53
54template <class T> struct C {
55  void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B<int>'}}
56};
57
58C<float> f1;
59C<int> f2; // expected-note {{in instantiation of template class}}
60C<A> f3; // expected-note {{in instantiation of template class}}
61