| ... | ... | @@ -4287,7 +4287,33 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4287 | 4287 | const ParseError = Error || error{ParseError}; |
| 4288 | 4288 | |
| 4289 | 4289 | fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 4290 | | return parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4290 | const node = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4291 | switch (it.next().?.id) { |
| 4292 | .QuestionMark => { |
| 4293 | // must come immediately after expr |
| 4294 | _ = try appendToken(c, .RParen, ")"); |
| 4295 | const if_node = try transCreateNodeIf(c); |
| 4296 | if_node.condition = node; |
| 4297 | if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4298 | if (it.next().?.id != .Colon) { |
| 4299 | try failDecl( |
| 4300 | c, |
| 4301 | source_loc, |
| 4302 | it.list.at(0).*.bytes, |
| 4303 | "unable to translate C expr: expected ':'", |
| 4304 | .{}, |
| 4305 | ); |
| 4306 | return error.ParseError; |
| 4307 | } |
| 4308 | if_node.@"else" = try transCreateNodeElse(c); |
| 4309 | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4310 | return &if_node.base; |
| 4311 | }, |
| 4312 | else => { |
| 4313 | _ = it.prev(); |
| 4314 | return node; |
| 4315 | }, |
| 4316 | } |
| 4291 | 4317 | } |
| 4292 | 4318 | |
| 4293 | 4319 | fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| ... | ... | @@ -4532,7 +4558,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4532 | 4558 | }, |
| 4533 | 4559 | .Shl => { |
| 4534 | 4560 | const op_token = try appendToken(c, .AngleBracketAngleBracketLeft, "<<"); |
| 4535 | | const rhs = try parseCExpr(c, it, source_loc, scope); |
| 4561 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4536 | 4562 | const bitshift_node = try c.a().create(ast.Node.InfixOp); |
| 4537 | 4563 | bitshift_node.* = .{ |
| 4538 | 4564 | .op_token = op_token, |
| ... | ... | @@ -4543,9 +4569,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4543 | 4569 | node = &bitshift_node.base; |
| 4544 | 4570 | }, |
| 4545 | 4571 | .Shr => { |
| 4546 | | const op_token = try appendToken(rp.c, .AngleBracketAngleBracketRight, ">>"); |
| 4547 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4548 | | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4572 | const op_token = try appendToken(c, .AngleBracketAngleBracketRight, ">>"); |
| 4573 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4574 | const bitshift_node = try c.a().create(ast.Node.InfixOp); |
| 4549 | 4575 | bitshift_node.* = .{ |
| 4550 | 4576 | .op_token = op_token, |
| 4551 | 4577 | .lhs = node, |
| ... | ... | @@ -4556,7 +4582,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4556 | 4582 | }, |
| 4557 | 4583 | .Pipe => { |
| 4558 | 4584 | const op_token = try appendToken(c, .Pipe, "|"); |
| 4559 | | const rhs = try parseCExpr(c, it, source_loc, scope); |
| 4585 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4560 | 4586 | const or_node = try c.a().create(ast.Node.InfixOp); |
| 4561 | 4587 | or_node.* = .{ |
| 4562 | 4588 | .op_token = op_token, |
| ... | ... | @@ -4567,9 +4593,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4567 | 4593 | node = &or_node.base; |
| 4568 | 4594 | }, |
| 4569 | 4595 | .Ampersand => { |
| 4570 | | const op_token = try appendToken(rp.c, .Ampersand, "&"); |
| 4571 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4572 | | const bitand_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4596 | const op_token = try appendToken(c, .Ampersand, "&"); |
| 4597 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4598 | const bitand_node = try c.a().create(ast.Node.InfixOp); |
| 4573 | 4599 | bitand_node.* = .{ |
| 4574 | 4600 | .op_token = op_token, |
| 4575 | 4601 | .lhs = node, |
| ... | ... | @@ -4579,9 +4605,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4579 | 4605 | node = &bitand_node.base; |
| 4580 | 4606 | }, |
| 4581 | 4607 | .Plus => { |
| 4582 | | const op_token = try appendToken(rp.c, .Plus, "+"); |
| 4583 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4584 | | const add_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4608 | const op_token = try appendToken(c, .Plus, "+"); |
| 4609 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4610 | const add_node = try c.a().create(ast.Node.InfixOp); |
| 4585 | 4611 | add_node.* = .{ |
| 4586 | 4612 | .op_token = op_token, |
| 4587 | 4613 | .lhs = node, |
| ... | ... | @@ -4591,9 +4617,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4591 | 4617 | node = &add_node.base; |
| 4592 | 4618 | }, |
| 4593 | 4619 | .Minus => { |
| 4594 | | const op_token = try appendToken(rp.c, .Minus, "-"); |
| 4595 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4596 | | const sub_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4620 | const op_token = try appendToken(c, .Minus, "-"); |
| 4621 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4622 | const sub_node = try c.a().create(ast.Node.InfixOp); |
| 4597 | 4623 | sub_node.* = .{ |
| 4598 | 4624 | .op_token = op_token, |
| 4599 | 4625 | .lhs = node, |
| ... | ... | @@ -4603,9 +4629,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4603 | 4629 | node = &sub_node.base; |
| 4604 | 4630 | }, |
| 4605 | 4631 | .And => { |
| 4606 | | const op_token = try appendToken(rp.c, .Keyword_and, "and"); |
| 4607 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4608 | | const and_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4632 | const op_token = try appendToken(c, .Keyword_and, "and"); |
| 4633 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4634 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 4609 | 4635 | and_node.* = .{ |
| 4610 | 4636 | .op_token = op_token, |
| 4611 | 4637 | .lhs = node, |
| ... | ... | @@ -4615,9 +4641,9 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4615 | 4641 | node = &and_node.base; |
| 4616 | 4642 | }, |
| 4617 | 4643 | .Or => { |
| 4618 | | const op_token = try appendToken(rp.c, .Keyword_or, "or"); |
| 4619 | | const rhs = try parseCExpr(rp, it, source_loc, scope); |
| 4620 | | const or_node = try rp.c.a().create(ast.Node.InfixOp); |
| 4644 | const op_token = try appendToken(c, .Keyword_or, "or"); |
| 4645 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4646 | const or_node = try c.a().create(ast.Node.InfixOp); |
| 4621 | 4647 | or_node.* = .{ |
| 4622 | 4648 | .op_token = op_token, |
| 4623 | 4649 | .lhs = node, |
| ... | ... | @@ -4626,9 +4652,57 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4626 | 4652 | }; |
| 4627 | 4653 | node = &or_node.base; |
| 4628 | 4654 | }, |
| 4655 | .Gt => { |
| 4656 | const op_token = try appendToken(c, .AngleBracketRight, ">"); |
| 4657 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4658 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 4659 | and_node.* = .{ |
| 4660 | .op_token = op_token, |
| 4661 | .lhs = node, |
| 4662 | .op = .GreaterThan, |
| 4663 | .rhs = rhs, |
| 4664 | }; |
| 4665 | node = &and_node.base; |
| 4666 | }, |
| 4667 | .Gte => { |
| 4668 | const op_token = try appendToken(c, .AngleBracketRightEqual, ">="); |
| 4669 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4670 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 4671 | and_node.* = .{ |
| 4672 | .op_token = op_token, |
| 4673 | .lhs = node, |
| 4674 | .op = .GreaterOrEqual, |
| 4675 | .rhs = rhs, |
| 4676 | }; |
| 4677 | node = &and_node.base; |
| 4678 | }, |
| 4679 | .Lt => { |
| 4680 | const op_token = try appendToken(c, .AngleBracketLeft, "<"); |
| 4681 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4682 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 4683 | and_node.* = .{ |
| 4684 | .op_token = op_token, |
| 4685 | .lhs = node, |
| 4686 | .op = .LessThan, |
| 4687 | .rhs = rhs, |
| 4688 | }; |
| 4689 | node = &and_node.base; |
| 4690 | }, |
| 4691 | .Lte => { |
| 4692 | const op_token = try appendToken(c, .AngleBracketLeftEqual, "<="); |
| 4693 | const rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4694 | const and_node = try c.a().create(ast.Node.InfixOp); |
| 4695 | and_node.* = .{ |
| 4696 | .op_token = op_token, |
| 4697 | .lhs = node, |
| 4698 | .op = .LessOrEqual, |
| 4699 | .rhs = rhs, |
| 4700 | }; |
| 4701 | node = &and_node.base; |
| 4702 | }, |
| 4629 | 4703 | .LBrace => { |
| 4630 | 4704 | const arr_node = try transCreateNodeArrayAccess(c, node); |
| 4631 | | arr_node.op.ArrayAccess = try parseCExpr(c, it, source_loc, scope); |
| 4705 | arr_node.op.ArrayAccess = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4632 | 4706 | arr_node.rtoken = try appendToken(c, .RBrace, "]"); |
| 4633 | 4707 | node = &arr_node.base; |
| 4634 | 4708 | if (it.next().?.id != .RBrace) { |
| ... | ... | @@ -4645,7 +4719,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4645 | 4719 | .LParen => { |
| 4646 | 4720 | const call_node = try transCreateNodeFnCall(c, node); |
| 4647 | 4721 | while (true) { |
| 4648 | | const arg = try parseCExpr(c, it, source_loc, scope); |
| 4722 | const arg = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 4649 | 4723 | try call_node.op.Call.params.push(arg); |
| 4650 | 4724 | const next = it.next().?; |
| 4651 | 4725 | if (next.id == .Comma) |
| ... | ... | @@ -4666,26 +4740,6 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig |
| 4666 | 4740 | call_node.rtoken = try appendToken(c, .RParen, ")"); |
| 4667 | 4741 | node = &call_node.base; |
| 4668 | 4742 | }, |
| 4669 | | .QuestionMark => { |
| 4670 | | // must come immediately after expr |
| 4671 | | _ = try appendToken(c, .RParen, ")"); |
| 4672 | | const if_node = try transCreateNodeIf(c); |
| 4673 | | if_node.condition = node; |
| 4674 | | if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4675 | | if (it.next().?.id != .Colon) { |
| 4676 | | try failDecl( |
| 4677 | | c, |
| 4678 | | source_loc, |
| 4679 | | it.list.at(0).*.bytes, |
| 4680 | | "unable to translate C expr: expected ':'", |
| 4681 | | .{}, |
| 4682 | | ); |
| 4683 | | return error.ParseError; |
| 4684 | | } |
| 4685 | | if_node.@"else" = try transCreateNodeElse(c); |
| 4686 | | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 4687 | | node = &if_node.base; |
| 4688 | | }, |
| 4689 | 4743 | else => { |
| 4690 | 4744 | _ = it.prev(); |
| 4691 | 4745 | return node; |