translate-c treat c bools as ints

This commit is contained in:
Vexu 2020-03-12 14:18:41 +02:00
parent f58705b4a6
commit dda711ba0d
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 71 additions and 5 deletions

View File

@ -560,7 +560,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
// TODO https://github.com/ziglang/zig/issues/3756 // TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802 // TODO https://github.com/ziglang/zig/issues/1802
const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{var_name, c.getMangle()}) else var_name; const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ var_name, c.getMangle() }) else var_name;
const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
@ -677,7 +677,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
// TODO https://github.com/ziglang/zig/issues/3756 // TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802 // TODO https://github.com/ziglang/zig/issues/1802
const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{typedef_name, c.getMangle()}) else typedef_name; const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
if (mem.eql(u8, checked_name, "uint8_t")) if (mem.eql(u8, checked_name, "uint8_t"))
return transTypeDefAsBuiltin(c, typedef_decl, "u8") return transTypeDefAsBuiltin(c, typedef_decl, "u8")
@ -4871,7 +4871,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
const name = try c.str(raw_name); const name = try c.str(raw_name);
// TODO https://github.com/ziglang/zig/issues/3756 // TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802 // TODO https://github.com/ziglang/zig/issues/1802
const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{name, c.getMangle()}) else name; const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() }) else name;
if (scope.containsNow(mangled_name)) { if (scope.containsNow(mangled_name)) {
continue; continue;
} }
@ -5560,12 +5560,63 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
} }
} }
fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
if (!isBoolRes(node)) {
if (node.id != .InfixOp) return node;
const group_node = try c.a().create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = node,
.rparen = try appendToken(c, .RParen, ")"),
};
return &group_node.base;
}
const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt");
try builtin_node.params.push(node);
builtin_node.rparen_token = try appendToken(c, .RParen, ")");
return &builtin_node.base;
}
fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
if (isBoolRes(node)) {
if (node.id != .InfixOp) return node;
const group_node = try c.a().create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = node,
.rparen = try appendToken(c, .RParen, ")"),
};
return &group_node.base;
}
const op_token = try appendToken(c, .BangEqual, "!=");
const zero = try transCreateNodeInt(c, 0);
const res = try c.a().create(ast.Node.InfixOp);
res.* = .{
.op_token = op_token,
.lhs = node,
.op = .BangEqual,
.rhs = zero,
};
const group_node = try c.a().create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = &res.base,
.rparen = try appendToken(c, .RParen, ")"),
};
return &group_node.base;
}
fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
var node = try parseCPrimaryExpr(c, it, source, source_loc, scope); var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);
while (true) { while (true) {
const tok = it.next().?; const tok = it.next().?;
var op_token: ast.TokenIndex = undefined; var op_token: ast.TokenIndex = undefined;
var op_id: ast.Node.InfixOp.Op = undefined; var op_id: ast.Node.InfixOp.Op = undefined;
var bool_op = false;
switch (tok.id) { switch (tok.id) {
.Period => { .Period => {
const name_tok = it.next().?; const name_tok = it.next().?;
@ -5654,10 +5705,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.AmpersandAmpersand => { .AmpersandAmpersand => {
op_token = try appendToken(c, .Keyword_and, "and"); op_token = try appendToken(c, .Keyword_and, "and");
op_id = .BoolAnd; op_id = .BoolAnd;
bool_op = true;
}, },
.PipePipe => { .PipePipe => {
op_token = try appendToken(c, .Keyword_or, "or"); op_token = try appendToken(c, .Keyword_or, "or");
op_id = .BoolOr; op_id = .BoolOr;
bool_op = true;
}, },
.AngleBracketRight => { .AngleBracketRight => {
op_token = try appendToken(c, .AngleBracketRight, ">"); op_token = try appendToken(c, .AngleBracketRight, ">");
@ -5740,12 +5793,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
return node; return node;
}, },
} }
const rhs_node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
const op_node = try c.a().create(ast.Node.InfixOp); const op_node = try c.a().create(ast.Node.InfixOp);
const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt;
op_node.* = .{ op_node.* = .{
.op_token = op_token, .op_token = op_token,
.lhs = node, .lhs = try cast_fn(c, node),
.op = op_id, .op = op_id,
.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope), .rhs = try cast_fn(c, rhs_node),
}; };
node = &op_node.base; node = &op_node.base;
} }

View File

@ -3,6 +3,17 @@ const std = @import("std");
const CrossTarget = std.zig.CrossTarget; const CrossTarget = std.zig.CrossTarget;
pub fn addCases(cases: *tests.TranslateCContext) void { pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("c booleans are just ints",
\\#define FOO(x) ((x >= 0) + (x >= 0))
\\#define BAR 1 && 2 > 4
, &[_][]const u8{
\\pub inline fn FOO(x: var) @TypeOf(@boolToInt(x >= 0) + @boolToInt(x >= 0)) {
\\ return @boolToInt(x >= 0) + @boolToInt(x >= 0);
\\}
,
\\pub const BAR = (1 != 0) and (2 > 4);
});
cases.add("struct with aligned fields", cases.add("struct with aligned fields",
\\struct foo { \\struct foo {
\\ __attribute__((aligned(1))) short bar; \\ __attribute__((aligned(1))) short bar;