1 | // Check struct: |
2 | // |
3 | // First check compiling and printing of this file. |
4 | // |
5 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ |
6 | // RUN: -DKW=struct -DBASES= -o - %s \ |
7 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
8 | // |
9 | // RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES= %s > %t.c |
10 | // RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=struct -DBASES= \ |
11 | // RUN: %s --input-file %t.c |
12 | // |
13 | // Now check compiling and printing of the printed file. |
14 | // |
15 | // RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c |
16 | // RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c |
17 | // |
18 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.c \ |
19 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
20 | // |
21 | // RUN: %clang_cc1 -verify -ast-print %t.c \ |
22 | // RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=struct \ |
23 | // RUN: -DBASES= %s |
24 | |
25 | // Repeat for union: |
26 | // |
27 | // First check compiling and printing of this file. |
28 | // |
29 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ |
30 | // RUN: -DKW=union -DBASES= -o - %s \ |
31 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
32 | // |
33 | // RUN: %clang_cc1 -verify -ast-print -DKW=union -DBASES= %s > %t.c |
34 | // RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=union -DBASES= \ |
35 | // RUN: %s --input-file %t.c |
36 | // |
37 | // Now check compiling and printing of the printed file. |
38 | // |
39 | // RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c |
40 | // RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c |
41 | // |
42 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.c \ |
43 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
44 | // |
45 | // RUN: %clang_cc1 -verify -ast-print %t.c \ |
46 | // RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=union \ |
47 | // RUN: -DBASES= %s |
48 | |
49 | // Repeat for C++ (BASES helps ensure we're printing as C++ not as C): |
50 | // |
51 | // First check compiling and printing of this file. |
52 | // |
53 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ |
54 | // RUN: -DKW=struct -DBASES=' : B' -o - -xc++ %s \ |
55 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
56 | // |
57 | // RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES=' : B' -xc++ %s \ |
58 | // RUN: > %t.cpp |
59 | // RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ |
60 | // RUN: -DBASES=' : B' %s --input-file %t.cpp |
61 | // |
62 | // Now check compiling and printing of the printed file. |
63 | // |
64 | // RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" > %t.diags |
65 | // RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.diags |
66 | // RUN: cat %t.diags >> %t.cpp |
67 | // |
68 | // RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.cpp \ |
69 | // RUN: | FileCheck --check-prefixes=CHECK,LLVM %s |
70 | // |
71 | // RUN: %clang_cc1 -verify -ast-print %t.cpp \ |
72 | // RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ |
73 | // RUN: -DBASES=' : B' %s |
74 | // |
75 | // Make sure implicit attributes aren't printed. See comments in inMemberPtr |
76 | // for details. |
77 | // |
78 | // RUN: %clang_cc1 -triple i686-pc-win32 -verify -ast-print -DKW=struct \ |
79 | // RUN: -DBASES=' : B' -xc++ %s > %t.cpp |
80 | // RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ |
81 | // RUN: -DBASES=' : B' %s --input-file %t.cpp |
82 | // |
83 | // RUN: cat %t.diags >> %t.cpp |
84 | // RUN: %clang_cc1 -triple i686-pc-win32 -verify -ast-print %t.cpp \ |
85 | // RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ |
86 | // RUN: -DBASES=' : B' %s |
87 | |
88 | // END. |
89 | |
90 | #ifndef KW |
91 | # error KW undefined |
92 | # define KW struct // help syntax checkers |
93 | #endif |
94 | |
95 | #ifndef BASES |
96 | # error BASES undefined |
97 | # define BASES // help syntax checkers |
98 | #endif |
99 | |
100 | struct B {}; |
101 | |
102 | // CHECK-LABEL: defFirst |
103 | void defFirst() { |
104 | // PRINT-NEXT: [[KW]] |
105 | // PRINT-DAG: __attribute__((aligned(16))) |
106 | // PRINT-DAG: __attribute__((deprecated(""))) |
107 | // PRINT-NOT: __attribute__ |
108 | // PRINT-SAME: T[[BASES]] { |
109 | // PRINT-NEXT: int i; |
110 | // PRINT-NEXT: } *p0; |
111 | // expected-warning@+2 {{'T' is deprecated}} |
112 | // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} |
113 | KW __attribute__((aligned(16))) __attribute__((deprecated(""))) T BASES { |
114 | int i; |
115 | } *p0; |
116 | |
117 | // PRINT-NEXT: [[KW]] T *p1; |
118 | KW T *p1; // expected-warning {{'T' is deprecated}} |
119 | |
120 | // LLVM: store i64 16 |
121 | long s0 = sizeof *p0; |
122 | // LLVM-NEXT: store i64 16 |
123 | long s1 = sizeof *p1; |
124 | } |
125 | |
126 | // CHECK-LABEL: defLast |
127 | void defLast() { |
128 | // PRINT-NEXT: [[KW]] __attribute__((aligned(16))) T *p0; |
129 | KW __attribute__((aligned(16))) T *p0; |
130 | |
131 | // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T[[BASES]] { |
132 | // PRINT-NEXT: int i; |
133 | // PRINT-NEXT: } *p1; |
134 | // expected-warning@+2 {{'T' is deprecated}} |
135 | // expected-note@+1 {{'T' has been explicitly marked deprecated here}} |
136 | KW __attribute__((deprecated(""))) T BASES { int i; } *p1; |
137 | |
138 | // LLVM: store i64 16 |
139 | long s0 = sizeof *p0; |
140 | // LLVM-NEXT: store i64 16 |
141 | long s1 = sizeof *p1; |
142 | } |
143 | |
144 | // CHECK-LABEL: defMiddle |
145 | void defMiddle() { |
146 | // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p0; |
147 | // expected-warning@+2 {{'T' is deprecated}} |
148 | // expected-note@+1 3 {{'T' has been explicitly marked deprecated here}} |
149 | KW __attribute__((deprecated(""))) T *p0; |
150 | |
151 | // PRINT-NEXT: [[KW]] __attribute__((aligned(16))) T[[BASES]] { |
152 | // PRINT-NEXT: int i; |
153 | // PRINT-NEXT: } *p1; |
154 | KW __attribute__((aligned(16))) T BASES { int i; } *p1; // expected-warning {{'T' is deprecated}} |
155 | |
156 | // PRINT-NEXT: [[KW]] T *p2; |
157 | KW T *p2; // expected-warning {{'T' is deprecated}} |
158 | |
159 | // LLVM: store i64 16 |
160 | long s0 = sizeof *p0; |
161 | // LLVM-NEXT: store i64 16 |
162 | long s1 = sizeof *p1; |
163 | // LLVM-NEXT: store i64 16 |
164 | long s2 = sizeof *p2; |
165 | } |
166 | |
167 | // CHECK-LABEL: defSelfRef |
168 | void defSelfRef() { |
169 | // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p0; |
170 | // expected-warning@+2 {{'T' is deprecated}} |
171 | // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} |
172 | KW __attribute__((deprecated(""))) T *p0; |
173 | |
174 | // PRINT-NEXT: [[KW]] __attribute__((aligned(64))) T[[BASES]] { |
175 | // PRINT-NEXT: int i; |
176 | // PRINT-NEXT: [[KW]] T *p2; |
177 | // PRINT-NEXT: [[KW]] __attribute__((may_alias)) T *p3; |
178 | // PRINT-NEXT: [[KW]] T *p4; |
179 | // PRINT-NEXT: } *p1; |
180 | KW __attribute__((aligned(64))) T BASES { // expected-warning {{'T' is deprecated}} |
181 | int i; |
182 | KW T *p2; |
183 | // FIXME: For C++, T at p3 loses aligned and deprecated, perhaps because |
184 | // that RecordDecl isn't in the same redecl list. Perhaps the redecl lists |
185 | // are split here but not in C due to the different scoping rules in C++ |
186 | // classes. |
187 | KW __attribute__((may_alias)) T *p3; |
188 | KW T *p4; |
189 | } *p1; |
190 | |
191 | // LLVM: store i64 64 |
192 | long s0 = sizeof *p0; |
193 | // LLVM-NEXT: store i64 64 |
194 | long s1 = sizeof *p1; |
195 | // LLVM-NEXT: store i64 64 |
196 | long s2 = sizeof *p0->p2; |
197 | // LLVM-NEXT: store i64 64 |
198 | long s3 = sizeof *p1->p3; |
199 | // LLVM-NEXT: store i64 64 |
200 | long s4 = sizeof *p1->p4->p2; |
201 | } |
202 | |
203 | // CHECK-LABEL: declsOnly |
204 | void declsOnly() { |
205 | // PRINT-NEXT: [[KW]] T *p0; |
206 | KW T *p0; |
207 | |
208 | // PRINT-NEXT: [[KW]] __attribute__((may_alias)) T *p1; |
209 | KW __attribute__((may_alias)) T *p1; |
210 | |
211 | // PRINT-NEXT: [[KW]] T *p2; |
212 | KW T *p2; |
213 | |
214 | // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p3; |
215 | // expected-warning@+2 {{'T' is deprecated}} |
216 | // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} |
217 | KW __attribute__((deprecated(""))) T *p3; |
218 | |
219 | // PRINT-NEXT: [[KW]] T *p4; |
220 | KW T *p4; // expected-warning {{'T' is deprecated}} |
221 | } |
222 | |
223 | // Make sure expanded printing of tag types is turned back off in other parts |
224 | // of a tag declaration. The base class list is checked above. |
225 | |
226 | // CHECK-LABEL: inMembers |
227 | void inMembers() { |
228 | // PRINT-NEXT: [[KW]] T1 { |
229 | // PRINT-NEXT: int i; |
230 | // PRINT-NEXT: }; |
231 | KW T1 { int i; }; |
232 | // PRINT-NEXT: [[KW]] T2 { |
233 | // PRINT-NEXT: [[KW]] T1 i; |
234 | // PRINT-NEXT: }; |
235 | KW T2 { KW T1 i; }; |
236 | } |
237 | |
238 | // CHECK-LABEL: inInit |
239 | void inInit() { |
240 | // PRINT-NEXT: [[KW]] T1 { |
241 | // PRINT-NEXT: int i; |
242 | // PRINT-NEXT: }; |
243 | KW T1 { int i; }; |
244 | // PRINT-NEXT: [[KW]] T2 { |
245 | // PRINT-NEXT: long i; |
246 | // PRINT-NEXT: } t2 = {sizeof([[KW]] T1)}; |
247 | KW T2 { long i; } t2 = {sizeof(KW T1)}; |
248 | } |
249 | |
250 | #ifdef __cplusplus |
251 | // PRINT-CXX-LABEL: inMemberPtr |
252 | void inMemberPtr() { |
253 | // Under windows, the implicit attribute __single_inheritance used to print |
254 | // between KW and T1 here, but that wasn't faithful to the original source. |
255 | // |
256 | // PRINT-CXX-NEXT: [[KW]] T1 { |
257 | // PRINT-CXX-NEXT: int i; |
258 | // PRINT-CXX-NEXT: }; |
259 | KW T1 { int i; }; |
260 | // PRINT-CXX-NEXT: [[KW]] T2 { |
261 | // PRINT-CXX-NEXT: } T1::*p; |
262 | KW T2 {} T1::*p; |
263 | } |
264 | #endif |
265 | |
266 | // Check that tag decl groups stay together in decl contexts. |
267 | |
268 | // PRINT-LABEL: DeclGroupAtFileScope { |
269 | // PRINT-NEXT: int i; |
270 | // PRINT-NEXT: } *DeclGroupAtFileScopePtr; |
271 | KW DeclGroupAtFileScope { int i; } *DeclGroupAtFileScopePtr; |
272 | |
273 | // PRINT-LABEL: DeclGroupInMemberList { |
274 | KW DeclGroupInMemberList { |
275 | // PRINT-NEXT: struct T1 { |
276 | // PRINT-NEXT: int i; |
277 | // PRINT-NEXT: } t1; |
278 | struct T1 { int i; } t1; |
279 | // PRINT-NEXT: union T2 { |
280 | // PRINT-NEXT: int i; |
281 | // PRINT-NEXT: } *t20, t21[2]; |
282 | union T2 { int i; } *t20, t21[2]; |
283 | // PRINT-NEXT: enum T3 { |
284 | // PRINT-NEXT: T30 |
285 | // PRINT-NEXT: } t30; |
286 | enum T3 { T30 } t30; |
287 | // PRINT-NEXT: }; |
288 | }; |
289 | |
290 | // A tag decl group in the tag decl's own member list is exercised in |
291 | // defSelfRef above. |
292 | |