| ... | ... | @@ -5627,44 +5627,20 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5627 | 5627 | return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); |
| 5628 | 5628 | } |
| 5629 | 5629 | }, |
| 5630 | | // eventually this will be replaced by std.c.parse which will handle these correctly |
| 5631 | 5630 | .Keyword_void => return try Tag.type.create(c.arena, "c_void"), |
| 5632 | 5631 | .Keyword_bool => return try Tag.type.create(c.arena, "bool"), |
| 5633 | | .Keyword_double => return try Tag.type.create(c.arena, "f64"), |
| 5634 | | .Keyword_long => return try Tag.type.create(c.arena, "c_long"), |
| 5635 | | .Keyword_int => return try Tag.type.create(c.arena, "c_int"), |
| 5636 | | .Keyword_float => return try Tag.type.create(c.arena, "f32"), |
| 5637 | | .Keyword_short => return try Tag.type.create(c.arena, "c_short"), |
| 5638 | | .Keyword_char => return try Tag.type.create(c.arena, "u8"), |
| 5639 | | .Keyword_unsigned => if (m.next()) |t| switch (t) { |
| 5640 | | .Keyword_char => return try Tag.type.create(c.arena, "u8"), |
| 5641 | | .Keyword_short => return try Tag.type.create(c.arena, "c_ushort"), |
| 5642 | | .Keyword_int => return try Tag.type.create(c.arena, "c_uint"), |
| 5643 | | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 5644 | | _ = m.next(); |
| 5645 | | return try Tag.type.create(c.arena, "c_ulonglong"); |
| 5646 | | } else return try Tag.type.create(c.arena, "c_ulong"), |
| 5647 | | else => { |
| 5648 | | m.i -= 1; |
| 5649 | | return try Tag.type.create(c.arena, "c_uint"); |
| 5650 | | }, |
| 5651 | | } else { |
| 5652 | | return try Tag.type.create(c.arena, "c_uint"); |
| 5653 | | }, |
| 5654 | | .Keyword_signed => if (m.next()) |t| switch (t) { |
| 5655 | | .Keyword_char => return try Tag.type.create(c.arena, "i8"), |
| 5656 | | .Keyword_short => return try Tag.type.create(c.arena, "c_short"), |
| 5657 | | .Keyword_int => return try Tag.type.create(c.arena, "c_int"), |
| 5658 | | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 5659 | | _ = m.next(); |
| 5660 | | return try Tag.type.create(c.arena, "c_longlong"); |
| 5661 | | } else return try Tag.type.create(c.arena, "c_long"), |
| 5662 | | else => { |
| 5663 | | m.i -= 1; |
| 5664 | | return try Tag.type.create(c.arena, "c_int"); |
| 5665 | | }, |
| 5666 | | } else { |
| 5667 | | return try Tag.type.create(c.arena, "c_int"); |
| 5632 | .Keyword_char, |
| 5633 | .Keyword_int, |
| 5634 | .Keyword_short, |
| 5635 | .Keyword_long, |
| 5636 | .Keyword_float, |
| 5637 | .Keyword_double, |
| 5638 | .Keyword_signed, |
| 5639 | .Keyword_unsigned, |
| 5640 | .Keyword_complex, |
| 5641 | => { |
| 5642 | m.i -= 1; |
| 5643 | return try parseCNumericType(c, m, scope); |
| 5668 | 5644 | }, |
| 5669 | 5645 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| 5670 | 5646 | // struct Foo will be declared as struct_Foo by transRecordDecl |
| ... | ... | @@ -5678,7 +5654,6 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5678 | 5654 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| 5679 | 5655 | return try Tag.identifier.create(c.arena, name); |
| 5680 | 5656 | }, |
| 5681 | | .Keyword_complex => {}, // TODO |
| 5682 | 5657 | else => {}, |
| 5683 | 5658 | } |
| 5684 | 5659 | |
| ... | ... | @@ -5686,6 +5661,107 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5686 | 5661 | return null; |
| 5687 | 5662 | } |
| 5688 | 5663 | |
| 5664 | fn parseCNumericType(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5665 | const KwCounter = struct { |
| 5666 | double: u8 = 0, |
| 5667 | long: u8 = 0, |
| 5668 | int: u8 = 0, |
| 5669 | float: u8 = 0, |
| 5670 | short: u8 = 0, |
| 5671 | char: u8 = 0, |
| 5672 | unsigned: u8 = 0, |
| 5673 | signed: u8 = 0, |
| 5674 | complex: u8 = 0, |
| 5675 | |
| 5676 | fn eql(self: @This(), other: @This()) bool { |
| 5677 | return meta.eql(self, other); |
| 5678 | } |
| 5679 | }; |
| 5680 | |
| 5681 | // Yes, these can be in *any* order |
| 5682 | // This still doesn't cover cases where for example volatile is intermixed |
| 5683 | |
| 5684 | var kw = KwCounter{}; |
| 5685 | // prevent overflow |
| 5686 | var i: u8 = 0; |
| 5687 | while (i < math.maxInt(u8)) : (i += 1) { |
| 5688 | switch (m.next().?) { |
| 5689 | .Keyword_double => kw.double += 1, |
| 5690 | .Keyword_long => kw.long += 1, |
| 5691 | .Keyword_int => kw.int += 1, |
| 5692 | .Keyword_float => kw.float += 1, |
| 5693 | .Keyword_short => kw.short += 1, |
| 5694 | .Keyword_char => kw.char += 1, |
| 5695 | .Keyword_unsigned => kw.unsigned += 1, |
| 5696 | .Keyword_signed => kw.signed += 1, |
| 5697 | .Keyword_complex => kw.complex += 1, |
| 5698 | else => { |
| 5699 | m.i -= 1; |
| 5700 | break; |
| 5701 | }, |
| 5702 | } |
| 5703 | } |
| 5704 | |
| 5705 | if (kw.eql(.{ .int = 1 }) or kw.eql(.{ .signed = 1 }) or kw.eql(.{ .signed = 1, .int = 1 })) |
| 5706 | return Tag.type.create(c.arena, "c_int"); |
| 5707 | |
| 5708 | if (kw.eql(.{ .unsigned = 1 }) or kw.eql(.{ .unsigned = 1, .int = 1 })) |
| 5709 | return Tag.type.create(c.arena, "c_uint"); |
| 5710 | |
| 5711 | if (kw.eql(.{ .long = 1 }) or kw.eql(.{ .signed = 1, .long = 1 }) or kw.eql(.{ .long = 1, .int = 1 }) or kw.eql(.{ .signed = 1, .long = 1, .int = 1 })) |
| 5712 | return Tag.type.create(c.arena, "c_long"); |
| 5713 | |
| 5714 | if (kw.eql(.{ .unsigned = 1, .long = 1 }) or kw.eql(.{ .unsigned = 1, .long = 1, .int = 1 })) |
| 5715 | return Tag.type.create(c.arena, "c_ulong"); |
| 5716 | |
| 5717 | if (kw.eql(.{ .long = 2 }) or kw.eql(.{ .signed = 1, .long = 2 }) or kw.eql(.{ .long = 2, .int = 1 }) or kw.eql(.{ .signed = 1, .long = 2, .int = 1 })) |
| 5718 | return Tag.type.create(c.arena, "c_longlong"); |
| 5719 | |
| 5720 | if (kw.eql(.{ .unsigned = 1, .long = 2 }) or kw.eql(.{ .unsigned = 1, .long = 2, .int = 1 })) |
| 5721 | return Tag.type.create(c.arena, "c_ulonglong"); |
| 5722 | |
| 5723 | if (kw.eql(.{ .signed = 1, .char = 1 })) |
| 5724 | return Tag.type.create(c.arena, "i8"); |
| 5725 | |
| 5726 | if (kw.eql(.{ .char = 1 }) or kw.eql(.{ .unsigned = 1, .char = 1 })) |
| 5727 | return Tag.type.create(c.arena, "u8"); |
| 5728 | |
| 5729 | if (kw.eql(.{ .short = 1 }) or kw.eql(.{ .signed = 1, .short = 1 }) or kw.eql(.{ .short = 1, .int = 1 }) or kw.eql(.{ .signed = 1, .short = 1, .int = 1 })) |
| 5730 | return Tag.type.create(c.arena, "c_short"); |
| 5731 | |
| 5732 | if (kw.eql(.{ .unsigned = 1, .short = 1 }) or kw.eql(.{ .unsigned = 1, .short = 1, .int = 1 })) |
| 5733 | return Tag.type.create(c.arena, "c_ushort"); |
| 5734 | |
| 5735 | if (kw.eql(.{ .float = 1 })) |
| 5736 | return Tag.type.create(c.arena, "f32"); |
| 5737 | |
| 5738 | if (kw.eql(.{ .double = 1 })) |
| 5739 | return Tag.type.create(c.arena, "f64"); |
| 5740 | |
| 5741 | if (kw.eql(.{ .long = 1, .double = 1 })) { |
| 5742 | try m.fail(c, "unable to translate: TODO long double", .{}); |
| 5743 | return error.ParseError; |
| 5744 | } |
| 5745 | |
| 5746 | if (kw.eql(.{ .float = 1, .complex = 1 })) { |
| 5747 | try m.fail(c, "unable to translate: TODO _Complex", .{}); |
| 5748 | return error.ParseError; |
| 5749 | } |
| 5750 | |
| 5751 | if (kw.eql(.{ .double = 1, .complex = 1 })) { |
| 5752 | try m.fail(c, "unable to translate: TODO _Complex", .{}); |
| 5753 | return error.ParseError; |
| 5754 | } |
| 5755 | |
| 5756 | if (kw.eql(.{ .long = 1, .double = 1, .complex = 1 })) { |
| 5757 | try m.fail(c, "unable to translate: TODO _Complex", .{}); |
| 5758 | return error.ParseError; |
| 5759 | } |
| 5760 | |
| 5761 | try m.fail(c, "unable to translate: invalid numeric type", .{}); |
| 5762 | return error.ParseError; |
| 5763 | } |
| 5764 | |
| 5689 | 5765 | fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, scope: *Scope, node: Node) ParseError!Node { |
| 5690 | 5766 | switch (m.next().?) { |
| 5691 | 5767 | .Asterisk => { |