zig fmt: Fix edge case in inline asm parsing

The presence of a trailing comma in the single and only input/output
declaration confused the parser and made zig fmt discard any element
placed after the comma.
This commit is contained in:
LemonBoy 2021-05-04 19:29:25 +02:00 committed by Andrew Kelley
parent 70a9a3a562
commit e863204c47
2 changed files with 45 additions and 7 deletions

View File

@ -1979,20 +1979,26 @@ pub const Tree = struct {
// asm ("foo" :: [_] "" (y) : "a", "b"); // asm ("foo" :: [_] "" (y) : "a", "b");
const last_input = result.inputs[result.inputs.len - 1]; const last_input = result.inputs[result.inputs.len - 1];
const rparen = tree.lastToken(last_input); const rparen = tree.lastToken(last_input);
if (token_tags[rparen + 1] == .colon and var i = rparen + 1;
token_tags[rparen + 2] == .string_literal) // Allow a (useless) comma right after the closing parenthesis.
if (token_tags[i] == .comma) i += 1;
if (token_tags[i] == .colon and
token_tags[i + 1] == .string_literal)
{ {
result.first_clobber = rparen + 2; result.first_clobber = i + 1;
} }
} else { } else {
// asm ("foo" : [_] "" (x) :: "a", "b"); // asm ("foo" : [_] "" (x) :: "a", "b");
const last_output = result.outputs[result.outputs.len - 1]; const last_output = result.outputs[result.outputs.len - 1];
const rparen = tree.lastToken(last_output); const rparen = tree.lastToken(last_output);
if (token_tags[rparen + 1] == .colon and var i = rparen + 1;
token_tags[rparen + 2] == .colon and // Allow a (useless) comma right after the closing parenthesis.
token_tags[rparen + 3] == .string_literal) if (token_tags[i] == .comma) i += 1;
if (token_tags[i] == .colon and
token_tags[i + 1] == .colon and
token_tags[i + 2] == .string_literal)
{ {
result.first_clobber = rparen + 3; result.first_clobber = i + 2;
} }
} }

View File

@ -4,6 +4,38 @@
// The MIT license requires this copyright notice to be included in all copies // The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software. // and substantial portions of the software.
test "zig fmt: preserves clobbers in inline asm with stray comma" {
try testTransform(
\\fn foo() void {
\\ asm volatile (""
\\ : [_] "" (-> type),
\\ :
\\ : "clobber"
\\ );
\\ asm volatile (""
\\ :
\\ : [_] "" (type),
\\ : "clobber"
\\ );
\\}
\\
,
\\fn foo() void {
\\ asm volatile (""
\\ : [_] "" (-> type)
\\ :
\\ : "clobber"
\\ );
\\ asm volatile (""
\\ :
\\ : [_] "" (type)
\\ : "clobber"
\\ );
\\}
\\
);
}
test "zig fmt: respect line breaks in struct field value declaration" { test "zig fmt: respect line breaks in struct field value declaration" {
try testCanonical( try testCanonical(
\\const Foo = struct { \\const Foo = struct {