| ... | ... | @@ -5331,7 +5331,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5331 | 5331 | // for handling type macros (EVIL) |
| 5332 | 5332 | // TODO maybe detect and treat type macros as typedefs in parseCSpecifierQualifierList? |
| 5333 | 5333 | m.i -= 1; |
| 5334 | | if (try parseCTypeName(c, m, scope)) |type_name| { |
| 5334 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 5335 | 5335 | return type_name; |
| 5336 | 5336 | } |
| 5337 | 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 | 5543 | while (true) { |
| 5544 | 5544 | switch (m.next().?) { |
| 5545 | 5545 | .Asterisk => { |
| 5546 | | const next = m.peek().?; |
| 5547 | | if (next == .RParen or next == .Nl or next == .Eof) { |
| 5548 | | // type *) |
| 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 | | } |
| 5546 | const lhs = try macroBoolToInt(c, node); |
| 5547 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5548 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 5573 | 5549 | }, |
| 5574 | 5550 | .Slash => { |
| 5575 | 5551 | const lhs = try macroBoolToInt(c, node); |
| ... | ... | @@ -5592,7 +5568,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5592 | 5568 | fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5593 | 5569 | switch (m.next().?) { |
| 5594 | 5570 | .LParen => { |
| 5595 | | if (try parseCTypeName(c, m, scope)) |type_name| { |
| 5571 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 5596 | 5572 | if (m.next().? != .RParen) { |
| 5597 | 5573 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5598 | 5574 | return error.ParseError; |
| ... | ... | @@ -5611,19 +5587,21 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5611 | 5587 | return parseCUnaryExpr(c, m, scope); |
| 5612 | 5588 | } |
| 5613 | 5589 | |
| 5614 | | fn parseCTypeName(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { |
| 5615 | | if (try parseCSpecifierQualifierList(c, m, scope)) |node| { |
| 5590 | // allow_fail is set when unsure if we are parsing a type-name |
| 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 | 5593 | return try parseCAbstractDeclarator(c, m, scope, node); |
| 5617 | 5594 | } else { |
| 5618 | 5595 | return null; |
| 5619 | 5596 | } |
| 5620 | 5597 | } |
| 5621 | 5598 | |
| 5622 | | fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { |
| 5623 | | switch (m.next().?) { |
| 5599 | fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_fail: bool) ParseError!?Node { |
| 5600 | const tok = m.next().?; |
| 5601 | switch (tok) { |
| 5624 | 5602 | .Identifier => { |
| 5625 | 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 | 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 | 5635 | else => {}, |
| 5658 | 5636 | } |
| 5659 | 5637 | |
| 5660 | | m.i -= 1; |
| 5661 | | return null; |
| 5638 | if (allow_fail) { |
| 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 | 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 | 5917 | .Keyword_sizeof => { |
| 5935 | 5918 | const operand = if (m.peek().? == .LParen) blk: { |
| 5936 | 5919 | _ = m.next(); |
| 5937 | | // C grammar says this should be 'type-name' but we have to |
| 5938 | | // use parseCMulExpr to correctly handle pointer types. |
| 5939 | | const inner = try parseCMulExpr(c, m, scope); |
| 5920 | const inner = (try parseCTypeName(c, m, scope, false)).?; |
| 5940 | 5921 | if (m.next().? != .RParen) { |
| 5941 | 5922 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5942 | 5923 | return error.ParseError; |
| ... | ... | @@ -5953,9 +5934,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5953 | 5934 | try m.fail(c, "unable to translate C expr: expected '('", .{}); |
| 5954 | 5935 | return error.ParseError; |
| 5955 | 5936 | } |
| 5956 | | // C grammar says this should be 'type-name' but we have to |
| 5957 | | // use parseCMulExpr to correctly handle pointer types. |
| 5958 | | const operand = try parseCMulExpr(c, m, scope); |
| 5937 | const operand = (try parseCTypeName(c, m, scope, false)).?; |
| 5959 | 5938 | if (m.next().? != .RParen) { |
| 5960 | 5939 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5961 | 5940 | return error.ParseError; |