1 // RUN: %clang_cc1 -fsyntax-only -Wmismatched-tags -verify %s
2 // RUN: not %clang_cc1 -fsyntax-only -Wmismatched-tags %s 2>&1 | FileCheck %s
3 class X; // expected-note 2{{here}}
4 typedef struct X * X_t; // expected-warning{{previously declared}}
5 union X { int x; float y; }; // expected-error{{use of 'X' with tag type that does not match previous declaration}}
6 
7 template<typename T> struct Y; // expected-note{{did you mean class here?}}
8 template<class U> class Y { }; // expected-warning{{previously declared}}
9 
10 template <typename>
11 struct Z {
12   struct Z { // expected-error{{member 'Z' has the same name as its class}}
13   };
14 };
15 
16 class A;
17 class A;  // expected-note{{previous use is here}}
18 struct A;  // expected-warning{{struct 'A' was previously declared as a class}}
19 
20 class B;  // expected-note{{did you mean struct here?}}
21 class B;  // expected-note{{previous use is here}}\
22           // expected-note{{did you mean struct here?}}
23 struct B;  // expected-warning{{struct 'B' was previously declared as a class}}
24 struct B {};  // expected-warning{{'B' defined as a struct here but previously declared as a class}}
25 
26 class C;  // expected-note{{previous use is here}}
27 struct C;  // expected-warning{{struct 'C' was previously declared as a class}}\
28            // expected-note{{previous use is here}}\
29            // expected-note{{did you mean class here?}}
30 class C;  // expected-warning{{class 'C' was previously declared as a struct}}\
31           // expected-note{{previous use is here}}
32 struct C;  // expected-warning{{struct 'C' was previously declared as a class}}\
33            // expected-note{{did you mean class here?}}
34 class C {};  // expected-warning{{'C' defined as a class here but previously declared as a struct}}
35 
36 struct D {};  // expected-note{{previous definition is here}}\
37               // expected-note{{previous use is here}}
38 class D {};  // expected-error{{redefinition of 'D'}}
39 struct D;
40 class D;  // expected-warning{{class 'D' was previously declared as a struct}}\
41           // expected-note{{did you mean struct here?}}
42 
43 class E;
44 class E;
45 class E {};
46 class E;
47 
48 struct F;
49 struct F;
50 struct F {}; // expected-note {{previous use}}
51 struct F;
52 class F; // expected-warning {{previously declared as a struct}} expected-note {{did you mean struct}}
53 
54 template<class U> class G;  // expected-note{{previous use is here}}\
55                             // expected-note{{did you mean struct here?}}
56 template<class U> struct G;  // expected-warning{{struct template 'G' was previously declared as a class template}}
57 template<class U> struct G {};  // expected-warning{{'G' defined as a struct template here but previously declared as a class template}}
58 
59 // Declarations from contexts where the warning is disabled are entirely
60 // ignored for the purpose of this warning.
61 struct J;
62 struct K; // expected-note {{previous use}}
63 struct L;
64 struct M; // expected-note {{previous use}}
65 
66 #pragma clang diagnostic push
67 #pragma clang diagnostic ignored "-Wmismatched-tags"
68 struct H;
69 class I {};
70 class J;
71 class K;
72 class L;
73 class M {};
74 #pragma clang diagnostic pop
75 
76 class H; // expected-note {{previous use}}
77 struct H; // expected-warning {{previously declared as a class}}
78 
79 struct I; // expected-note {{previous use}}
80 class I; // expected-warning {{previously declared as a struct}}
81 
82 struct J;
83 class K; // expected-warning {{previously declared as a struct}}
84 struct L;
85 class M; // expected-warning {{previously declared as a struct}}
86 
87 /*
88 *** 'X' messages ***
89 CHECK: warning: struct 'X' was previously declared as a class
90 CHECK: {{^}}typedef struct X * X_t;
91 CHECK: {{^}}        ^{{$}}
92 CHECK: note: previous use is here
93 CHECK: {{^}}class X;
94 CHECK: {{^}}      ^{{$}}
95 CHECK: error: use of 'X' with tag type that does not match previous declaration
96 CHECK: {{^}}union X { int x; float y; };
97 CHECK: {{^}}^~~~~{{$}}
98 CHECK: {{^}}class{{$}}
99 CHECK: note: previous use is here
100 CHECK: {{^}}class X;
101 CHECK: {{^}}      ^{{$}}
102 *** 'Y' messages ***
103 CHECK: warning: 'Y' defined as a class template here but
104       previously declared as a struct template
105 CHECK: {{^}}template<class U> class Y { };
106 CHECK: {{^}}                  ^{{$}}
107 CHECK: note: did you mean class here?
108 CHECK: {{^}}template<typename T> struct Y;
109 CHECK: {{^}}                     ^~~~~~{{$}}
110 CHECK: {{^}}                     class{{$}}
111 *** 'A' messages ***
112 CHECK: warning: struct 'A' was previously declared as a class
113 CHECK: {{^}}struct A;
114 CHECK: {{^}}^{{$}}
115 CHECK: note: previous use is here
116 CHECK: {{^}}class A;
117 CHECK: {{^}}      ^{{$}}
118 *** 'B' messages ***
119 CHECK: warning: struct 'B' was previously declared as a class
120 CHECK: {{^}}struct B;
121 CHECK: {{^}}^{{$}}
122 CHECK: note: previous use is here
123 CHECK: {{^}}class B;
124 CHECK: {{^}}      ^{{$}}
125 CHECK: 'B' defined as a struct here but previously declared as a class
126 CHECK: {{^}}struct B {};
127 CHECK: {{^}}^{{$}}
128 CHECK: note: did you mean struct here?
129 CHECK: {{^}}class B;
130 CHECK: {{^}}^~~~~{{$}}
131 CHECK: {{^}}struct{{$}}
132 CHECK: note: did you mean struct here?
133 CHECK: {{^}}class B;
134 CHECK: {{^}}^~~~~{{$}}
135 CHECK: {{^}}struct{{$}}
136 *** 'C' messages ***
137 CHECK: warning: struct 'C' was previously declared as a class
138 CHECK: {{^}}struct C;
139 CHECK: {{^}}^{{$}}
140 CHECK: note: previous use is here
141 CHECK: {{^}}class C;
142 CHECK: {{^}}      ^{{$}}
143 CHECK: warning: class 'C' was previously declared as a struct
144 CHECK: {{^}}class C;
145 CHECK: {{^}}^{{$}}
146 CHECK: note: previous use is here
147 CHECK: {{^}}struct C;
148 CHECK: {{^}}       ^{{$}}
149 CHECK: warning: struct 'C' was previously declared as a class
150 CHECK: {{^}}struct C;
151 CHECK: {{^}}^{{$}}
152 CHECK: note: previous use is here
153 CHECK: {{^}}class C;
154 CHECK: {{^}}      ^{{$}}
155 CHECK: warning: 'C' defined as a class here but previously declared as a struct
156 CHECK: {{^}}class C {};
157 CHECK: {{^}}^{{$}}
158 CHECK: note: did you mean class here?
159 CHECK: {{^}}struct C;
160 CHECK: {{^}}^~~~~~{{$}}
161 CHECK: {{^}}class{{$}}
162 CHECK: note: did you mean class here?
163 CHECK: {{^}}struct C;
164 CHECK: {{^}}^~~~~~{{$}}
165 CHECK: {{^}}class{{$}}
166 *** 'D' messages ***
167 CHECK: error: redefinition of 'D'
168 CHECK: {{^}}class D {};
169 CHECK: {{^}}      ^{{$}}
170 CHECK: note: previous definition is here
171 CHECK: {{^}}struct D {};
172 CHECK: {{^}}       ^{{$}}
173 CHECK: warning: class 'D' was previously declared as a struct
174 CHECK: {{^}}class D;
175 CHECK: {{^}}^{{$}}
176 CHECK: note: previous use is here
177 CHECK: {{^}}struct D {};
178 CHECK: {{^}}       ^{{$}}
179 CHECK: note: did you mean struct here?
180 CHECK: {{^}}class D;
181 CHECK: {{^}}^~~~~{{$}}
182 CHECK: {{^}}struct{{$}}
183 *** 'E' messages ***
184 *** 'F' messages ***
185 *** 'G' messages ***
186 CHECK: warning: struct template 'G' was previously declared as a class template
187 CHECK: {{^}}template<class U> struct G;
188 CHECK: {{^}}                  ^{{$}}
189 CHECK: note: previous use is here
190 CHECK: {{^}}template<class U> class G;
191 CHECK: {{^}}                        ^{{$}}
192 CHECK: warning: 'G' defined as a struct template here but previously declared as a class template
193 CHECK: {{^}}template<class U> struct G {};
194 CHECK: {{^}}                  ^{{$}}
195 CHECK: note: did you mean struct here?
196 CHECK: {{^}}template<class U> class G;
197 CHECK: {{^}}                  ^~~~~
198 CHECK: {{^}}                  struct
199 */
200