p3.cpp revision 4033642464e8ba0982f88f34cffad808d247b393
1// RUN: %clang_cc1 -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  friend enum A; // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
16                 // expected-error {{enum types cannot be friends}}
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  union Member { // expected-note 4 {{previous use is here}}
29    void* a;
30  };
31};
32
33void b1(struct B<float>);
34void b2(class B<float>);
35void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}}
36//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly
37
38void c1(struct B<float>::Member);
39void c2(class B<float>::Member);
40void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
41void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
42
43void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
44void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
45void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
46void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
47
48void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
49void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
50void e3(union B<A>::Member);
51void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
52
53template <class T> struct C {
54  void foo(class B<T>::Member); // expected-error{{'Member' does not name a tag member in the specified scope}} \
55                                // expected-error{{use of 'Member' with tag type that does not match previous declaration}}
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