| ... | @@ -5331,7 +5331,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5331,7 +5331,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5331 | // for handling type macros (EVIL) | 5331 | // for handling type macros (EVIL) |
| 5332 | // TODO maybe detect and treat type macros as typedefs in parseCSpecifierQualifierList? | 5332 | // TODO maybe detect and treat type macros as typedefs in parseCSpecifierQualifierList? |
| 5333 | m.i -= 1; | 5333 | m.i -= 1; |
| 5334 | if (try parseCTypeName(c, m, scope)) |type_name| { | 5334 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 5335 | return type_name; | 5335 | return type_name; |
| 5336 | } | 5336 | } |
| 5337 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); | 5337 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); |
| ... | @@ -5543,33 +5543,9 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5543,33 +5543,9 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5543 | while (true) { | 5543 | while (true) { |
| 5544 | switch (m.next().?) { | 5544 | switch (m.next().?) { |
| 5545 | .Asterisk => { | 5545 | .Asterisk => { |
| 5546 | const next = m.peek().?; | 5546 | const lhs = try macroBoolToInt(c, node); |
| 5547 | if (next == .RParen or next == .Nl or next == .Eof) { | 5547 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5548 | // type *) | 5548 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 5549 | | | |
| 5550 | // last token of `node` | | |
| 5551 | const prev_id = m.list[m.i - 1].id; | | |
| 5552 | | | |
| 5553 | if (prev_id == .Keyword_void) { | | |
| 5554 | const ptr = try Tag.single_pointer.create(c.arena, .{ | | |
| 5555 | .is_const = false, | | |
| 5556 | .is_volatile = false, | | |
| 5557 | .elem_type = node, | | |
| 5558 | }); | | |
| 5559 | return Tag.optional_type.create(c.arena, ptr); | | |
| 5560 | } else { | | |
| 5561 | return Tag.c_pointer.create(c.arena, .{ | | |
| 5562 | .is_const = false, | | |
| 5563 | .is_volatile = false, | | |
| 5564 | .elem_type = node, | | |
| 5565 | }); | | |
| 5566 | } | | |
| 5567 | } else { | | |
| 5568 | // expr * expr | | |
| 5569 | const lhs = try macroBoolToInt(c, node); | | |
| 5570 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); | | |
| 5571 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | | |
| 5572 | } | | |
| 5573 | }, | 5549 | }, |
| 5574 | .Slash => { | 5550 | .Slash => { |
| 5575 | const lhs = try macroBoolToInt(c, node); | 5551 | const lhs = try macroBoolToInt(c, node); |
| ... | @@ -5592,7 +5568,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5592,7 +5568,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5592 | fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5568 | fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5593 | switch (m.next().?) { | 5569 | switch (m.next().?) { |
| 5594 | .LParen => { | 5570 | .LParen => { |
| 5595 | if (try parseCTypeName(c, m, scope)) |type_name| { | 5571 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 5596 | if (m.next().? != .RParen) { | 5572 | if (m.next().? != .RParen) { |
| 5597 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | 5573 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5598 | return error.ParseError; | 5574 | return error.ParseError; |
| ... | @@ -5611,19 +5587,21 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5611,19 +5587,21 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5611 | return parseCUnaryExpr(c, m, scope); | 5587 | return parseCUnaryExpr(c, m, scope); |
| 5612 | } | 5588 | } |
| 5613 | | 5589 | |
| 5614 | fn parseCTypeName(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { | 5590 | // allow_fail is set when unsure if we are parsing a type-name |
| 5615 | if (try parseCSpecifierQualifierList(c, m, scope)) |node| { | 5591 | fn parseCTypeName(c: *Context, m: *MacroCtx, scope: *Scope, allow_fail: bool) ParseError!?Node { |
| | 5592 | if (try parseCSpecifierQualifierList(c, m, scope, allow_fail)) |node| { |
| 5616 | return try parseCAbstractDeclarator(c, m, scope, node); | 5593 | return try parseCAbstractDeclarator(c, m, scope, node); |
| 5617 | } else { | 5594 | } else { |
| 5618 | return null; | 5595 | return null; |
| 5619 | } | 5596 | } |
| 5620 | } | 5597 | } |
| 5621 | | 5598 | |
| 5622 | fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { | 5599 | fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_fail: bool) ParseError!?Node { |
| 5623 | switch (m.next().?) { | 5600 | const tok = m.next().?; |
| | 5601 | switch (tok) { |
| 5624 | .Identifier => { | 5602 | .Identifier => { |
| 5625 | const mangled_name = scope.getAlias(m.slice()); | 5603 | const mangled_name = scope.getAlias(m.slice()); |
| 5626 | if (c.typedefs.contains(mangled_name)) { | 5604 | if (!allow_fail or c.typedefs.contains(mangled_name)) { |
| 5627 | return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); | 5605 | return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); |
| 5628 | } | 5606 | } |
| 5629 | }, | 5607 | }, |
| ... | @@ -5657,8 +5635,13 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE | ... | @@ -5657,8 +5635,13 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5657 | else => {}, | 5635 | else => {}, |
| 5658 | } | 5636 | } |
| 5659 | | 5637 | |
| 5660 | m.i -= 1; | 5638 | if (allow_fail) { |
| 5661 | return null; | 5639 | m.i -= 1; |
| | 5640 | return null; |
| | 5641 | } else { |
| | 5642 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); |
| | 5643 | return error.ParseError; |
| | 5644 | } |
| 5662 | } | 5645 | } |
| 5663 | | 5646 | |
| 5664 | fn parseCNumericType(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5647 | fn parseCNumericType(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| ... | @@ -5934,9 +5917,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5934,9 +5917,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5934 | .Keyword_sizeof => { | 5917 | .Keyword_sizeof => { |
| 5935 | const operand = if (m.peek().? == .LParen) blk: { | 5918 | const operand = if (m.peek().? == .LParen) blk: { |
| 5936 | _ = m.next(); | 5919 | _ = m.next(); |
| 5937 | // C grammar says this should be 'type-name' but we have to | 5920 | const inner = (try parseCTypeName(c, m, scope, false)).?; |
| 5938 | // use parseCMulExpr to correctly handle pointer types. | | |
| 5939 | const inner = try parseCMulExpr(c, m, scope); | | |
| 5940 | if (m.next().? != .RParen) { | 5921 | if (m.next().? != .RParen) { |
| 5941 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | 5922 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5942 | return error.ParseError; | 5923 | return error.ParseError; |
| ... | @@ -5953,9 +5934,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5953,9 +5934,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5953 | try m.fail(c, "unable to translate C expr: expected '('", .{}); | 5934 | try m.fail(c, "unable to translate C expr: expected '('", .{}); |
| 5954 | return error.ParseError; | 5935 | return error.ParseError; |
| 5955 | } | 5936 | } |
| 5956 | // C grammar says this should be 'type-name' but we have to | 5937 | const operand = (try parseCTypeName(c, m, scope, false)).?; |
| 5957 | // use parseCMulExpr to correctly handle pointer types. | | |
| 5958 | const operand = try parseCMulExpr(c, m, scope); | | |
| 5959 | if (m.next().? != .RParen) { | 5938 | if (m.next().? != .RParen) { |
| 5960 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | 5939 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5961 | return error.ParseError; | 5940 | return error.ParseError; |