authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-11 12:20:58+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-11 12:24:45+03:00
log2b28cebf644b29543fcb52504b11931a7c797ffb
tree9346697c4fc2faf5dc8d6bb10acdce38f577cf45
parentcf5932b236424d8e1b52500bc80ffb6d79e20134
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: use mangled name when macro translation fails

Closes #6009

2 files changed, 127 insertions(+), 198 deletions(-)

src-self-hosted/translate_c.zig+123-198
......@@ -3089,7 +3089,7 @@ fn transUnaryExprOrTypeTraitExpr(
30893089 .AlignOf => "@alignOf",
30903090 .PreferredAlignOf,
30913091 .VecStep,
3092 .OpenMPRequiredSimdAlign,
3092 .OpenMPRequiredSimdAlign,
30933093 => return revertAndWarn(
30943094 rp,
30953095 error.UnsupportedTranslation,
......@@ -5220,26 +5220,32 @@ pub fn freeErrors(errors: []ClangErrMsg) void {
52205220 ZigClangErrorMsg_delete(errors.ptr, errors.len);
52215221}
52225222
5223const CTokIterator = struct {
5223const MacroCtx = struct {
52245224 source: []const u8,
52255225 list: []const CToken,
52265226 i: usize = 0,
5227 loc: ZigClangSourceLocation,
5228 name: []const u8,
52275229
5228 fn peek(self: *CTokIterator) ?CToken.Id {
5230 fn peek(self: *MacroCtx) ?CToken.Id {
52295231 if (self.i >= self.list.len) return null;
52305232 return self.list[self.i + 1].id;
52315233 }
52325234
5233 fn next(self: *CTokIterator) ?CToken.Id {
5235 fn next(self: *MacroCtx) ?CToken.Id {
52345236 if (self.i >= self.list.len) return null;
52355237 self.i += 1;
52365238 return self.list[self.i].id;
52375239 }
52385240
5239 fn slice(self: *CTokIterator, index: usize) []const u8 {
5240 const tok = self.list[index];
5241 fn slice(self: *MacroCtx) []const u8 {
5242 const tok = self.list[self.i];
52415243 return self.source[tok.start..tok.end];
52425244 }
5245
5246 fn fail(self: *MacroCtx, c: *Context, comptime fmt: []const u8, args: anytype) !void {
5247 return failDecl(c, self.loc, self.name, fmt, args);
5248 }
52435249};
52445250
52455251fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
......@@ -5286,18 +5292,21 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
52865292 try tok_list.append(tok);
52875293 }
52885294
5289 var tok_it = CTokIterator{
5295 var macro_ctx = MacroCtx{
52905296 .source = slice,
52915297 .list = tok_list.items,
5298 .name = mangled_name,
5299 .loc = begin_loc,
52925300 };
5293 assert(mem.eql(u8, tok_it.slice(0), name));
5301 assert(mem.eql(u8, macro_ctx.slice(), name));
52945302
52955303 var macro_fn = false;
5296 switch (tok_it.peek().?) {
5304 switch (macro_ctx.peek().?) {
52975305 .Identifier => {
52985306 // if it equals itself, ignore. for example, from stdio.h:
52995307 // #define stdin stdin
5300 if (mem.eql(u8, name, tok_it.slice(1))) {
5308 const tok = macro_ctx.list[1];
5309 if (mem.eql(u8, name, slice[tok.start..tok.end])) {
53015310 continue;
53025311 }
53035312 },
......@@ -5308,15 +5317,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
53085317 },
53095318 .LParen => {
53105319 // if the name is immediately followed by a '(' then it is a function
5311 macro_fn = tok_it.list[0].end == tok_it.list[1].start;
5320 macro_fn = macro_ctx.list[0].end == macro_ctx.list[1].start;
53125321 },
53135322 else => {},
53145323 }
53155324
53165325 (if (macro_fn)
5317 transMacroFnDefine(c, &tok_it, mangled_name, begin_loc)
5326 transMacroFnDefine(c, &macro_ctx)
53185327 else
5319 transMacroDefine(c, &tok_it, mangled_name, begin_loc)) catch |err| switch (err) {
5328 transMacroDefine(c, &macro_ctx)) catch |err| switch (err) {
53205329 error.ParseError => continue,
53215330 error.OutOfMemory => |e| return e,
53225331 };
......@@ -5326,24 +5335,18 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
53265335 }
53275336}
53285337
5329fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
5338fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
53305339 const scope = &c.global_scope.base;
53315340
53325341 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
53335342 const mut_tok = try appendToken(c, .Keyword_const, "const");
5334 const name_tok = try appendIdentifier(c, name);
5343 const name_tok = try appendIdentifier(c, m.name);
53355344 const eq_token = try appendToken(c, .Equal, "=");
53365345
5337 const init_node = try parseCExpr(c, it, source_loc, scope);
5338 const last = it.next().?;
5346 const init_node = try parseCExpr(c, m, scope);
5347 const last = m.next().?;
53395348 if (last != .Eof and last != .Nl)
5340 return failDecl(
5341 c,
5342 source_loc,
5343 name,
5344 "unable to translate C expr: unexpected token .{}",
5345 .{@tagName(last)},
5346 );
5349 return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)});
53475350
53485351 const semicolon_token = try appendToken(c, .Semicolon, ";");
53495352 const node = try ast.Node.VarDecl.create(c.arena, .{
......@@ -5355,10 +5358,10 @@ fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc
53555358 .eq_token = eq_token,
53565359 .init_node = init_node,
53575360 });
5358 _ = try c.global_scope.macro_table.put(name, &node.base);
5361 _ = try c.global_scope.macro_table.put(m.name, &node.base);
53595362}
53605363
5361fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
5364fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
53625365 var block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
53635366 defer block_scope.deinit();
53645367 const scope = &block_scope.base;
......@@ -5366,34 +5369,22 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
53665369 const pub_tok = try appendToken(c, .Keyword_pub, "pub");
53675370 const inline_tok = try appendToken(c, .Keyword_inline, "inline");
53685371 const fn_tok = try appendToken(c, .Keyword_fn, "fn");
5369 const name_tok = try appendIdentifier(c, name);
5372 const name_tok = try appendIdentifier(c, m.name);
53705373 _ = try appendToken(c, .LParen, "(");
53715374
5372 if (it.next().? != .LParen) {
5373 return failDecl(
5374 c,
5375 source_loc,
5376 name,
5377 "unable to translate C expr: expected '('",
5378 .{},
5379 );
5375 if (m.next().? != .LParen) {
5376 return m.fail(c, "unable to translate C expr: expected '('", .{});
53805377 }
53815378
53825379 var fn_params = std.ArrayList(ast.Node.FnProto.ParamDecl).init(c.gpa);
53835380 defer fn_params.deinit();
53845381
53855382 while (true) {
5386 if (it.next().? != .Identifier) {
5387 return failDecl(
5388 c,
5389 source_loc,
5390 name,
5391 "unable to translate C expr: expected identifier",
5392 .{},
5393 );
5383 if (m.next().? != .Identifier) {
5384 return m.fail(c, "unable to translate C expr: expected identifier", .{});
53945385 }
53955386
5396 const mangled_name = try block_scope.makeMangledName(c, it.slice(it.i));
5387 const mangled_name = try block_scope.makeMangledName(c, m.slice());
53975388 const param_name_tok = try appendIdentifier(c, mangled_name);
53985389 _ = try appendToken(c, .Colon, ":");
53995390
......@@ -5411,20 +5402,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
54115402 .param_type = .{ .any_type = &any_type.base },
54125403 };
54135404
5414 if (it.peek().? != .Comma)
5405 if (m.peek().? != .Comma)
54155406 break;
5416 _ = it.next();
5407 _ = m.next();
54175408 _ = try appendToken(c, .Comma, ",");
54185409 }
54195410
5420 if (it.next().? != .RParen) {
5421 return failDecl(
5422 c,
5423 source_loc,
5424 name,
5425 "unable to translate C expr: expected ')'",
5426 .{},
5427 );
5411 if (m.next().? != .RParen) {
5412 return m.fail(c, "unable to translate C expr: expected ')'", .{});
54285413 }
54295414
54305415 _ = try appendToken(c, .RParen, ")");
......@@ -5432,16 +5417,10 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
54325417 const type_of = try c.createBuiltinCall("@TypeOf", 1);
54335418
54345419 const return_kw = try appendToken(c, .Keyword_return, "return");
5435 const expr = try parseCExpr(c, it, source_loc, scope);
5436 const last = it.next().?;
5420 const expr = try parseCExpr(c, m, scope);
5421 const last = m.next().?;
54375422 if (last != .Eof and last != .Nl)
5438 return failDecl(
5439 c,
5440 source_loc,
5441 name,
5442 "unable to translate C expr: unexpected token .{}",
5443 .{@tagName(last)},
5444 );
5423 return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)});
54455424 _ = try appendToken(c, .Semicolon, ";");
54465425 const type_of_arg = if (expr.tag != .Block) expr else blk: {
54475426 const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
......@@ -5472,32 +5451,26 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l
54725451 });
54735452 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
54745453
5475 _ = try c.global_scope.macro_table.put(name, &fn_proto.base);
5454 _ = try c.global_scope.macro_table.put(m.name, &fn_proto.base);
54765455}
54775456
54785457const ParseError = Error || error{ParseError};
54795458
5480fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5481 const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
5482 switch (it.next().?) {
5459fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
5460 const node = try parseCPrefixOpExpr(c, m, scope);
5461 switch (m.next().?) {
54835462 .QuestionMark => {
54845463 // must come immediately after expr
54855464 _ = try appendToken(c, .RParen, ")");
54865465 const if_node = try transCreateNodeIf(c);
54875466 if_node.condition = node;
5488 if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope);
5489 if (it.next().? != .Colon) {
5490 try failDecl(
5491 c,
5492 source_loc,
5493 it.slice(0),
5494 "unable to translate C expr: expected ':'",
5495 .{},
5496 );
5467 if_node.body = try parseCPrimaryExpr(c, m, scope);
5468 if (m.next().? != .Colon) {
5469 try m.fail(c, "unable to translate C expr: expected ':'", .{});
54975470 return error.ParseError;
54985471 }
54995472 if_node.@"else" = try transCreateNodeElse(c);
5500 if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope);
5473 if_node.@"else".?.body = try parseCPrimaryExpr(c, m, scope);
55015474 return &if_node.base;
55025475 },
55035476 .Comma => {
......@@ -5520,10 +5493,10 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation
55205493 };
55215494 try block_scope.statements.append(&op_node.base);
55225495
5523 last = try parseCPrefixOpExpr(c, it, source_loc, scope);
5496 last = try parseCPrefixOpExpr(c, m, scope);
55245497 _ = try appendToken(c, .Semicolon, ";");
5525 if (it.next().? != .Comma) {
5526 it.i -= 1;
5498 if (m.next().? != .Comma) {
5499 m.i -= 1;
55275500 break;
55285501 }
55295502 }
......@@ -5534,16 +5507,16 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation
55345507 return &block_node.base;
55355508 },
55365509 else => {
5537 it.i -= 1;
5510 m.i -= 1;
55385511 return node;
55395512 },
55405513 }
55415514}
55425515
5543fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
5544 var lit_bytes = it.slice(it.i);
5516fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!*ast.Node {
5517 var lit_bytes = m.slice();
55455518
5546 switch (it.list[it.i].id) {
5519 switch (m.list[m.i].id) {
55475520 .IntegerLiteral => |suffix| {
55485521 if (lit_bytes.len > 2 and lit_bytes[0] == '0') {
55495522 switch (lit_bytes[1]) {
......@@ -5604,8 +5577,8 @@ fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocati
56045577 }
56055578}
56065579
5607fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ![]const u8 {
5608 var source = source_bytes;
5580fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
5581 var source = m.slice();
56095582 for (source) |c, i| {
56105583 if (c == '\"' or c == '\'') {
56115584 source = source[i..];
......@@ -5677,11 +5650,11 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
56775650 bytes[i] = '?';
56785651 },
56795652 'u', 'U' => {
5680 try failDecl(ctx, source_loc, name, "macro tokenizing failed: TODO unicode escape sequences", .{});
5653 try m.fail(ctx, "macro tokenizing failed: TODO unicode escape sequences", .{});
56815654 return error.ParseError;
56825655 },
56835656 else => {
5684 try failDecl(ctx, source_loc, name, "macro tokenizing failed: unknown escape sequence", .{});
5657 try m.fail(ctx, "macro tokenizing failed: unknown escape sequence", .{});
56855658 return error.ParseError;
56865659 },
56875660 }
......@@ -5700,21 +5673,21 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
57005673 switch (c) {
57015674 '0'...'9' => {
57025675 num = std.math.mul(u8, num, 16) catch {
5703 try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
5676 try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
57045677 return error.ParseError;
57055678 };
57065679 num += c - '0';
57075680 },
57085681 'a'...'f' => {
57095682 num = std.math.mul(u8, num, 16) catch {
5710 try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
5683 try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
57115684 return error.ParseError;
57125685 };
57135686 num += c - 'a' + 10;
57145687 },
57155688 'A'...'F' => {
57165689 num = std.math.mul(u8, num, 16) catch {
5717 try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{});
5690 try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{});
57185691 return error.ParseError;
57195692 };
57205693 num += c - 'A' + 10;
......@@ -5741,7 +5714,7 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
57415714 if (accept_digit) {
57425715 count += 1;
57435716 num = std.math.mul(u8, num, 8) catch {
5744 try failDecl(ctx, source_loc, name, "macro tokenizing failed: octal literal overflowed", .{});
5717 try m.fail(ctx, "macro tokenizing failed: octal literal overflowed", .{});
57455718 return error.ParseError;
57465719 };
57475720 num += c - '0';
......@@ -5764,13 +5737,13 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
57645737 return bytes[0..i];
57655738}
57665739
5767fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5768 const tok = it.next().?;
5769 const slice = it.slice(it.i);
5740fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
5741 const tok = m.next().?;
5742 const slice = m.slice();
57705743 switch (tok) {
57715744 .CharLiteral => {
57725745 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
5773 const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
5746 const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, m));
57745747 const node = try c.arena.create(ast.Node.OneToken);
57755748 node.* = .{
57765749 .base = .{ .tag = .CharLiteral },
......@@ -5788,7 +5761,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
57885761 }
57895762 },
57905763 .StringLiteral => {
5791 const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
5764 const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, m));
57925765 const node = try c.arena.create(ast.Node.OneToken);
57935766 node.* = .{
57945767 .base = .{ .tag = .StringLiteral },
......@@ -5797,7 +5770,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
57975770 return &node.base;
57985771 },
57995772 .IntegerLiteral, .FloatLiteral => {
5800 return parseCNumLit(c, it, source_loc);
5773 return parseCNumLit(c, m);
58015774 },
58025775 // eventually this will be replaced by std.c.parse which will handle these correctly
58035776 .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
......@@ -5808,61 +5781,55 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
58085781 .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
58095782 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
58105783 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
5811 .Keyword_unsigned => if (it.next()) |t| switch (t) {
5784 .Keyword_unsigned => if (m.next()) |t| switch (t) {
58125785 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
58135786 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_ushort"),
58145787 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
5815 .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
5816 _ = it.next();
5788 .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
5789 _ = m.next();
58175790 return transCreateNodeIdentifierUnchecked(c, "c_ulonglong");
58185791 } else return transCreateNodeIdentifierUnchecked(c, "c_ulong"),
58195792 else => {
5820 it.i -= 1;
5793 m.i -= 1;
58215794 return transCreateNodeIdentifierUnchecked(c, "c_uint");
58225795 },
58235796 } else {
58245797 return transCreateNodeIdentifierUnchecked(c, "c_uint");
58255798 },
5826 .Keyword_signed => if (it.next()) |t| switch (t) {
5799 .Keyword_signed => if (m.next()) |t| switch (t) {
58275800 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "i8"),
58285801 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
58295802 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
5830 .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
5831 _ = it.next();
5803 .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
5804 _ = m.next();
58325805 return transCreateNodeIdentifierUnchecked(c, "c_longlong");
58335806 } else return transCreateNodeIdentifierUnchecked(c, "c_long"),
58345807 else => {
5835 it.i -= 1;
5808 m.i -= 1;
58365809 return transCreateNodeIdentifierUnchecked(c, "c_int");
58375810 },
58385811 } else {
58395812 return transCreateNodeIdentifierUnchecked(c, "c_int");
58405813 },
58415814 .Identifier => {
5842 const mangled_name = scope.getAlias(it.slice(it.i));
5815 const mangled_name = scope.getAlias(slice);
58435816 return transCreateNodeIdentifier(c, mangled_name);
58445817 },
58455818 .LParen => {
5846 const inner_node = try parseCExpr(c, it, source_loc, scope);
5819 const inner_node = try parseCExpr(c, m, scope);
58475820
5848 const next_id = it.next().?;
5821 const next_id = m.next().?;
58495822 if (next_id != .RParen) {
5850 try failDecl(
5851 c,
5852 source_loc,
5853 it.slice(0),
5854 "unable to translate C expr: expected ')'' instead got: {}",
5855 .{@tagName(next_id)},
5856 );
5823 try m.fail(c, "unable to translate C expr: expected ')'' instead got: {}", .{@tagName(next_id)});
58575824 return error.ParseError;
58585825 }
58595826 var saw_l_paren = false;
58605827 var saw_integer_literal = false;
5861 switch (it.peek().?) {
5828 switch (m.peek().?) {
58625829 // (type)(to_cast)
58635830 .LParen => {
58645831 saw_l_paren = true;
5865 _ = it.next();
5832 _ = m.next();
58665833 },
58675834 // (type)identifier
58685835 .Identifier => {},
......@@ -5876,16 +5843,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
58765843 // hack to get zig fmt to render a comma in builtin calls
58775844 _ = try appendToken(c, .Comma, ",");
58785845
5879 const node_to_cast = try parseCExpr(c, it, source_loc, scope);
5846 const node_to_cast = try parseCExpr(c, m, scope);
58805847
5881 if (saw_l_paren and it.next().? != .RParen) {
5882 try failDecl(
5883 c,
5884 source_loc,
5885 it.slice(0),
5886 "unable to translate C expr: expected ')''",
5887 .{},
5888 );
5848 if (saw_l_paren and m.next().? != .RParen) {
5849 try m.fail(c, "unable to translate C expr: expected ')''", .{});
58895850 return error.ParseError;
58905851 }
58915852
......@@ -5913,13 +5874,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL
59135874 return &group_node.base;
59145875 },
59155876 else => {
5916 try failDecl(
5917 c,
5918 source_loc,
5919 it.slice(0),
5920 "unable to translate C expr: unexpected token .{}",
5921 .{@tagName(tok)},
5922 );
5877 try m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(tok)});
59235878 return error.ParseError;
59245879 },
59255880 }
......@@ -6026,52 +5981,40 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
60265981 return &group_node.base;
60275982}
60285983
6029fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
6030 var node = try parseCPrimaryExpr(c, it, source_loc, scope);
5984fn parseCSuffixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
5985 var node = try parseCPrimaryExpr(c, m, scope);
60315986 while (true) {
60325987 var op_token: ast.TokenIndex = undefined;
60335988 var op_id: ast.Node.Tag = undefined;
60345989 var bool_op = false;
6035 switch (it.next().?) {
5990 switch (m.next().?) {
60365991 .Period => {
6037 if (it.next().? != .Identifier) {
6038 try failDecl(
6039 c,
6040 source_loc,
6041 it.slice(0),
6042 "unable to translate C expr: expected identifier",
6043 .{},
6044 );
5992 if (m.next().? != .Identifier) {
5993 try m.fail(c, "unable to translate C expr: expected identifier", .{});
60455994 return error.ParseError;
60465995 }
60475996
6048 node = try transCreateNodeFieldAccess(c, node, it.slice(it.i));
5997 node = try transCreateNodeFieldAccess(c, node, m.slice());
60495998 continue;
60505999 },
60516000 .Arrow => {
6052 if (it.next().? != .Identifier) {
6053 try failDecl(
6054 c,
6055 source_loc,
6056 it.slice(0),
6057 "unable to translate C expr: expected identifier",
6058 .{},
6059 );
6001 if (m.next().? != .Identifier) {
6002 try m.fail(c, "unable to translate C expr: expected identifier", .{});
60606003 return error.ParseError;
60616004 }
60626005 const deref = try transCreateNodePtrDeref(c, node);
6063 node = try transCreateNodeFieldAccess(c, deref, it.slice(it.i));
6006 node = try transCreateNodeFieldAccess(c, deref, m.slice());
60646007 continue;
60656008 },
60666009 .Asterisk => {
6067 if (it.peek().? == .RParen) {
6010 if (m.peek().? == .RParen) {
60686011 // type *)
60696012
60706013 // hack to get zig fmt to render a comma in builtin calls
60716014 _ = try appendToken(c, .Comma, ",");
60726015
60736016 // last token of `node`
6074 const prev_id = it.list[it.i - 1].id;
6017 const prev_id = m.list[m.i - 1].id;
60756018
60766019 if (prev_id == .Keyword_void) {
60776020 const ptr = try transCreateNodePtrType(c, false, false, .Asterisk);
......@@ -6142,17 +6085,11 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
61426085 },
61436086 .LBracket => {
61446087 const arr_node = try transCreateNodeArrayAccess(c, node);
6145 arr_node.index_expr = try parseCPrefixOpExpr(c, it, source_loc, scope);
6088 arr_node.index_expr = try parseCPrefixOpExpr(c, m, scope);
61466089 arr_node.rtoken = try appendToken(c, .RBracket, "]");
61476090 node = &arr_node.base;
6148 if (it.next().? != .RBracket) {
6149 try failDecl(
6150 c,
6151 source_loc,
6152 it.slice(0),
6153 "unable to translate C expr: expected ']'",
6154 .{},
6155 );
6091 if (m.next().? != .RBracket) {
6092 try m.fail(c, "unable to translate C expr: expected ']'", .{});
61566093 return error.ParseError;
61576094 }
61586095 continue;
......@@ -6162,19 +6099,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
61626099 var call_params = std.ArrayList(*ast.Node).init(c.gpa);
61636100 defer call_params.deinit();
61646101 while (true) {
6165 const arg = try parseCPrefixOpExpr(c, it, source_loc, scope);
6102 const arg = try parseCPrefixOpExpr(c, m, scope);
61666103 try call_params.append(arg);
6167 switch (it.next().?) {
6104 switch (m.next().?) {
61686105 .Comma => _ = try appendToken(c, .Comma, ","),
61696106 .RParen => break,
61706107 else => {
6171 try failDecl(
6172 c,
6173 source_loc,
6174 it.slice(0),
6175 "unable to translate C expr: expected ',' or ')'",
6176 .{},
6177 );
6108 try m.fail(c, "unable to translate C expr: expected ',' or ')'", .{});
61786109 return error.ParseError;
61796110 },
61806111 }
......@@ -6201,19 +6132,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
62016132 defer init_vals.deinit();
62026133
62036134 while (true) {
6204 const val = try parseCPrefixOpExpr(c, it, source_loc, scope);
6135 const val = try parseCPrefixOpExpr(c, m, scope);
62056136 try init_vals.append(val);
6206 switch (it.next().?) {
6137 switch (m.next().?) {
62076138 .Comma => _ = try appendToken(c, .Comma, ","),
62086139 .RBrace => break,
62096140 else => {
6210 try failDecl(
6211 c,
6212 source_loc,
6213 it.slice(0),
6214 "unable to translate C expr: expected ',' or '}}'",
6215 .{},
6216 );
6141 try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{});
62176142 return error.ParseError;
62186143 },
62196144 }
......@@ -6262,22 +6187,22 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
62626187 op_id = .ArrayCat;
62636188 op_token = try appendToken(c, .PlusPlus, "++");
62646189
6265 it.i -= 1;
6190 m.i -= 1;
62666191 },
62676192 .Identifier => {
62686193 op_id = .ArrayCat;
62696194 op_token = try appendToken(c, .PlusPlus, "++");
62706195
6271 it.i -= 1;
6196 m.i -= 1;
62726197 },
62736198 else => {
6274 it.i -= 1;
6199 m.i -= 1;
62756200 return node;
62766201 },
62776202 }
62786203 const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt;
62796204 const lhs_node = try cast_fn(c, node);
6280 const rhs_node = try parseCPrefixOpExpr(c, it, source_loc, scope);
6205 const rhs_node = try parseCPrefixOpExpr(c, m, scope);
62816206 const op_node = try c.arena.create(ast.Node.SimpleInfixOp);
62826207 op_node.* = .{
62836208 .base = .{ .tag = op_id },
......@@ -6289,36 +6214,36 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource
62896214 }
62906215}
62916216
6292fn parseCPrefixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
6293 switch (it.next().?) {
6217fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node {
6218 switch (m.next().?) {
62946219 .Bang => {
62956220 const node = try transCreateNodeSimplePrefixOp(c, .BoolNot, .Bang, "!");
6296 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
6221 node.rhs = try parseCPrefixOpExpr(c, m, scope);
62976222 return &node.base;
62986223 },
62996224 .Minus => {
63006225 const node = try transCreateNodeSimplePrefixOp(c, .Negation, .Minus, "-");
6301 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
6226 node.rhs = try parseCPrefixOpExpr(c, m, scope);
63026227 return &node.base;
63036228 },
6304 .Plus => return try parseCPrefixOpExpr(c, it, source_loc, scope),
6229 .Plus => return try parseCPrefixOpExpr(c, m, scope),
63056230 .Tilde => {
63066231 const node = try transCreateNodeSimplePrefixOp(c, .BitNot, .Tilde, "~");
6307 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
6232 node.rhs = try parseCPrefixOpExpr(c, m, scope);
63086233 return &node.base;
63096234 },
63106235 .Asterisk => {
6311 const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
6236 const node = try parseCPrefixOpExpr(c, m, scope);
63126237 return try transCreateNodePtrDeref(c, node);
63136238 },
63146239 .Ampersand => {
63156240 const node = try transCreateNodeSimplePrefixOp(c, .AddressOf, .Ampersand, "&");
6316 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
6241 node.rhs = try parseCPrefixOpExpr(c, m, scope);
63176242 return &node.base;
63186243 },
63196244 else => {
6320 it.i -= 1;
6321 return try parseCSuffixOpExpr(c, it, source_loc, scope);
6245 m.i -= 1;
6246 return try parseCSuffixOpExpr(c, m, scope);
63226247 },
63236248 }
63246249}
test/translate_c.zig+4
......@@ -1679,8 +1679,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16791679
16801680 cases.add("shadowing primitive types",
16811681 \\unsigned anyerror = 2;
1682 \\#define noreturn _Noreturn
16821683 , &[_][]const u8{
16831684 \\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2));
1685 ,
1686
1687 \\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
16841688 });
16851689
16861690 cases.add("floats",