/* $NetBSD: lsym_tag.c,v 1.10 2023/06/17 22:09:24 rillig Exp $ */ /* * Tests for the token lsym_tag, which represents one of the keywords * 'struct', 'union' or 'enum' that declare, define or use a tagged type. */ /* TODO: Add systematic tests for 'struct'. */ /* TODO: Add systematic tests for 'union'. */ /* TODO: Add systematic tests for 'enum'. */ //indent input int indent_enum_constants(void) { enum color { red, green }; enum color colors[] = { red, red, red, }; /* * Ensure that the token sequence 'enum type {' only matches if there * are no other tokens in between, to prevent statement continuations * from being indented like enum constant declarations. * * See https://gnats.netbsd.org/55453. */ if (colors[0] == (enum color)1) { return 1 + 2 + 3; } return 0; } //indent end //indent run-equals-input -ci2 //indent input struct stat { mode_t st_mode; }; union variant { enum { } tag; int v_int; long v_long; bool v_bool; void *v_pointer; }; //indent end //indent run-equals-input /* See FreeBSD r303485. */ //indent input int f(struct x *a); void t(void) { static const struct { int a; int b; } c[] = { { D, E }, { F, G } }; } void u(struct x a) { int b; struct y c = (struct y *)&a; } //indent end //indent run int f(struct x *a); void t(void) { static const struct { int a; int b; } c[] = { {D, E}, {F, G} }; } void u(struct x a) { int b; struct y c = (struct y *)&a; } //indent end /* Comment between 'struct' and the tag name; doesn't occur in practice. */ //indent input struct /* comment */ tag var; //indent end //indent run -di0 struct /* comment */ tag var; //indent end /* * Ensure that the names of struct members are all indented the same. * Before 2023-05-15, the indentation depended on their type name. */ //indent input struct outer { enum { untagged_constant, } untagged_member, second_untagged_member; enum tag_name { tagged_constant, } tagged_member, second_tagged_member; }; //indent end //indent run-equals-input -di0 /* * The initializer of an enum constant needs to be indented like any other * initializer, especially the continuation lines. */ //indent input enum multi_line { ml1 = 1 + 2 + offsetof(struct s, member) + 3, ml2 = 1 + 2 + offsetof(struct s, member) + 3, }; //indent end //indent run-equals-input -ci4 //indent run-equals-input -ci4 -nlp /* * When 'typedef' or a tag is followed by a name, that name marks a type and a * following '*' marks a pointer type. */ //indent input { // $ Syntactically invalid but shows that '*' is not multiplication. a = struct x * y; a = (struct x * y)z; } //indent end //indent run { // $ Everything before the '*' is treated as a declaration. a = struct x *y; a = (struct x *y)z; } //indent end