Fix edge case in hex-literal translation

This commit is contained in:
LemonBoy 2020-01-04 11:06:28 +01:00
parent 6ea193946d
commit 51e430fac0
3 changed files with 37 additions and 12 deletions

View File

@ -659,6 +659,16 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
try failDecl(ctx, loc, name, "macro tokenizing failed: invalid digit '{c}' in octal number", .{c});
return error.TokenizingFailed;
},
'u', 'U' => {
state = .NumLitIntSuffixU;
result.num_lit_suffix = .U;
result.bytes = chars[begin_index..i.*];
},
'l', 'L' => {
state = .NumLitIntSuffixL;
result.num_lit_suffix = .L;
result.bytes = chars[begin_index..i.*];
},
else => {
result.bytes = chars[begin_index..i.*];
return result;

View File

@ -2125,7 +2125,8 @@ fn transForLoop(
block_scope = try Scope.Block.init(rp.c, scope, null);
block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);
loop_scope.parent = &block_scope.?.base;
_ = try transStmt(rp, &loop_scope, init, .unused, .r_value);
const init_stmt = try transStmt(rp, &loop_scope, init, .unused, .r_value);
try block_scope.?.block_node.statements.push(init_stmt);
}
var cond_scope = Scope{
.parent = scope,
@ -4720,18 +4721,26 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou
fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
if (tok.id == .NumLitInt) {
if (tok.num_lit_suffix == .None) {
if (tok.bytes.len > 2 and tok.bytes[0] == '0') {
switch (tok.bytes[1]) {
'0'...'7' => {
// octal
return transCreateNodeInt(c, try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes}));
},
else => {},
}
var lit_bytes = tok.bytes;
if (tok.bytes.len > 2 and tok.bytes[0] == '0') {
switch (tok.bytes[1]) {
'0'...'7' => {
// Octal
lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes});
},
'X' => {
// Hexadecimal with capital X, valid in C but not in Zig
lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{tok.bytes[2..]});
},
else => {},
}
return transCreateNodeInt(c, tok.bytes);
}
if (tok.num_lit_suffix == .None) {
return transCreateNodeInt(c, lit_bytes);
}
const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) {
.U => "c_uint",
@ -4742,7 +4751,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P
else => unreachable,
}));
_ = try appendToken(c, .Comma, ",");
try cast_node.params.push(try transCreateNodeInt(c, tok.bytes));
try cast_node.params.push(try transCreateNodeInt(c, lit_bytes));
cast_node.rparen_token = try appendToken(c, .RParen, ")");
return &cast_node.base;
} else if (tok.id == .NumLitFloat) {

View File

@ -2,6 +2,12 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("#define hex literal with capital X",
\\#define VAL 0XF00D
, &[_][]const u8{
\\pub const VAL = 0xF00D;
});
cases.add("union initializer",
\\union { int x; char c[4]; }
\\ ua = {1},