| ... | @@ -5479,18 +5479,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5479,18 +5479,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5479 | .LParen => { | 5479 | .LParen => { |
| 5480 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); | 5480 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); |
| 5481 | | 5481 | |
| 5482 | if (it.next().?.id != .RParen) { | 5482 | const next_id = it.next().?.id; |
| | 5483 | if (next_id != .RParen) { |
| 5483 | const first_tok = it.list.at(0); | 5484 | const first_tok = it.list.at(0); |
| 5484 | try failDecl( | 5485 | try failDecl( |
| 5485 | c, | 5486 | c, |
| 5486 | source_loc, | 5487 | source_loc, |
| 5487 | source[first_tok.start..first_tok.end], | 5488 | source[first_tok.start..first_tok.end], |
| 5488 | "unable to translate C expr: expected ')'' here", | 5489 | "unable to translate C expr: expected ')'' instead got: {}", |
| 5489 | .{}, | 5490 | .{@tagName(next_id)}, |
| 5490 | ); | 5491 | ); |
| 5491 | return error.ParseError; | 5492 | return error.ParseError; |
| 5492 | } | 5493 | } |
| 5493 | var saw_l_paren = false; | 5494 | var saw_l_paren = false; |
| | 5495 | var saw_integer_literal = false; |
| 5494 | switch (it.peek().?.id) { | 5496 | switch (it.peek().?.id) { |
| 5495 | // (type)(to_cast) | 5497 | // (type)(to_cast) |
| 5496 | .LParen => { | 5498 | .LParen => { |
| ... | @@ -5499,6 +5501,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5499,6 +5501,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5499 | }, | 5501 | }, |
| 5500 | // (type)identifier | 5502 | // (type)identifier |
| 5501 | .Identifier => {}, | 5503 | .Identifier => {}, |
| | 5504 | // (type)integer |
| | 5505 | .IntegerLiteral => { |
| | 5506 | saw_integer_literal = true; |
| | 5507 | }, |
| 5502 | else => return inner_node, | 5508 | else => return inner_node, |
| 5503 | } | 5509 | } |
| 5504 | | 5510 | |
| ... | @@ -5519,6 +5525,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5519,6 +5525,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5519 | return error.ParseError; | 5525 | return error.ParseError; |
| 5520 | } | 5526 | } |
| 5521 | | 5527 | |
| | 5528 | if (saw_integer_literal) { |
| | 5529 | // @intToPtr(dest, x) |
| | 5530 | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); |
| | 5531 | try int_to_ptr.params.push(inner_node); |
| | 5532 | try int_to_ptr.params.push(node_to_cast); |
| | 5533 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| | 5534 | return &int_to_ptr.base; |
| | 5535 | } |
| | 5536 | |
| 5522 | //( if (@typeInfo(@TypeOf(x)) == .Pointer) | 5537 | //( if (@typeInfo(@TypeOf(x)) == .Pointer) |
| 5523 | // @ptrCast(dest, @alignCast(@alignOf(dest.Child), x)) | 5538 | // @ptrCast(dest, @alignCast(@alignOf(dest.Child), x)) |
| 5524 | //else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer)) | 5539 | //else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer)) |
| ... | @@ -5750,19 +5765,24 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5750,19 +5765,24 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5750 | // hack to get zig fmt to render a comma in builtin calls | 5765 | // hack to get zig fmt to render a comma in builtin calls |
| 5751 | _ = try appendToken(c, .Comma, ","); | 5766 | _ = try appendToken(c, .Comma, ","); |
| 5752 | | 5767 | |
| 5753 | const ptr_kind = blk: { | 5768 | // * token |
| 5754 | // * token | 5769 | _ = it.prev(); |
| 5755 | _ = it.prev(); | 5770 | // last token of `node` |
| 5756 | // last token of `node` | 5771 | const prev_id = it.prev().?.id; |
| 5757 | const prev_id = it.prev().?.id; | 5772 | _ = it.next(); |
| 5758 | _ = it.next(); | 5773 | _ = it.next(); |
| 5759 | _ = it.next(); | | |
| 5760 | break :blk if (prev_id == .Keyword_void) .Asterisk else Token.Id.Identifier; | | |
| 5761 | }; | | |
| 5762 | | 5774 | |
| 5763 | const ptr = try transCreateNodePtrType(c, false, false, ptr_kind); | 5775 | if (prev_id == .Keyword_void) { |
| 5764 | ptr.rhs = node; | 5776 | const ptr = try transCreateNodePtrType(c, false, false, .Asterisk); |
| 5765 | return &ptr.base; | 5777 | ptr.rhs = node; |
| | 5778 | const optional_node = try transCreateNodePrefixOp(c, .OptionalType, .QuestionMark, "?"); |
| | 5779 | optional_node.rhs = &ptr.base; |
| | 5780 | return &optional_node.base; |
| | 5781 | } else { |
| | 5782 | const ptr = try transCreateNodePtrType(c, false, false, Token.Id.Identifier); |
| | 5783 | ptr.rhs = node; |
| | 5784 | return &ptr.base; |
| | 5785 | } |
| 5766 | } else { | 5786 | } else { |
| 5767 | // expr * expr | 5787 | // expr * expr |
| 5768 | op_token = try appendToken(c, .Asterisk, "*"); | 5788 | op_token = try appendToken(c, .Asterisk, "*"); |