std.zig.render: handle legacy clobber updating more gracefully

"that's really easy to handle correctly" he said
This commit is contained in:
Andrew Kelley
2025-07-15 16:10:36 -07:00
parent 15f45e89a7
commit 54f073377c
2 changed files with 81 additions and 23 deletions

View File

@@ -32,7 +32,7 @@ test "zig fmt: tuple struct" {
}
test "zig fmt: preserves clobbers in inline asm with stray comma" {
try testCanonical(
try testTransform(
\\fn foo() void {
\\ asm volatile (""
\\ : [_] "" (-> type),
@@ -46,6 +46,20 @@ test "zig fmt: preserves clobbers in inline asm with stray comma" {
\\ );
\\}
\\
,
\\fn foo() void {
\\ asm volatile (""
\\ : [_] "" (-> type),
\\ :
\\ : .{ .clobber = true }
\\ );
\\ asm volatile (""
\\ :
\\ : [_] "" (type),
\\ : .{ .clobber = true }
\\ );
\\}
\\
);
}
@@ -64,7 +78,7 @@ test "zig fmt: remove trailing comma at the end of assembly clobber" {
\\ asm volatile (""
\\ : [_] "" (-> type),
\\ :
\\ : "clobber1", "clobber2"
\\ : .{ .clobber1 = true, .clobber2 = true }
\\ );
\\}
\\
@@ -628,7 +642,7 @@ test "zig fmt: builtin call with trailing comma" {
}
test "zig fmt: asm expression with comptime content" {
try testCanonical(
try testTransform(
\\comptime {
\\ asm ("foo" ++ "bar");
\\}
@@ -648,6 +662,26 @@ test "zig fmt: asm expression with comptime content" {
\\ );
\\}
\\
,
\\comptime {
\\ asm ("foo" ++ "bar");
\\}
\\pub fn main() void {
\\ asm volatile ("foo" ++ "bar");
\\ asm volatile ("foo" ++ "bar"
\\ : [_] "" (x),
\\ );
\\ asm volatile ("foo" ++ "bar"
\\ : [_] "" (x),
\\ : [_] "" (y),
\\ );
\\ asm volatile ("foo" ++ "bar"
\\ : [_] "" (x),
\\ : [_] "" (y),
\\ : .{ .h = true, .e = true, .l = true, .l = true, .o = true }
\\ );
\\}
\\
);
}
@@ -2182,7 +2216,7 @@ test "zig fmt: simple asm" {
\\ : [a] "x" (-> i32),
\\ : [a] "x" (1),
\\ );
\\ asm ("still not real assembly" ::: "a", "b");
\\ asm ("still not real assembly" ::: .{ .a = true, .b = true });
\\}
\\
);
@@ -3907,7 +3941,7 @@ test "zig fmt: fn type" {
}
test "zig fmt: inline asm" {
try testCanonical(
try testTransform(
\\pub fn syscall1(number: usize, arg1: usize) usize {
\\ return asm volatile ("syscall"
\\ : [ret] "={rax}" (-> usize),
@@ -3917,6 +3951,16 @@ test "zig fmt: inline asm" {
\\ );
\\}
\\
,
\\pub fn syscall1(number: usize, arg1: usize) usize {
\\ return asm volatile ("syscall"
\\ : [ret] "={rax}" (-> usize),
\\ : [number] "{rax}" (number),
\\ [arg1] "{rdi}" (arg1),
\\ : .{ .rcx = true, .r11 = true }
\\ );
\\}
\\
);
}
@@ -3998,7 +4042,7 @@ test "zig fmt: inline asm parameter alignment" {
\\ asm volatile (
\\ \\ foo
\\ \\ bar
\\ ::: "", "");
\\ ::: .{ .a = true, .b = true });
\\ asm volatile (
\\ \\ foo
\\ \\ bar
@@ -4006,8 +4050,7 @@ test "zig fmt: inline asm parameter alignment" {
\\ [_] "" (-> usize),
\\ : [_] "" (0),
\\ [_] "" (0),
\\ : "", ""
\\ );
\\ : .{});
\\}
\\
);
@@ -5325,7 +5368,7 @@ test "zig fmt: make single-line if no trailing comma, fmt: off" {
\\ asm ("not real assembly"
\\ :[a] "x" (->i32),:[a] "x" (1),);
\\ asm volatile ("still not real assembly"
\\ :::"a","b",);
\\ :::.{.a = true,.b = true,});
\\ }
\\}
);
@@ -5737,7 +5780,7 @@ test "zig fmt: canonicalize symbols (asm)" {
\\ [@"arg1"] "{rdi}" (arg),
\\ [arg2] "{rsi}" (arg),
\\ [arg3] "{rdx}" (arg),
\\ : "rcx", "r11"
\\ : "rcx", "fn"
\\ );
\\
\\ const @"false": usize = 10;
@@ -5759,7 +5802,7 @@ test "zig fmt: canonicalize symbols (asm)" {
\\ [arg1] "{rdi}" (arg),
\\ [arg2] "{rsi}" (arg),
\\ [arg3] "{rdx}" (arg),
\\ : "rcx", "r11"
\\ : .{ .rcx = true, .@"fn" = true }
\\ );
\\
\\ const @"false": usize = 10;

View File

@@ -2398,8 +2398,8 @@ fn renderAsmLegacy(
var tok_i = first_clobber;
while (true) : (tok_i += 1) {
try ais.writer().writeAll(".@");
try ais.writer().writeAll(tokenSliceForRender(tree, tok_i));
try ais.writer().writeByte('.');
_ = try writeStringLiteralAsIdentifier(r, tok_i);
try ais.writer().writeAll(" = true");
tok_i += 1;
@@ -2411,6 +2411,7 @@ fn renderAsmLegacy(
},
.comma => {
if (tree.tokenTag(tok_i + 1) == .r_paren) {
try ais.writer().writeAll(" }");
ais.popIndent();
return renderToken(r, tok_i + 1, space);
} else {
@@ -2512,11 +2513,10 @@ fn renderAsmLegacy(
switch (tree.tokenTag(tok_i + 1)) {
.r_paren => {
ais.setIndentDelta(indent_delta);
try ais.writer().writeAll(".@");
const lexeme = tokenSliceForRender(tree, tok_i);
try ais.writer().writeAll(lexeme);
try ais.writer().writeByte('.');
const lexeme_len = try writeStringLiteralAsIdentifier(r, tok_i);
try ais.writer().writeAll(" = true }");
try renderSpace(r, tok_i, lexeme.len, .newline);
try renderSpace(r, tok_i, lexeme_len, .newline);
ais.popIndent();
return renderToken(r, tok_i + 1, space);
},
@@ -2524,17 +2524,16 @@ fn renderAsmLegacy(
switch (tree.tokenTag(tok_i + 2)) {
.r_paren => {
ais.setIndentDelta(indent_delta);
try ais.writer().writeAll(".@");
const lexeme = tokenSliceForRender(tree, tok_i);
try ais.writer().writeAll(lexeme);
try ais.writer().writeByte('.');
const lexeme_len = try writeStringLiteralAsIdentifier(r, tok_i);
try ais.writer().writeAll(" = true }");
try renderSpace(r, tok_i, lexeme.len, .newline);
try renderSpace(r, tok_i, lexeme_len, .newline);
ais.popIndent();
return renderToken(r, tok_i + 2, space);
},
else => {
try ais.writer().writeAll(".@");
try ais.writer().writeAll(tokenSliceForRender(tree, tok_i));
try ais.writer().writeByte('.');
_ = try writeStringLiteralAsIdentifier(r, tok_i);
try ais.writer().writeAll(" = true");
try renderToken(r, tok_i + 1, .space);
tok_i += 2;
@@ -3232,6 +3231,22 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 {
return ret;
}
fn writeStringLiteralAsIdentifier(r: *Render, token_index: Ast.TokenIndex) !usize {
const tree = r.tree;
const ais = r.ais;
assert(tree.tokenTag(token_index) == .string_literal);
const lexeme = tokenSliceForRender(tree, token_index);
const unquoted = lexeme[1..][0 .. lexeme.len - 2];
if (std.zig.isValidId(unquoted)) {
try ais.writer().writeAll(unquoted);
return unquoted.len;
} else {
try ais.writer().writeByte('@');
try ais.writer().writeAll(lexeme);
return lexeme.len + 1;
}
}
fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool {
const between_source = tree.source[tree.tokenStart(token_index)..tree.tokenStart(token_index + 1)];
for (between_source) |byte| switch (byte) {