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
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
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
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
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
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
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
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
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