@@ -61,25 +61,21 @@ pub const Iterator = struct {
6161 return .{ self .slice [self .index ], self .index };
6262 }
6363 if (self .source ) | * source | {
64- var cur = source .qt ;
65- if (cur .isInvalid ()) {
64+ if (source .qt .isInvalid ()) {
6665 self .source = null ;
6766 return null ;
6867 }
69- while ( true ) switch (cur .type (source .comp )) {
70- .typeof = > | typeof | cur = typeof .base ,
68+ loop : switch (source . qt .type (source .comp )) {
69+ .typeof = > | typeof | continue : loop typeof .base . type ( source . comp ) ,
7170 .attributed = > | attributed | {
7271 self .slice = attributed .attributes ;
7372 self .index = 1 ;
7473 source .qt = attributed .base ;
7574 return .{ self .slice [0 ], 0 };
7675 },
77- .typedef = > | typedef | cur = typedef .base ,
78- else = > {
79- self .source = null ;
80- break ;
81- },
82- };
76+ .typedef = > | typedef | continue :loop typedef .base .type (source .comp ),
77+ else = > self .source = null ,
78+ }
8379 }
8480 return null ;
8581 }
@@ -712,6 +708,9 @@ const attributes = struct {
712708 pub const thiscall = struct {};
713709 pub const sysv_abi = struct {};
714710 pub const ms_abi = struct {};
711+ // TODO cannot be combined with weak or selectany
712+ pub const internal_linkage = struct {};
713+ pub const availability = struct {};
715714};
716715
717716pub const Tag = std .meta .DeclEnum (attributes );
@@ -776,9 +775,9 @@ pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
776775
777776 const tag_and_opts = attribute_names .fromName (normalized ) orelse return null ;
778777 switch (actual_kind ) {
779- inline else = > | tag | {
780- if (@field (tag_and_opts . properties , @tagName (tag )))
781- return tag_and_opts .properties . tag ;
778+ inline else = > | available_kind | {
779+ if (@field (tag_and_opts , @tagName (available_kind )))
780+ return tag_and_opts .tag ;
782781 },
783782 }
784783 return null ;
@@ -814,7 +813,7 @@ fn applyVariableOrParameterAttributes(p: *Parser, qt: QualType, attr_buf_start:
814813 for (attrs , toks ) | attr , tok | switch (attr .tag ) {
815814 // zig fmt: off
816815 .alias , .may_alias , .deprecated , .unavailable , .unused , .warn_if_not_aligned , .weak , .used ,
817- .noinit , .retain , .persistent , .section , .mode , .asm_label , .nullability , .unaligned ,
816+ .noinit , .retain , .persistent , .section , .mode , .asm_label , .nullability , .unaligned , .selectany , .internal_linkage ,
818817 = > try p .attr_application_buf .append (gpa , attr ),
819818 // zig fmt: on
820819 .common = > if (nocommon ) {
@@ -874,18 +873,18 @@ fn applyVariableOrParameterAttributes(p: *Parser, qt: QualType, attr_buf_start:
874873
875874pub fn applyFieldAttributes (p : * Parser , field_qt : * QualType , attr_buf_start : usize ) ! []const Attribute {
876875 const attrs = p .attr_buf .items (.attr )[attr_buf_start .. ];
877- const toks = p .attr_buf .items (.tok )[attr_buf_start .. ];
876+ const seen = p .attr_buf .items (.seen )[attr_buf_start .. ];
878877 p .attr_application_buf .items .len = 0 ;
879- for (attrs , toks ) | attr , tok | switch (attr .tag ) {
880- // zig fmt: off
881- .@"packed" , .may_alias , .deprecated , .unavailable , .unused , .warn_if_not_aligned ,
882- .mode , .warn_unused_result , .nodiscard , .nullability , .unaligned ,
883- = > try p . attr_application_buf . append ( p . comp . gpa , attr ) ,
884- // zig fmt: on
885- .vector_size = > try attr .applyVectorSize (p , tok , field_qt ),
886- .aligned = > try attr . applyAligned ( p , field_qt .* , null ),
887- .calling_convention = > try applyCallingConvention ( attr , p , tok , field_qt .* ) ,
888- else = > try ignoredAttrErr ( p , tok , attr . tag , "fields" ) ,
878+ for (attrs , 0 .. ) | attr , i | switch (attr .tag ) {
879+ .@"packed" = > {
880+ try p . attr_application_buf . append ( p . comp . gpa , attr );
881+ seen [ i ] = true ;
882+ } ,
883+ .aligned = > {
884+ try attr .applyAligned (p , field_qt .* , null );
885+ seen [ i ] = true ;
886+ } ,
887+ else = > {} ,
889888 };
890889 return p .attr_application_buf .items ;
891890}
@@ -894,29 +893,35 @@ pub fn applyTypeAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diag
894893 const gpa = p .comp .gpa ;
895894 const attrs = p .attr_buf .items (.attr )[attr_buf_start .. ];
896895 const toks = p .attr_buf .items (.tok )[attr_buf_start .. ];
896+ const seens = p .attr_buf .items (.seen )[attr_buf_start .. ];
897897 p .attr_application_buf .items .len = 0 ;
898898 var base_qt = qt ;
899- for (attrs , toks ) | attr , tok | switch (attr .tag ) {
900- // zig fmt: off
901- .@"packed" , .may_alias , .deprecated , .unavailable , .unused , .warn_if_not_aligned , .mode , .nullability , .unaligned ,
902- = > try p .attr_application_buf .append (gpa , attr ),
903- // zig fmt: on
904- .transparent_union = > try attr .applyTransparentUnion (p , tok , base_qt ),
905- .vector_size = > try attr .applyVectorSize (p , tok , & base_qt ),
906- .aligned = > try attr .applyAligned (p , base_qt , diagnostic ),
907- .designated_init = > if (base_qt .is (p .comp , .@"struct" )) {
908- try p .attr_application_buf .append (gpa , attr );
909- } else {
910- try p .err (tok , .designated_init_invalid , .{});
911- },
912- .calling_convention = > try applyCallingConvention (attr , p , tok , base_qt ),
913- .alloc_size ,
914- .copy ,
915- .scalar_storage_order ,
916- .nonstring ,
917- = > | t | try p .err (tok , .attribute_todo , .{ @tagName (t ), "types" }),
918- else = > try ignoredAttrErr (p , tok , attr .tag , "types" ),
919- };
899+ for (attrs , toks , seens ) | attr , tok , seen | {
900+ if (seen ) continue ;
901+
902+ switch (attr .tag ) {
903+ // zig fmt: off
904+ .@"packed" , .may_alias , .deprecated , .unavailable , .unused , .warn_if_not_aligned , .mode ,
905+ .nullability , .unaligned , .warn_unused_result ,
906+ = > try p .attr_application_buf .append (gpa , attr ),
907+ // zig fmt: on
908+ .transparent_union = > try attr .applyTransparentUnion (p , tok , base_qt ),
909+ .vector_size = > try attr .applyVectorSize (p , tok , & base_qt ),
910+ .aligned = > try attr .applyAligned (p , base_qt , diagnostic ),
911+ .designated_init = > if (base_qt .is (p .comp , .@"struct" )) {
912+ try p .attr_application_buf .append (gpa , attr );
913+ } else {
914+ try p .err (tok , .designated_init_invalid , .{});
915+ },
916+ .calling_convention = > try applyCallingConvention (attr , p , tok , base_qt ),
917+ .alloc_size ,
918+ .copy ,
919+ .scalar_storage_order ,
920+ .nonstring ,
921+ = > | t | try p .err (tok , .attribute_todo , .{ @tagName (t ), "types" }),
922+ else = > try ignoredAttrErr (p , tok , attr .tag , "types" ),
923+ }
924+ }
920925 return applySelected (base_qt , p );
921926}
922927
@@ -935,7 +940,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
935940 .noreturn , .unused , .used , .warning , .deprecated , .unavailable , .weak , .pure , .leaf ,
936941 .@"const" , .warn_unused_result , .section , .returns_nonnull , .returns_twice , .@"error" ,
937942 .externally_visible , .retain , .flatten , .gnu_inline , .alias , .asm_label , .nodiscard ,
938- .reproducible , .unsequenced , .nothrow , .nullability , .unaligned ,
943+ .reproducible , .unsequenced , .nothrow , .nullability , .unaligned , .internal_linkage ,
939944 = > try p .attr_application_buf .append (gpa , attr ),
940945 // zig fmt: on
941946 .hot = > if (cold ) {
@@ -1164,7 +1169,7 @@ pub fn applyStatementAttributes(p: *Parser, expr_start: TokenIndex, attr_buf_sta
11641169 try p .attr_application_buf .append (p .comp .gpa , attr );
11651170 break ;
11661171 },
1167- .r_brace = > {},
1172+ .r_brace , .semicolon = > {},
11681173 else = > {
11691174 try p .err (expr_start , .invalid_fallthrough , .{});
11701175 break ;
0 commit comments