| ... | @@ -5627,44 +5627,20 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE | ... | @@ -5627,44 +5627,20 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5627 | return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); | 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 | .Keyword_void => return try Tag.type.create(c.arena, "c_void"), | 5630 | .Keyword_void => return try Tag.type.create(c.arena, "c_void"), |
| 5632 | .Keyword_bool => return try Tag.type.create(c.arena, "bool"), | 5631 | .Keyword_bool => return try Tag.type.create(c.arena, "bool"), |
| 5633 | .Keyword_double => return try Tag.type.create(c.arena, "f64"), | 5632 | .Keyword_char, |
| 5634 | .Keyword_long => return try Tag.type.create(c.arena, "c_long"), | 5633 | .Keyword_int, |
| 5635 | .Keyword_int => return try Tag.type.create(c.arena, "c_int"), | 5634 | .Keyword_short, |
| 5636 | .Keyword_float => return try Tag.type.create(c.arena, "f32"), | 5635 | .Keyword_long, |
| 5637 | .Keyword_short => return try Tag.type.create(c.arena, "c_short"), | 5636 | .Keyword_float, |
| 5638 | .Keyword_char => return try Tag.type.create(c.arena, "u8"), | 5637 | .Keyword_double, |
| 5639 | .Keyword_unsigned => if (m.next()) |t| switch (t) { | 5638 | .Keyword_signed, |
| 5640 | .Keyword_char => return try Tag.type.create(c.arena, "u8"), | 5639 | .Keyword_unsigned, |
| 5641 | .Keyword_short => return try Tag.type.create(c.arena, "c_ushort"), | 5640 | .Keyword_complex, |
| 5642 | .Keyword_int => return try Tag.type.create(c.arena, "c_uint"), | 5641 | => { |
| 5643 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { | 5642 | m.i -= 1; |
| 5644 | _ = m.next(); | 5643 | return try parseCNumericType(c, m, scope); |
| 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"); | | |
| 5668 | }, | 5644 | }, |
| 5669 | .Keyword_enum, .Keyword_struct, .Keyword_union => { | 5645 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| 5670 | // struct Foo will be declared as struct_Foo by transRecordDecl | 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,7 +5654,6 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5678 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); | 5654 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| 5679 | return try Tag.identifier.create(c.arena, name); | 5655 | return try Tag.identifier.create(c.arena, name); |
| 5680 | }, | 5656 | }, |
| 5681 | .Keyword_complex => {}, // TODO | | |
| 5682 | else => {}, | 5657 | else => {}, |
| 5683 | } | 5658 | } |
| 5684 | | 5659 | |
| ... | @@ -5686,6 +5661,107 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE | ... | @@ -5686,6 +5661,107 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseE |
| 5686 | return null; | 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 | fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, scope: *Scope, node: Node) ParseError!Node { | 5765 | fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, scope: *Scope, node: Node) ParseError!Node { |
| 5690 | switch (m.next().?) { | 5766 | switch (m.next().?) { |
| 5691 | .Asterisk => { | 5767 | .Asterisk => { |