p3.cpp revision 136a6988960ac3aeb96f298da7a1a182db7217cd
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 { 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 34// FIXME: this note should be on the template declaration, not the point of instantiation 35void b1(struct B<float>); // expected-note {{previous use is here}} 36void b2(class B<float>); 37void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}} 38//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly 39 40void c1(struct B<float>::Member); 41void c2(class B<float>::Member); 42void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} 43void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} 44 45void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} 46void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} 47void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} 48void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} 49 50void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} 51void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} 52void e3(union B<A>::Member); 53void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} 54 55template <class T> struct C { 56 void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B<int>'}} 57}; 58 59C<float> f1; 60C<int> f2; // expected-note {{in instantiation of template class}} 61C<A> f3; // expected-note {{in instantiation of template class}} 62