1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3class A {}; // expected-note 4 {{previous use is here}}
4enum E {};
5
6void a1(struct A);
7void a2(class A);
8void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
9void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
10
11class A1 {
12  friend struct A;
13  friend class A;
14  friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
15
16  friend enum A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
17  friend enum E; // expected-warning {{befriending enumeration type 'enum E' is a C++11 extension}}
18};
19
20template <class T> struct B { // expected-note {{previous use is here}}
21  class Member {}; // expected-note 2 {{previous use is here}}
22};
23
24template <> class B<int> {
25  // no type Member
26};
27
28template <> struct B<A> {
29  union Member { // expected-note 4 {{previous use is here}}
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 {{no struct named 'Member' in 'B<int>'}}
45void d2(class B<int>::Member); // expected-error {{no class named 'Member' in 'B<int>'}}
46void d3(union B<int>::Member); // expected-error {{no union named 'Member' in 'B<int>'}}
47void d4(enum B<int>::Member); // expected-error {{no enum named 'Member' in 'B<int>'}}
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 class named 'Member' in 'B<int>'}} \
56                                // expected-error{{use of 'Member' with tag type that does not match previous declaration}}
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