mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
translate-c-2 various fixes
- make non-namespaced enums ints - fix .used compound assignments not being grouped - fix macro calls with casts producing invalid Zig
This commit is contained in:
parent
40f607d195
commit
9d31b65b34
@ -30,6 +30,7 @@ pub const CToken = struct {
|
||||
Arrow,
|
||||
LBrace,
|
||||
RBrace,
|
||||
Pipe,
|
||||
};
|
||||
|
||||
pub const NumLitSuffix = enum {
|
||||
@ -360,6 +361,10 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
||||
result.id = .RBrace;
|
||||
state = .Done;
|
||||
},
|
||||
'|' => {
|
||||
result.id = .Pipe;
|
||||
state = .Done;
|
||||
},
|
||||
else => return error.TokenizingFailed,
|
||||
}
|
||||
},
|
||||
|
||||
@ -781,7 +781,11 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
|
||||
_ = try appendToken(c, .Comma, ",");
|
||||
// In C each enum value is in the global namespace. So we put them there too.
|
||||
// At this point we can rely on the enum emitting successfully.
|
||||
try addEnumTopLevel(c, name, field_name, enum_val_name);
|
||||
const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
|
||||
tld_node.eq_token = try appendToken(c, .Equal, "=");
|
||||
tld_node.init_node = try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
|
||||
tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
try addTopLevelDecl(c, field_name, &tld_node.base);
|
||||
}
|
||||
container_node.rbrace_token = try appendToken(c, .RBrace, "}");
|
||||
|
||||
@ -797,25 +801,6 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
|
||||
return transCreateNodeIdentifier(c, name);
|
||||
}
|
||||
|
||||
fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void {
|
||||
const node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
|
||||
node.eq_token = try appendToken(c, .Equal, "=");
|
||||
const enum_ident = try transCreateNodeIdentifier(c, enum_name);
|
||||
const period_tok = try appendToken(c, .Period, ".");
|
||||
const field_ident = try transCreateNodeIdentifier(c, field_name);
|
||||
node.semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
|
||||
const field_access_node = try c.a().create(ast.Node.InfixOp);
|
||||
field_access_node.* = .{
|
||||
.op_token = period_tok,
|
||||
.lhs = enum_ident,
|
||||
.op = .Period,
|
||||
.rhs = field_ident,
|
||||
};
|
||||
node.init_node = &field_access_node.base;
|
||||
try addTopLevelDecl(c, field_name, &node.base);
|
||||
}
|
||||
|
||||
fn createAlias(c: *Context, alias: var) !void {
|
||||
const node = try transCreateNodeVarDecl(c, true, true, alias.alias);
|
||||
node.eq_token = try appendToken(c, .Equal, "=");
|
||||
@ -1570,6 +1555,15 @@ fn transCCast(
|
||||
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type));
|
||||
return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr);
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(dst_type) == .Enum)
|
||||
{
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
|
||||
try builtin_node.params.push(try transQualType(rp, dst_type, loc));
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
try builtin_node.params.push(expr);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
return &builtin_node.base;
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(src_type) == .Enum and
|
||||
ZigClangQualType_getTypeClass(dst_type) != .Enum)
|
||||
{
|
||||
@ -2326,7 +2320,13 @@ fn transCreatePreCrement(
|
||||
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
|
||||
// semicolon must immediately follow rbrace because it is the last token in a block
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
return &block_scope.block_node.base;
|
||||
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
|
||||
grouped_expr.* = .{
|
||||
.lparen = try appendToken(rp.c, .LParen, "("),
|
||||
.expr = &block_scope.block_node.base,
|
||||
.rparen = try appendToken(rp.c, .RParen, ")"),
|
||||
};
|
||||
return &grouped_expr.base;
|
||||
}
|
||||
|
||||
fn transCreatePostCrement(
|
||||
@ -2392,7 +2392,13 @@ fn transCreatePostCrement(
|
||||
try block_scope.block_node.statements.push(&break_node.base);
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
|
||||
return &block_scope.block_node.base;
|
||||
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
|
||||
grouped_expr.* = .{
|
||||
.lparen = try appendToken(rp.c, .LParen, "("),
|
||||
.expr = &block_scope.block_node.base,
|
||||
.rparen = try appendToken(rp.c, .RParen, ")"),
|
||||
};
|
||||
return &grouped_expr.base;
|
||||
}
|
||||
|
||||
fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node {
|
||||
@ -2508,7 +2514,13 @@ fn transCreateCompoundAssign(
|
||||
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
|
||||
// semicolon must immediately follow rbrace because it is the last token in a block
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
return &block_scope.block_node.base;
|
||||
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
|
||||
grouped_expr.* = .{
|
||||
.lparen = try appendToken(rp.c, .LParen, "("),
|
||||
.expr = &block_scope.block_node.base,
|
||||
.rparen = try appendToken(rp.c, .RParen, ")"),
|
||||
};
|
||||
return &grouped_expr.base;
|
||||
}
|
||||
|
||||
fn transCPtrCast(
|
||||
@ -4314,7 +4326,10 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc:
|
||||
|
||||
if (it.peek().?.id == .RParen) {
|
||||
_ = it.next();
|
||||
return inner_node;
|
||||
if (it.peek().?.id != .LParen) {
|
||||
return inner_node;
|
||||
}
|
||||
_ = it.next();
|
||||
}
|
||||
|
||||
// hack to get zig fmt to render a comma in builtin calls
|
||||
@ -4458,7 +4473,7 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
||||
},
|
||||
.Shl => {
|
||||
const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<");
|
||||
const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope);
|
||||
const rhs = try parseCExpr(rp, it, source_loc, scope);
|
||||
const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||
bitshift_node.* = .{
|
||||
.op_token = op_token,
|
||||
@ -4468,9 +4483,21 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
||||
};
|
||||
node = &bitshift_node.base;
|
||||
},
|
||||
.Pipe => {
|
||||
const op_token = try appendToken(rp.c, .Pipe, "|");
|
||||
const rhs = try parseCExpr(rp, it, source_loc, scope);
|
||||
const or_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||
or_node.* = .{
|
||||
.op_token = op_token,
|
||||
.lhs = node,
|
||||
.op = .BitOr,
|
||||
.rhs = rhs,
|
||||
};
|
||||
node = &or_node.base;
|
||||
},
|
||||
.LBrace => {
|
||||
const arr_node = try transCreateNodeArrayAccess(rp.c, node);
|
||||
arr_node.op.ArrayAccess = try parseCPrimaryExpr(rp, it, source_loc, scope);
|
||||
arr_node.op.ArrayAccess = try parseCExpr(rp, it, source_loc, scope);
|
||||
arr_node.rtoken = try appendToken(rp.c, .RBrace, "]");
|
||||
node = &arr_node.base;
|
||||
if (it.next().?.id != .RBrace)
|
||||
|
||||
@ -166,50 +166,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add_both("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA,
|
||||
\\ FooB,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ @"1",
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
,
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
,
|
||||
\\pub const Foo1 = enum_Foo.@"1";
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
cases.add_both("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA = 2,
|
||||
\\ FooB = 5,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A = 2,
|
||||
\\ B = 5,
|
||||
\\ @"1" = 6,
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
,
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
,
|
||||
\\pub const Foo1 = enum_Foo.@"1";
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
cases.add_both("typedef of function in struct field",
|
||||
\\typedef void lws_callback_function(void);
|
||||
\\struct Foo {
|
||||
@ -921,27 +877,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ p,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const a = enum_unnamed_1.a;
|
||||
\\pub const b = enum_unnamed_1.b;
|
||||
\\pub const c = enum_unnamed_1.c;
|
||||
\\pub const a = 0;
|
||||
\\pub const b = 1;
|
||||
\\pub const c = 2;
|
||||
\\const enum_unnamed_1 = extern enum {
|
||||
\\ a,
|
||||
\\ b,
|
||||
\\ c,
|
||||
\\};
|
||||
\\pub const d = enum_unnamed_1;
|
||||
\\pub const e = enum_unnamed_2.e;
|
||||
\\pub const f = enum_unnamed_2.f;
|
||||
\\pub const g = enum_unnamed_2.g;
|
||||
\\pub const e = 0;
|
||||
\\pub const f = 4;
|
||||
\\pub const g = 5;
|
||||
\\const enum_unnamed_2 = extern enum {
|
||||
\\ e = 0,
|
||||
\\ f = 4,
|
||||
\\ g = 5,
|
||||
\\};
|
||||
\\pub export var h: enum_unnamed_2 = @as(enum_unnamed_2, e);
|
||||
\\pub const i = enum_unnamed_3.i;
|
||||
\\pub const j = enum_unnamed_3.j;
|
||||
\\pub const k = enum_unnamed_3.k;
|
||||
\\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e);
|
||||
\\pub const i = 0;
|
||||
\\pub const j = 1;
|
||||
\\pub const k = 2;
|
||||
\\const enum_unnamed_3 = extern enum {
|
||||
\\ i,
|
||||
\\ j,
|
||||
@ -951,9 +907,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ l: enum_unnamed_3,
|
||||
\\ m: d,
|
||||
\\};
|
||||
\\pub const n = enum_i.n;
|
||||
\\pub const o = enum_i.o;
|
||||
\\pub const p = enum_i.p;
|
||||
\\pub const n = 0;
|
||||
\\pub const o = 1;
|
||||
\\pub const p = 2;
|
||||
\\pub const enum_i = extern enum {
|
||||
\\ n,
|
||||
\\ o,
|
||||
@ -1393,8 +1349,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ Two,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const One = enum_unnamed_1.One;
|
||||
\\pub const Two = enum_unnamed_1.Two;
|
||||
\\pub const One = 0;
|
||||
\\pub const Two = 1;
|
||||
\\const enum_unnamed_1 = extern enum {
|
||||
\\ One,
|
||||
\\ Two,
|
||||
@ -1496,9 +1452,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
\\pub const FooC = enum_Foo.C;
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
@ -1509,7 +1462,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var a = _arg_a;
|
||||
\\ var b = _arg_b;
|
||||
\\ var c = _arg_c;
|
||||
\\ var d: enum_Foo = @as(enum_Foo, FooA);
|
||||
\\ var d: enum_Foo = @intToEnum(enum_Foo, FooA);
|
||||
\\ var e: c_int = @boolToInt(((a != 0) and (b != 0)));
|
||||
\\ var f: c_int = @boolToInt(((b != 0) and (c != null)));
|
||||
\\ var g: c_int = @boolToInt(((a != 0) and (c != null)));
|
||||
@ -1543,8 +1496,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ x: c_int,
|
||||
\\ y: c_int,
|
||||
\\};
|
||||
\\pub const BarA = enum_Bar.A;
|
||||
\\pub const BarB = enum_Bar.B;
|
||||
,
|
||||
\\pub const enum_Bar = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
@ -1746,9 +1698,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return 4;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const A = enum_SomeEnum.A;
|
||||
\\pub const B = enum_SomeEnum.B;
|
||||
\\pub const C = enum_SomeEnum.C;
|
||||
\\pub const enum_SomeEnum = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
@ -1863,26 +1812,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
\\ u -%= 1;
|
||||
\\ i = blk: {
|
||||
\\ i = (blk: {
|
||||
\\ const _ref_1 = &i;
|
||||
\\ _ref_1.* += 1;
|
||||
\\ break :blk _ref_1.*;
|
||||
\\ };
|
||||
\\ i = blk: {
|
||||
\\ });
|
||||
\\ i = (blk: {
|
||||
\\ const _ref_2 = &i;
|
||||
\\ _ref_2.* -= 1;
|
||||
\\ break :blk _ref_2.*;
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ const _ref_3 = &u;
|
||||
\\ _ref_3.* +%= 1;
|
||||
\\ break :blk _ref_3.*;
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ const _ref_4 = &u;
|
||||
\\ _ref_4.* -%= 1;
|
||||
\\ break :blk _ref_4.*;
|
||||
\\ };
|
||||
\\ });
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -2062,30 +2011,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
\\ u -%= 1;
|
||||
\\ i = blk: {
|
||||
\\ i = (blk: {
|
||||
\\ const _ref_1 = &i;
|
||||
\\ const _tmp_2 = _ref_1.*;
|
||||
\\ _ref_1.* += 1;
|
||||
\\ break :blk _tmp_2;
|
||||
\\ };
|
||||
\\ i = blk: {
|
||||
\\ });
|
||||
\\ i = (blk: {
|
||||
\\ const _ref_3 = &i;
|
||||
\\ const _tmp_4 = _ref_3.*;
|
||||
\\ _ref_3.* -= 1;
|
||||
\\ break :blk _tmp_4;
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ const _ref_5 = &u;
|
||||
\\ const _tmp_6 = _ref_5.*;
|
||||
\\ _ref_5.* +%= 1;
|
||||
\\ break :blk _tmp_6;
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ const _ref_7 = &u;
|
||||
\\ const _tmp_8 = _ref_7.*;
|
||||
\\ _ref_7.* -%= 1;
|
||||
\\ break :blk _tmp_8;
|
||||
\\ };
|
||||
\\ });
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -2172,6 +2121,58 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const FOO_CHAR = '\x3f';
|
||||
});
|
||||
|
||||
cases.add_2("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA,
|
||||
\\ FooB,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ @"1",
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = 0;
|
||||
,
|
||||
\\pub const FooB = 1;
|
||||
,
|
||||
\\pub const Foo1 = 2;
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
cases.add_2("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA = 2,
|
||||
\\ FooB = 5,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A = 2,
|
||||
\\ B = 5,
|
||||
\\ @"1" = 6,
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = 2;
|
||||
,
|
||||
\\pub const FooB = 5;
|
||||
,
|
||||
\\pub const Foo1 = 6;
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
cases.add_2("macro cast",
|
||||
\\#define FOO(bar) baz((void *)(baz))
|
||||
, &[_][]const u8{
|
||||
\\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz))) {
|
||||
\\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz));
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases for only stage1 because stage2 behavior is better ////////////////
|
||||
cases.addC("Parameterless function prototypes",
|
||||
\\void foo() {}
|
||||
@ -3124,4 +3125,48 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub const FOO_CHAR = 63;
|
||||
});
|
||||
|
||||
cases.add("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA,
|
||||
\\ FooB,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ @"1",
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
,
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
,
|
||||
\\pub const Foo1 = enum_Foo.@"1";
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
cases.add("enums",
|
||||
\\enum Foo {
|
||||
\\ FooA = 2,
|
||||
\\ FooB = 5,
|
||||
\\ Foo1,
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A = 2,
|
||||
\\ B = 5,
|
||||
\\ @"1" = 6,
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
,
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
,
|
||||
\\pub const Foo1 = enum_Foo.@"1";
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user