1 /* $NetBSD: lsym_tag.c,v 1.10 2023/06/17 22:09:24 rillig Exp $ */
2
3 /*
4 * Tests for the token lsym_tag, which represents one of the keywords
5 * 'struct', 'union' or 'enum' that declare, define or use a tagged type.
6 */
7
8 /* TODO: Add systematic tests for 'struct'. */
9 /* TODO: Add systematic tests for 'union'. */
10 /* TODO: Add systematic tests for 'enum'. */
11
12
13 //indent input
14 int
indent_enum_constants(void)15 indent_enum_constants(void)
16 {
17 enum color {
18 red,
19 green
20 };
21 enum color colors[] = {
22 red,
23 red,
24 red,
25 };
26 /*
27 * Ensure that the token sequence 'enum type {' only matches if there
28 * are no other tokens in between, to prevent statement continuations
29 * from being indented like enum constant declarations.
30 *
31 * See https://gnats.netbsd.org/55453.
32 */
33 if (colors[0] == (enum color)1) {
34 return 1
35 + 2
36 + 3;
37 }
38 return 0;
39 }
40 //indent end
41
42 //indent run-equals-input -ci2
43
44
45 //indent input
46 struct stat {
47 mode_t st_mode;
48 };
49
50 union variant {
51 enum {
52 } tag;
53 int v_int;
54 long v_long;
55 bool v_bool;
56 void *v_pointer;
57 };
58 //indent end
59
60 //indent run-equals-input
61
62
63 /* See FreeBSD r303485. */
64 //indent input
65 int f(struct x *a);
66
67 void
t(void)68 t(void)
69 {
70 static const struct {
71 int a;
72 int b;
73 } c[] = {
74 { D, E },
75 { F, G }
76 };
77 }
78
u(struct x a)79 void u(struct x a) {
80 int b;
81 struct y c = (struct y *)&a;
82 }
83 //indent end
84
85 //indent run
86 int f(struct x *a);
87
88 void
t(void)89 t(void)
90 {
91 static const struct {
92 int a;
93 int b;
94 } c[] = {
95 {D, E},
96 {F, G}
97 };
98 }
99
100 void
u(struct x a)101 u(struct x a)
102 {
103 int b;
104 struct y c = (struct y *)&a;
105 }
106 //indent end
107
108
109 /* Comment between 'struct' and the tag name; doesn't occur in practice. */
110 //indent input
111 struct /* comment */ tag var;
112 //indent end
113
114 //indent run -di0
115 struct /* comment */ tag var;
116 //indent end
117
118
119 /*
120 * Ensure that the names of struct members are all indented the same.
121 * Before 2023-05-15, the indentation depended on their type name.
122 */
123 //indent input
124 struct outer {
125 enum {
126 untagged_constant,
127 } untagged_member,
128 second_untagged_member;
129 enum tag_name {
130 tagged_constant,
131 } tagged_member,
132 second_tagged_member;
133 };
134 //indent end
135
136 //indent run-equals-input -di0
137
138
139 /*
140 * The initializer of an enum constant needs to be indented like any other
141 * initializer, especially the continuation lines.
142 */
143 //indent input
144 enum multi_line {
145 ml1 = 1
146 + 2
147 + offsetof(struct s, member)
148 + 3,
149 ml2 = 1
150 + 2
151 + offsetof(struct s, member)
152 + 3,
153 };
154 //indent end
155
156 //indent run-equals-input -ci4
157
158 //indent run-equals-input -ci4 -nlp
159
160
161 /*
162 * When 'typedef' or a tag is followed by a name, that name marks a type and a
163 * following '*' marks a pointer type.
164 */
165 //indent input
166 {
167 // $ Syntactically invalid but shows that '*' is not multiplication.
168 a = struct x * y;
169 a = (struct x * y)z;
170 }
171 //indent end
172
173 //indent run
174 {
175 // $ Everything before the '*' is treated as a declaration.
176 a = struct x *y;
177 a = (struct x *y)z;
178 }
179 //indent end
180