Skip to content

Commit d133bdc

Browse files
committed
translate-c: implement a switch block-scope
should fix ziglang/zig#14809
1 parent 7f71a84 commit d133bdc

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

src/translate_c.zig

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3300,8 +3300,11 @@ fn transSwitch(
33003300
scope: *Scope,
33013301
stmt: *const clang.SwitchStmt,
33023302
) TransError!Node {
3303+
var outer_scope = try Scope.Block.init(c, scope, false);
3304+
defer outer_scope.deinit();
3305+
33033306
var loop_scope = Scope{
3304-
.parent = scope,
3307+
.parent = &outer_scope.base,
33053308
.id = .loop,
33063309
};
33073310

@@ -3471,6 +3474,9 @@ fn transSwitch(
34713474
try cases.append(switch_else);
34723475
}
34733476
},
3477+
.DeclStmtClass => {
3478+
_ = try transDeclStmt(c, &outer_scope.base, @ptrCast(it[0]), true);
3479+
},
34743480
else => {
34753481
if (required_enum) |*re| {
34763482
if (re.inner_stmt_to_enum_field.get(it[0])) |field_name| {
@@ -3540,7 +3546,9 @@ fn transSwitch(
35403546
try block_scope.?.statements.append(Tag.@"break".init());
35413547
const while_body = try block_scope.?.complete(c);
35423548

3543-
return Tag.while_true.create(c.arena, while_body);
3549+
try outer_scope.statements.append(try Tag.while_true.create(c.arena, while_body));
3550+
3551+
return outer_scope.complete(c);
35443552
}
35453553

35463554
/// Collects all items for this case, returns the first statement after the labels.
@@ -3658,6 +3666,9 @@ fn transSwitchProngStmtInline(
36583666
return;
36593667
}
36603668
},
3669+
.DeclStmtClass => {
3670+
try transDeclStmtAsAssignments(c, block, @ptrCast(it[0]));
3671+
},
36613672
else => {
36623673
const result = try transStmt(c, &block.base, it[0], .unused);
36633674
switch (result.tag()) {
@@ -5371,36 +5382,39 @@ fn transLabelStmt(c: *Context, scope: *Scope, stmt: *const clang.LabelStmt) Tran
53715382
}
53725383
}
53735384

5374-
fn transStmtToScopeAndExeBlock(c: *Context, scope: *Scope, exe_block: *Scope.Block, stmt: *const clang.Stmt) TransError!void {
5375-
if (stmt.getStmtClass() == .DeclStmtClass) {
5376-
const decl_stmt: *const clang.DeclStmt = @ptrCast(stmt);
5377-
_ = try transDeclStmt(c, scope, decl_stmt, true);
5385+
// fn transDeclStmt(c: *Context, scope: *Scope, stmt: *const clang.DeclStmt, late_init: bool) TransError!Node {
53785386

5379-
var it = decl_stmt.decl_begin();
5380-
const end_it = decl_stmt.decl_end();
5381-
while (it != end_it) : (it += 1) {
5382-
if (it[0].getKind() == .Var) {
5383-
const decl: *const clang.VarDecl = @ptrCast(it[0]);
5384-
const qual_type = decl.getTypeSourceInfo_getType();
5387+
fn transDeclStmtAsAssignments(c: *Context, block: *Scope.Block, stmt: *const clang.DeclStmt) TransError!void {
5388+
var it = stmt.decl_begin();
5389+
const end_it = stmt.decl_end();
5390+
while (it != end_it) : (it += 1) {
5391+
if (it[0].getKind() == .Var) {
5392+
const decl: *const clang.VarDecl = @ptrCast(it[0]);
5393+
const qual_type = decl.getTypeSourceInfo_getType();
53855394

5386-
if (decl.getStorageClass() != .Extern and !decl.isStaticLocal()) {
5387-
if (decl.getInit()) |init| {
5388-
const name = try c.str(@as(*const clang.NamedDecl, @ptrCast(decl)).getName_bytes_begin());
5395+
if (decl.getStorageClass() != .Extern and !decl.isStaticLocal()) {
5396+
if (decl.getInit()) |init| {
5397+
const name = try c.str(@as(*const clang.NamedDecl, @ptrCast(decl)).getName_bytes_begin());
53895398

5390-
var rhs_node = try transExprCoercing(c, &exe_block.base, init, .used);
5391-
if (!qualTypeIsBoolean(qual_type) and isBoolRes(rhs_node)) {
5392-
rhs_node = try Tag.int_from_bool.create(c.arena, rhs_node);
5393-
}
5394-
try exe_block.statements.append(
5395-
try transCreateNodeInfixOp(c, .assign, try Tag.identifier.create(c.arena, scope.getAlias(name)), rhs_node, .used),
5396-
);
5399+
var rhs_node = try transExprCoercing(c, &block.base, init, .used);
5400+
if (!qualTypeIsBoolean(qual_type) and isBoolRes(rhs_node)) {
5401+
rhs_node = try Tag.int_from_bool.create(c.arena, rhs_node);
53975402
}
5403+
try block.statements.append(
5404+
try transCreateNodeInfixOp(c, .assign, try Tag.identifier.create(c.arena, block.base.getAlias(name)), rhs_node, .used),
5405+
);
53985406
}
5399-
} else {
5400-
// the last two args of transDeclStmtOne are not used
5401-
try transDeclStmtOne(c, scope, it[0], undefined, undefined);
54025407
}
54035408
}
5409+
}
5410+
}
5411+
5412+
fn transStmtToScopeAndExeBlock(c: *Context, scope: *Scope, exe_block: *Scope.Block, stmt: *const clang.Stmt) TransError!void {
5413+
if (stmt.getStmtClass() == .DeclStmtClass) {
5414+
const decl_stmt: *const clang.DeclStmt = @ptrCast(stmt);
5415+
_ = try transDeclStmt(c, scope, decl_stmt, true);
5416+
5417+
try transDeclStmtAsAssignments(c, exe_block, @ptrCast(stmt));
54045418
} else {
54055419
const result = try transStmt(c, &exe_block.base, stmt, .unused);
54065420
if (result.tag() != .empty_block) {

0 commit comments

Comments
 (0)