Commit 2b28cebf64
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -3089,7 +3089,7 @@ fn transUnaryExprOrTypeTraitExpr(
.AlignOf => "@alignOf",
.PreferredAlignOf,
.VecStep,
- .OpenMPRequiredSimdAlign,
+ .OpenMPRequiredSimdAlign,
=> return revertAndWarn(
rp,
error.UnsupportedTranslation,
@@ -5220,26 +5220,32 @@ pub fn freeErrors(errors: []ClangErrMsg) void {
ZigClangErrorMsg_delete(errors.ptr, errors.len);
}
-const CTokIterator = struct {
+const MacroCtx = struct {
source: []const u8,
list: []const CToken,
i: usize = 0,
+ loc: ZigClangSourceLocation,
+ name: []const u8,
- fn peek(self: *CTokIterator) ?CToken.Id {
+ fn peek(self: *MacroCtx) ?CToken.Id {
if (self.i >= self.list.len) return null;
return self.list[self.i + 1].id;
}
- fn next(self: *CTokIterator) ?CToken.Id {
+ fn next(self: *MacroCtx) ?CToken.Id {
if (self.i >= self.list.len) return null;
self.i += 1;
return self.list[self.i].id;
}
- fn slice(self: *CTokIterator, index: usize) []const u8 {
- const tok = self.list[index];
+ fn slice(self: *MacroCtx) []const u8 {
+ const tok = self.list[self.i];
return self.source[tok.start..tok.end];
}
+
+ fn fail(self: *MacroCtx, c: *Context, comptime fmt: []const u8, args: anytype) !void {
+ return failDecl(c, self.loc, self.name, fmt, args);
+ }
};
fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
@@ -5286,18 +5292,21 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
try tok_list.append(tok);
}
- var tok_it = CTokIterator{
+ var macro_ctx = MacroCtx{
.source = slice,
.list = tok_list.items,
+ .name = mangled_name,
+ .loc = begin_loc,
};
- assert(mem.eql(u8, tok_it.slice(0), name));
+ assert(mem.eql(u8, macro_ctx.slice(), name));
var macro_fn = false;
- switch (tok_it.peek().?) {
+ switch (macro_ctx.peek().?) {
.Identifier => {
// if it equals itself, ignore. for example, from stdio.h:
// #define stdin stdin
- if (mem.eql(u8, name, tok_it.slice(1))) {
+ const tok = macro_ctx.list[1];
+ if (mem.eql(u8, name, slice[tok.start..tok.end])) {
continue;
}
},
@@ -5308,15 +5317,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
},
.LParen => {
// if the name is immediately followed by a '(' then it is a function
- macro_fn = tok_it.list[0].end == tok_it.list[1].start;
+ macro_fn = macro_ctx.list[0].end == macro_ctx.list[1].start;
},
else => {},
}
(if (macro_fn)
- transMacroFnDefine(c, &tok_it, mangled_name, begin_loc)
+ transMacroFnDefine(c, ¯o_ctx)
else
- transMacroDefine(c, &tok_it, mangled_name, begin_loc)) catch |err| switch (err) {
+ transMacroDefine(c, ¯o_ctx)) catch |err| switch (err) {
error.ParseError => continue,
error.OutOfMemory => |e| return e,
};
@@ -5326,24 +5335,18 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
}
}
-fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
+fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
const scope = &c.global_scope.base;
const visib_tok = try appendToken(c, .Keyword_pub, "pub");
const mut_tok = try appendToken(c, .Keyword_const, "const");
- const name_tok = try appendIdentifier(c, name);
+ const name_tok = try appendIdentifier(c, m.name);
const eq_token = try appendToken(c, .Equal, "=");
- const init_node = try parseCExpr(c, it, source_loc, scope);
- const last = it.next().?;
+ const init_node = try parseCExpr(c, m, scope);
+ const last = m.next().?;
if (last != .Eof and last != .Nl)
- return failDecl(
- c,
- source_loc,
- name,
- "unable to translate C expr: unexpected token .{}",
- .{@tagName(last)},
- );
+ return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)});
const semicolon_token = try appendToken(c, .Semicolon, ";");
const node = try ast.Node.VarDecl.create(c.arena, .{
@@ -5355,10 +5358,10 @@ fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc
.eq_token = eq_token,
.init_node = init_node,
});
- _ = try c.global_scope.macro_table.put(name, &node.base);
+ _ = try c.global_scope.macro_table.put(m.name, &node.base);
}
-fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
+fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
var block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
defer block_scope.deinit();
const scope = &block_scope.base;
@@ -5366,34 +5369,22 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
const pub_tok = try appendToken(c, .Keyword_pub, "pub");
const inline_tok = try appendToken(c, .Keyword_inline, "inline");
const fn_tok = try appendToken(c, .Keyword_fn, "fn");
- const name_tok = try appendIdentifier(c, name);
+ const name_tok = try appendIdentifier(c, m.name);
_ = try appendToken(c, .LParen, "(");
- if (it.next().? != .LParen) {
- return failDecl(
- c,
- source_loc,
- name,
- "unable to translate C expr: expected '('",
- .{},
- );
+ if (m.next().? != .LParen) {
+ return m.fail(c, "unable to translate C expr: expected '('", .{});
}
var fn_params = std.ArrayList(ast.Node.FnProto.ParamDecl).init(c.gpa);
defer fn_params.deinit();
while (true) {
- if (it.next().? != .Identifier) {
- return failDecl(
- c,
- source_loc,
- name,
- "unable to translate C expr: expected identifier",
- .{},
- );
+ if (m.next().? != .Identifier) {
+ return m.fail(c, "unable to translate C expr: expected identifier", .{});
}
- const mangled_name = try block_scope.makeMangledName(c, it.slice(it.i));
+ const mangled_name = try block_scope.makeMangledName(c, m.slice());
const param_name_tok = try appendIdentifier(c, mangled_name);
_ = try appendToken(c, .Colon, ":");
@@ -5411,20 +5402,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
.param_type = .{ .any_type = &any_type.base },
};
- if (it.peek().? != .Comma)
+ if (m.peek().? != .Comma)
break;
- _ = it.next();
+ _ = m.next();
_ = try appendToken(c, .Comma, ",");
}
- if (it.next().? != .RParen) {
- return failDecl(
- c,
- source_loc,
- name,
- "unable to translate C expr: expected ')'",
- .{},
- );
+ if (m.next().? != .RParen) {
+ return m.fail(c, "unable to translate C expr: expected ')'", .{});
}
_ = try appendToken(c, .RParen, ")");
@@ -5432,16 +5417,10 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
const type_of = try c.createBuiltinCall("@TypeOf", 1);
const return_kw = try appendToken(c, .Keyword_return, "return");
- const expr = try parseCExpr(c, it, source_loc, scope);
- const last = it.next().?;
+ const expr = try parseCExpr(c, m, scope);
+ const last = m.next().?;
if (last != .Eof and last != .Nl)
- return failDecl(
- c,
- source_loc,
- name,
- "unable to translate C expr: unexpected token .{}",
- .{@tagName(last)},
- );
+ return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)});
_ = try appendToken(c, .Semicolon, ";");
const type_of_arg = if (expr.tag != .Block) expr else blk: {
const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
@@ -5472,32 +5451,26 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
});
mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
- _ = try c.global_scope.macro_table.put(name, &fn_proto.base);
+ _ = try c.global_scope.macro_table.put(m.name, &fn_proto.base);
}
const ParseError = Error || error{ParseError};
-fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
- const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
- switch (it.next().?) {
+fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
+ const node = try parseCPrefixOpExpr(c, m, scope);
+ switch (m.next().?) {
.QuestionMark => {
// must come immediately after expr
_ = try appendToken(c, .RParen, ")");
const if_node = try transCreateNodeIf(c);
if_node.condition = node;
- if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope);
- if (it.next().? != .Colon) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ':'",
- .{},
- );
+ if_node.body = try parseCPrimaryExpr(c, m, scope);
+ if (m.next().? != .Colon) {
+ try m.fail(c, "unable to translate C expr: expected ':'", .{});
return error.ParseError;
}
if_node.@"else" = try transCreateNodeElse(c);
- if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope);
+ if_node.@"else".?.body = try parseCPrimaryExpr(c, m, scope);
return &if_node.base;
},
.Comma => {
@@ -5520,10 +5493,10 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation
};
try block_scope.statements.append(&op_node.base);
- last = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ last = try parseCPrefixOpExpr(c, m, scope);
_ = try appendToken(c, .Semicolon, ";");
- if (it.next().? != .Comma) {
- it.i -= 1;
+ if (m.next().? != .Comma) {
+ m.i -= 1;
break;
}
}
@@ -5534,16 +5507,16 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation
return &block_node.base;
},
else => {
- it.i -= 1;
+ m.i -= 1;
return node;
},
}
}
-fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
- var lit_bytes = it.slice(it.i);
+fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!*ast.Node {
+ var lit_bytes = m.slice();
- switch (it.list[it.i].id) {
+ switch (m.list[m.i].id) {
.IntegerLiteral => |suffix| {
if (lit_bytes.len > 2 and lit_bytes[0] == '0') {
switch (lit_bytes[1]) {
@@ -5604,8 +5577,8 @@ fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocati
}
}
-fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ![]const u8 {
- var source = source_bytes;
+fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
+ var source = m.slice();
for (source) |c, i| {
if (c == '\"' or c == '\'') {
source = source[i..];
@@ -5677,11 +5650,11 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
bytes[i] = '?';
},
'u', 'U' => {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: TODO unicode escape sequences", .{});
+ try m.fail(ctx, "macro tokenizing failed: TODO unicode escape sequences", .{});
return error.ParseError;
},
else => {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: unknown escape sequence", .{});
+ try m.fail(ctx, "macro tokenizing failed: unknown escape sequence", .{});
return error.ParseError;
},
}
@@ -5700,21 +5673,21 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
switch (c) {
'0'...'9' => {
num = std.math.mul(u8, num, 16) catch {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
+ try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
return error.ParseError;
};
num += c - '0';
},
'a'...'f' => {
num = std.math.mul(u8, num, 16) catch {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
+ try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
return error.ParseError;
};
num += c - 'a' + 10;
},
'A'...'F' => {
num = std.math.mul(u8, num, 16) catch {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
+ try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
return error.ParseError;
};
num += c - 'A' + 10;
@@ -5741,7 +5714,7 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
if (accept_digit) {
count += 1;
num = std.math.mul(u8, num, 8) catch {
- try failDecl(ctx, source_loc, name, "macro tokenizing failed: octal literal overflowed", .{});
+ try m.fail(ctx, "macro tokenizing failed: octal literal overflowed", .{});
return error.ParseError;
};
num += c - '0';
@@ -5764,13 +5737,13 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
return bytes[0..i];
}
-fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
- const tok = it.next().?;
- const slice = it.slice(it.i);
+fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
+ const tok = m.next().?;
+ const slice = m.slice();
switch (tok) {
.CharLiteral => {
if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
- const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
+ const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, m));
const node = try c.arena.create(ast.Node.OneToken);
node.* = .{
.base = .{ .tag = .CharLiteral },
@@ -5788,7 +5761,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
}
},
.StringLiteral => {
- const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
+ const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, m));
const node = try c.arena.create(ast.Node.OneToken);
node.* = .{
.base = .{ .tag = .StringLiteral },
@@ -5797,7 +5770,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
return &node.base;
},
.IntegerLiteral, .FloatLiteral => {
- return parseCNumLit(c, it, source_loc);
+ return parseCNumLit(c, m);
},
// eventually this will be replaced by std.c.parse which will handle these correctly
.Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
@@ -5808,61 +5781,55 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
.Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
.Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
.Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
- .Keyword_unsigned => if (it.next()) |t| switch (t) {
+ .Keyword_unsigned => if (m.next()) |t| switch (t) {
.Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
.Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_ushort"),
.Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
- .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
- _ = it.next();
+ .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
+ _ = m.next();
return transCreateNodeIdentifierUnchecked(c, "c_ulonglong");
} else return transCreateNodeIdentifierUnchecked(c, "c_ulong"),
else => {
- it.i -= 1;
+ m.i -= 1;
return transCreateNodeIdentifierUnchecked(c, "c_uint");
},
} else {
return transCreateNodeIdentifierUnchecked(c, "c_uint");
},
- .Keyword_signed => if (it.next()) |t| switch (t) {
+ .Keyword_signed => if (m.next()) |t| switch (t) {
.Keyword_char => return transCreateNodeIdentifierUnchecked(c, "i8"),
.Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
.Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
- .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
- _ = it.next();
+ .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
+ _ = m.next();
return transCreateNodeIdentifierUnchecked(c, "c_longlong");
} else return transCreateNodeIdentifierUnchecked(c, "c_long"),
else => {
- it.i -= 1;
+ m.i -= 1;
return transCreateNodeIdentifierUnchecked(c, "c_int");
},
} else {
return transCreateNodeIdentifierUnchecked(c, "c_int");
},
.Identifier => {
- const mangled_name = scope.getAlias(it.slice(it.i));
+ const mangled_name = scope.getAlias(slice);
return transCreateNodeIdentifier(c, mangled_name);
},
.LParen => {
- const inner_node = try parseCExpr(c, it, source_loc, scope);
+ const inner_node = try parseCExpr(c, m, scope);
- const next_id = it.next().?;
+ const next_id = m.next().?;
if (next_id != .RParen) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ')'' instead got: {}",
- .{@tagName(next_id)},
- );
+ try m.fail(c, "unable to translate C expr: expected ')'' instead got: {}", .{@tagName(next_id)});
return error.ParseError;
}
var saw_l_paren = false;
var saw_integer_literal = false;
- switch (it.peek().?) {
+ switch (m.peek().?) {
// (type)(to_cast)
.LParen => {
saw_l_paren = true;
- _ = it.next();
+ _ = m.next();
},
// (type)identifier
.Identifier => {},
@@ -5876,16 +5843,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
// hack to get zig fmt to render a comma in builtin calls
_ = try appendToken(c, .Comma, ",");
- const node_to_cast = try parseCExpr(c, it, source_loc, scope);
+ const node_to_cast = try parseCExpr(c, m, scope);
- if (saw_l_paren and it.next().? != .RParen) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ')''",
- .{},
- );
+ if (saw_l_paren and m.next().? != .RParen) {
+ try m.fail(c, "unable to translate C expr: expected ')''", .{});
return error.ParseError;
}
@@ -5913,13 +5874,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
return &group_node.base;
},
else => {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: unexpected token .{}",
- .{@tagName(tok)},
- );
+ try m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(tok)});
return error.ParseError;
},
}
@@ -6026,52 +5981,40 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
return &group_node.base;
}
-fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
- var node = try parseCPrimaryExpr(c, it, source_loc, scope);
+fn parseCSuffixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
+ var node = try parseCPrimaryExpr(c, m, scope);
while (true) {
var op_token: ast.TokenIndex = undefined;
var op_id: ast.Node.Tag = undefined;
var bool_op = false;
- switch (it.next().?) {
+ switch (m.next().?) {
.Period => {
- if (it.next().? != .Identifier) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected identifier",
- .{},
- );
+ if (m.next().? != .Identifier) {
+ try m.fail(c, "unable to translate C expr: expected identifier", .{});
return error.ParseError;
}
- node = try transCreateNodeFieldAccess(c, node, it.slice(it.i));
+ node = try transCreateNodeFieldAccess(c, node, m.slice());
continue;
},
.Arrow => {
- if (it.next().? != .Identifier) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected identifier",
- .{},
- );
+ if (m.next().? != .Identifier) {
+ try m.fail(c, "unable to translate C expr: expected identifier", .{});
return error.ParseError;
}
const deref = try transCreateNodePtrDeref(c, node);
- node = try transCreateNodeFieldAccess(c, deref, it.slice(it.i));
+ node = try transCreateNodeFieldAccess(c, deref, m.slice());
continue;
},
.Asterisk => {
- if (it.peek().? == .RParen) {
+ if (m.peek().? == .RParen) {
// type *)
// hack to get zig fmt to render a comma in builtin calls
_ = try appendToken(c, .Comma, ",");
// last token of `node`
- const prev_id = it.list[it.i - 1].id;
+ const prev_id = m.list[m.i - 1].id;
if (prev_id == .Keyword_void) {
const ptr = try transCreateNodePtrType(c, false, false, .Asterisk);
@@ -6142,17 +6085,11 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
},
.LBracket => {
const arr_node = try transCreateNodeArrayAccess(c, node);
- arr_node.index_expr = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ arr_node.index_expr = try parseCPrefixOpExpr(c, m, scope);
arr_node.rtoken = try appendToken(c, .RBracket, "]");
node = &arr_node.base;
- if (it.next().? != .RBracket) {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ']'",
- .{},
- );
+ if (m.next().? != .RBracket) {
+ try m.fail(c, "unable to translate C expr: expected ']'", .{});
return error.ParseError;
}
continue;
@@ -6162,19 +6099,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
var call_params = std.ArrayList(*ast.Node).init(c.gpa);
defer call_params.deinit();
while (true) {
- const arg = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ const arg = try parseCPrefixOpExpr(c, m, scope);
try call_params.append(arg);
- switch (it.next().?) {
+ switch (m.next().?) {
.Comma => _ = try appendToken(c, .Comma, ","),
.RParen => break,
else => {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ',' or ')'",
- .{},
- );
+ try m.fail(c, "unable to translate C expr: expected ',' or ')'", .{});
return error.ParseError;
},
}
@@ -6201,19 +6132,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
defer init_vals.deinit();
while (true) {
- const val = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ const val = try parseCPrefixOpExpr(c, m, scope);
try init_vals.append(val);
- switch (it.next().?) {
+ switch (m.next().?) {
.Comma => _ = try appendToken(c, .Comma, ","),
.RBrace => break,
else => {
- try failDecl(
- c,
- source_loc,
- it.slice(0),
- "unable to translate C expr: expected ',' or '}}'",
- .{},
- );
+ try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{});
return error.ParseError;
},
}
@@ -6262,22 +6187,22 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
op_id = .ArrayCat;
op_token = try appendToken(c, .PlusPlus, "++");
- it.i -= 1;
+ m.i -= 1;
},
.Identifier => {
op_id = .ArrayCat;
op_token = try appendToken(c, .PlusPlus, "++");
- it.i -= 1;
+ m.i -= 1;
},
else => {
- it.i -= 1;
+ m.i -= 1;
return node;
},
}
const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt;
const lhs_node = try cast_fn(c, node);
- const rhs_node = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ const rhs_node = try parseCPrefixOpExpr(c, m, scope);
const op_node = try c.arena.create(ast.Node.SimpleInfixOp);
op_node.* = .{
.base = .{ .tag = op_id },
@@ -6289,36 +6214,36 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
}
}
-fn parseCPrefixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
- switch (it.next().?) {
+fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
+ switch (m.next().?) {
.Bang => {
const node = try transCreateNodeSimplePrefixOp(c, .BoolNot, .Bang, "!");
- node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ node.rhs = try parseCPrefixOpExpr(c, m, scope);
return &node.base;
},
.Minus => {
const node = try transCreateNodeSimplePrefixOp(c, .Negation, .Minus, "-");
- node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ node.rhs = try parseCPrefixOpExpr(c, m, scope);
return &node.base;
},
- .Plus => return try parseCPrefixOpExpr(c, it, source_loc, scope),
+ .Plus => return try parseCPrefixOpExpr(c, m, scope),
.Tilde => {
const node = try transCreateNodeSimplePrefixOp(c, .BitNot, .Tilde, "~");
- node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ node.rhs = try parseCPrefixOpExpr(c, m, scope);
return &node.base;
},
.Asterisk => {
- const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ const node = try parseCPrefixOpExpr(c, m, scope);
return try transCreateNodePtrDeref(c, node);
},
.Ampersand => {
const node = try transCreateNodeSimplePrefixOp(c, .AddressOf, .Ampersand, "&");
- node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
+ node.rhs = try parseCPrefixOpExpr(c, m, scope);
return &node.base;
},
else => {
- it.i -= 1;
- return try parseCSuffixOpExpr(c, it, source_loc, scope);
+ m.i -= 1;
+ return try parseCSuffixOpExpr(c, m, scope);
},
}
}
test/translate_c.zig
@@ -1679,8 +1679,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("shadowing primitive types",
\\unsigned anyerror = 2;
+ \\#define noreturn _Noreturn
, &[_][]const u8{
\\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2));
+ ,
+
+ \\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
});
cases.add("floats",