| ... | @@ -280,6 +280,8 @@ pub const Context = struct { | ... | @@ -280,6 +280,8 @@ pub const Context = struct { |
| 280 | opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{}, | 280 | opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{}, |
| 281 | /// Table of unnamed enums and records that are child types of typedefs. | 281 | /// Table of unnamed enums and records that are child types of typedefs. |
| 282 | unnamed_typedefs: std.AutoHashMapUnmanaged(usize, []const u8) = .{}, | 282 | unnamed_typedefs: std.AutoHashMapUnmanaged(usize, []const u8) = .{}, |
| | 283 | /// Needed to decide if we are parsing a typename |
| | 284 | typedefs: std.StringArrayHashMapUnmanaged(void) = .{}, |
| 283 | | 285 | |
| 284 | /// This one is different than the root scope's name table. This contains | 286 | /// This one is different than the root scope's name table. This contains |
| 285 | /// a list of names that we found by visiting all the top level decls without | 287 | /// a list of names that we found by visiting all the top level decls without |
| ... | @@ -348,6 +350,7 @@ pub fn translate( | ... | @@ -348,6 +350,7 @@ pub fn translate( |
| 348 | context.global_names.deinit(gpa); | 350 | context.global_names.deinit(gpa); |
| 349 | context.opaque_demotes.deinit(gpa); | 351 | context.opaque_demotes.deinit(gpa); |
| 350 | context.unnamed_typedefs.deinit(gpa); | 352 | context.unnamed_typedefs.deinit(gpa); |
| | 353 | context.typedefs.deinit(gpa); |
| 351 | context.global_scope.deinit(); | 354 | context.global_scope.deinit(); |
| 352 | } | 355 | } |
| 353 | | 356 | |
| ... | @@ -461,6 +464,7 @@ fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void { | ... | @@ -461,6 +464,7 @@ fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void { |
| 461 | result.value_ptr.* = name; | 464 | result.value_ptr.* = name; |
| 462 | // Put this typedef in the decl_table to avoid redefinitions. | 465 | // Put this typedef in the decl_table to avoid redefinitions. |
| 463 | try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), name); | 466 | try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), name); |
| | 467 | try c.typedefs.put(c.gpa, name, {}); |
| 464 | } | 468 | } |
| 465 | } | 469 | } |
| 466 | } | 470 | } |
| ... | @@ -792,6 +796,8 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa | ... | @@ -792,6 +796,8 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa |
| 792 | // TODO https://github.com/ziglang/zig/issues/3756 | 796 | // TODO https://github.com/ziglang/zig/issues/3756 |
| 793 | // TODO https://github.com/ziglang/zig/issues/1802 | 797 | // TODO https://github.com/ziglang/zig/issues/1802 |
| 794 | var name: []const u8 = if (isZigPrimitiveType(bare_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ bare_name, c.getMangle() }) else bare_name; | 798 | var name: []const u8 = if (isZigPrimitiveType(bare_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ bare_name, c.getMangle() }) else bare_name; |
| | 799 | try c.typedefs.put(c.gpa, name, {}); |
| | 800 | |
| 795 | if (builtin_typedef_map.get(name)) |builtin| { | 801 | if (builtin_typedef_map.get(name)) |builtin| { |
| 796 | return c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin); | 802 | return c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin); |
| 797 | } | 803 | } |
| ... | @@ -5303,56 +5309,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5303,56 +5309,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5303 | .IntegerLiteral, .FloatLiteral => { | 5309 | .IntegerLiteral, .FloatLiteral => { |
| 5304 | return parseCNumLit(c, m); | 5310 | return parseCNumLit(c, m); |
| 5305 | }, | 5311 | }, |
| 5306 | // eventually this will be replaced by std.c.parse which will handle these correctly | | |
| 5307 | .Keyword_void => return Tag.type.create(c.arena, "c_void"), | | |
| 5308 | .Keyword_bool => return Tag.type.create(c.arena, "bool"), | | |
| 5309 | .Keyword_double => return Tag.type.create(c.arena, "f64"), | | |
| 5310 | .Keyword_long => return Tag.type.create(c.arena, "c_long"), | | |
| 5311 | .Keyword_int => return Tag.type.create(c.arena, "c_int"), | | |
| 5312 | .Keyword_float => return Tag.type.create(c.arena, "f32"), | | |
| 5313 | .Keyword_short => return Tag.type.create(c.arena, "c_short"), | | |
| 5314 | .Keyword_char => return Tag.type.create(c.arena, "u8"), | | |
| 5315 | .Keyword_unsigned => if (m.next()) |t| switch (t) { | | |
| 5316 | .Keyword_char => return Tag.type.create(c.arena, "u8"), | | |
| 5317 | .Keyword_short => return Tag.type.create(c.arena, "c_ushort"), | | |
| 5318 | .Keyword_int => return Tag.type.create(c.arena, "c_uint"), | | |
| 5319 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { | | |
| 5320 | _ = m.next(); | | |
| 5321 | return Tag.type.create(c.arena, "c_ulonglong"); | | |
| 5322 | } else return Tag.type.create(c.arena, "c_ulong"), | | |
| 5323 | else => { | | |
| 5324 | m.i -= 1; | | |
| 5325 | return Tag.type.create(c.arena, "c_uint"); | | |
| 5326 | }, | | |
| 5327 | } else { | | |
| 5328 | return Tag.type.create(c.arena, "c_uint"); | | |
| 5329 | }, | | |
| 5330 | .Keyword_signed => if (m.next()) |t| switch (t) { | | |
| 5331 | .Keyword_char => return Tag.type.create(c.arena, "i8"), | | |
| 5332 | .Keyword_short => return Tag.type.create(c.arena, "c_short"), | | |
| 5333 | .Keyword_int => return Tag.type.create(c.arena, "c_int"), | | |
| 5334 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { | | |
| 5335 | _ = m.next(); | | |
| 5336 | return Tag.type.create(c.arena, "c_longlong"); | | |
| 5337 | } else return Tag.type.create(c.arena, "c_long"), | | |
| 5338 | else => { | | |
| 5339 | m.i -= 1; | | |
| 5340 | return Tag.type.create(c.arena, "c_int"); | | |
| 5341 | }, | | |
| 5342 | } else { | | |
| 5343 | return Tag.type.create(c.arena, "c_int"); | | |
| 5344 | }, | | |
| 5345 | .Keyword_enum, .Keyword_struct, .Keyword_union => { | | |
| 5346 | // struct Foo will be declared as struct_Foo by transRecordDecl | | |
| 5347 | const next_id = m.next().?; | | |
| 5348 | if (next_id != .Identifier) { | | |
| 5349 | try m.fail(c, "unable to translate C expr: expected Identifier instead got: {s}", .{@tagName(next_id)}); | | |
| 5350 | return error.ParseError; | | |
| 5351 | } | | |
| 5352 | | | |
| 5353 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); | | |
| 5354 | return Tag.identifier.create(c.arena, name); | | |
| 5355 | }, | | |
| 5356 | .Identifier => { | 5312 | .Identifier => { |
| 5357 | const mangled_name = scope.getAlias(slice); | 5313 | const mangled_name = scope.getAlias(slice); |
| 5358 | if (mem.startsWith(u8, mangled_name, "__builtin_") and !isBuiltinDefined(mangled_name)) { | 5314 | if (mem.startsWith(u8, mangled_name, "__builtin_") and !isBuiltinDefined(mangled_name)) { |
| ... | @@ -5369,37 +5325,15 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5369,37 +5325,15 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5369 | try m.fail(c, "unable to translate C expr: expected ')' instead got: {s}", .{@tagName(next_id)}); | 5325 | try m.fail(c, "unable to translate C expr: expected ')' instead got: {s}", .{@tagName(next_id)}); |
| 5370 | return error.ParseError; | 5326 | return error.ParseError; |
| 5371 | } | 5327 | } |
| 5372 | var saw_l_paren = false; | 5328 | return inner_node; |
| 5373 | var saw_integer_literal = false; | | |
| 5374 | switch (m.peek().?) { | | |
| 5375 | // (type)(to_cast) | | |
| 5376 | .LParen => { | | |
| 5377 | saw_l_paren = true; | | |
| 5378 | _ = m.next(); | | |
| 5379 | }, | | |
| 5380 | // (type)sizeof(x) | | |
| 5381 | .Keyword_sizeof, | | |
| 5382 | // (type)alignof(x) | | |
| 5383 | .Keyword_alignof, | | |
| 5384 | // (type)identifier | | |
| 5385 | .Identifier, | | |
| 5386 | => {}, | | |
| 5387 | // (type)integer | | |
| 5388 | .IntegerLiteral => { | | |
| 5389 | saw_integer_literal = true; | | |
| 5390 | }, | | |
| 5391 | else => return inner_node, | | |
| 5392 | } | | |
| 5393 | const node_to_cast = try parseCExpr(c, m, scope); | | |
| 5394 | | | |
| 5395 | if (saw_l_paren and m.next().? != .RParen) { | | |
| 5396 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | | |
| 5397 | return error.ParseError; | | |
| 5398 | } | | |
| 5399 | | | |
| 5400 | return Tag.std_meta_cast.create(c.arena, .{ .lhs = inner_node, .rhs = node_to_cast }); | | |
| 5401 | }, | 5329 | }, |
| 5402 | else => { | 5330 | else => { |
| | 5331 | // for handling type macros (EVIL) |
| | 5332 | // TODO maybe detect and treat type macros as typedefs in parseCSpecifierQualifierList? |
| | 5333 | m.i -= 1; |
| | 5334 | if (try parseCTypeName(c, m, scope)) |type_name| { |
| | 5335 | return type_name; |
| | 5336 | } |
| 5403 | 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)}); |
| 5404 | return error.ParseError; | 5338 | return error.ParseError; |
| 5405 | }, | 5339 | }, |
| ... | @@ -5605,7 +5539,7 @@ fn parseCAddSubExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5605,7 +5539,7 @@ fn parseCAddSubExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5605 | } | 5539 | } |
| 5606 | | 5540 | |
| 5607 | fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5541 | fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5608 | var node = try parseCUnaryExpr(c, m, scope); | 5542 | var node = try parseCCastExpr(c, m, scope); |
| 5609 | while (true) { | 5543 | while (true) { |
| 5610 | switch (m.next().?) { | 5544 | switch (m.next().?) { |
| 5611 | .Asterisk => { | 5545 | .Asterisk => { |
| ... | @@ -5633,18 +5567,18 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5633,18 +5567,18 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5633 | } else { | 5567 | } else { |
| 5634 | // expr * expr | 5568 | // expr * expr |
| 5635 | const lhs = try macroBoolToInt(c, node); | 5569 | const lhs = try macroBoolToInt(c, node); |
| 5636 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5570 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5637 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 5571 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 5638 | } | 5572 | } |
| 5639 | }, | 5573 | }, |
| 5640 | .Slash => { | 5574 | .Slash => { |
| 5641 | const lhs = try macroBoolToInt(c, node); | 5575 | const lhs = try macroBoolToInt(c, node); |
| 5642 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5576 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5643 | node = try Tag.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 5577 | node = try Tag.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 5644 | }, | 5578 | }, |
| 5645 | .Percent => { | 5579 | .Percent => { |
| 5646 | const lhs = try macroBoolToInt(c, node); | 5580 | const lhs = try macroBoolToInt(c, node); |
| 5647 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5581 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5648 | node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 5582 | node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 5649 | }, | 5583 | }, |
| 5650 | else => { | 5584 | else => { |
| ... | @@ -5655,8 +5589,209 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5655,8 +5589,209 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5655 | } | 5589 | } |
| 5656 | } | 5590 | } |
| 5657 | | 5591 | |
| 5658 | fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5592 | fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5659 | var node = try parseCPrimaryExpr(c, m, scope); | 5593 | switch (m.next().?) { |
| | 5594 | .LParen => { |
| | 5595 | if (try parseCTypeName(c, m, scope)) |type_name| { |
| | 5596 | if (m.next().? != .RParen) { |
| | 5597 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| | 5598 | return error.ParseError; |
| | 5599 | } |
| | 5600 | if (m.peek().? == .LBrace) { |
| | 5601 | // initializer list |
| | 5602 | return parseCPostfixExpr(c, m, scope, type_name); |
| | 5603 | } |
| | 5604 | const node_to_cast = try parseCCastExpr(c, m, scope); |
| | 5605 | return Tag.std_meta_cast.create(c.arena, .{ .lhs = type_name, .rhs = node_to_cast }); |
| | 5606 | } |
| | 5607 | }, |
| | 5608 | else => {}, |
| | 5609 | } |
| | 5610 | m.i -= 1; |
| | 5611 | return parseCUnaryExpr(c, m, scope); |
| | 5612 | } |
| | 5613 | |
| | 5614 | fn parseCTypeName(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { |
| | 5615 | if (try parseCSpecifierQualifierList(c, m, scope)) |node| { |
| | 5616 | return try parseCAbstractDeclarator(c, m, scope, node); |
| | 5617 | } else { |
| | 5618 | return null; |
| | 5619 | } |
| | 5620 | } |
| | 5621 | |
| | 5622 | fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!?Node { |
| | 5623 | switch (m.next().?) { |
| | 5624 | .Identifier => { |
| | 5625 | const mangled_name = scope.getAlias(m.slice()); |
| | 5626 | if (c.typedefs.contains(mangled_name)) { |
| | 5627 | return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); |
| | 5628 | } |
| | 5629 | }, |
| | 5630 | .Keyword_void => return try Tag.type.create(c.arena, "c_void"), |
| | 5631 | .Keyword_bool => return try Tag.type.create(c.arena, "bool"), |
| | 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); |
| | 5644 | }, |
| | 5645 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| | 5646 | // struct Foo will be declared as struct_Foo by transRecordDecl |
| | 5647 | const slice = m.slice(); |
| | 5648 | const next_id = m.next().?; |
| | 5649 | if (next_id != .Identifier) { |
| | 5650 | try m.fail(c, "unable to translate C expr: expected Identifier instead got: {s}", .{@tagName(next_id)}); |
| | 5651 | return error.ParseError; |
| | 5652 | } |
| | 5653 | |
| | 5654 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| | 5655 | return try Tag.identifier.create(c.arena, name); |
| | 5656 | }, |
| | 5657 | else => {}, |
| | 5658 | } |
| | 5659 | |
| | 5660 | m.i -= 1; |
| | 5661 | return null; |
| | 5662 | } |
| | 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 | |
| | 5765 | fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, scope: *Scope, node: Node) ParseError!Node { |
| | 5766 | switch (m.next().?) { |
| | 5767 | .Asterisk => { |
| | 5768 | // last token of `node` |
| | 5769 | const prev_id = m.list[m.i - 1].id; |
| | 5770 | |
| | 5771 | if (prev_id == .Keyword_void) { |
| | 5772 | const ptr = try Tag.single_pointer.create(c.arena, .{ |
| | 5773 | .is_const = false, |
| | 5774 | .is_volatile = false, |
| | 5775 | .elem_type = node, |
| | 5776 | }); |
| | 5777 | return Tag.optional_type.create(c.arena, ptr); |
| | 5778 | } else { |
| | 5779 | return Tag.c_pointer.create(c.arena, .{ |
| | 5780 | .is_const = false, |
| | 5781 | .is_volatile = false, |
| | 5782 | .elem_type = node, |
| | 5783 | }); |
| | 5784 | } |
| | 5785 | }, |
| | 5786 | else => { |
| | 5787 | m.i -= 1; |
| | 5788 | return node; |
| | 5789 | }, |
| | 5790 | } |
| | 5791 | } |
| | 5792 | |
| | 5793 | fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node { |
| | 5794 | var node = type_name orelse try parseCPrimaryExpr(c, m, scope); |
| 5660 | while (true) { | 5795 | while (true) { |
| 5661 | switch (m.next().?) { | 5796 | switch (m.next().?) { |
| 5662 | .Period => { | 5797 | .Period => { |
| ... | @@ -5776,24 +5911,24 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5776,24 +5911,24 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5776 | fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5911 | fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5777 | switch (m.next().?) { | 5912 | switch (m.next().?) { |
| 5778 | .Bang => { | 5913 | .Bang => { |
| 5779 | const operand = try macroIntToBool(c, try parseCUnaryExpr(c, m, scope)); | 5914 | const operand = try macroIntToBool(c, try parseCCastExpr(c, m, scope)); |
| 5780 | return Tag.not.create(c.arena, operand); | 5915 | return Tag.not.create(c.arena, operand); |
| 5781 | }, | 5916 | }, |
| 5782 | .Minus => { | 5917 | .Minus => { |
| 5783 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5918 | const operand = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5784 | return Tag.negate.create(c.arena, operand); | 5919 | return Tag.negate.create(c.arena, operand); |
| 5785 | }, | 5920 | }, |
| 5786 | .Plus => return try parseCUnaryExpr(c, m, scope), | 5921 | .Plus => return try parseCCastExpr(c, m, scope), |
| 5787 | .Tilde => { | 5922 | .Tilde => { |
| 5788 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5923 | const operand = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5789 | return Tag.bit_not.create(c.arena, operand); | 5924 | return Tag.bit_not.create(c.arena, operand); |
| 5790 | }, | 5925 | }, |
| 5791 | .Asterisk => { | 5926 | .Asterisk => { |
| 5792 | const operand = try parseCUnaryExpr(c, m, scope); | 5927 | const operand = try parseCCastExpr(c, m, scope); |
| 5793 | return Tag.deref.create(c.arena, operand); | 5928 | return Tag.deref.create(c.arena, operand); |
| 5794 | }, | 5929 | }, |
| 5795 | .Ampersand => { | 5930 | .Ampersand => { |
| 5796 | const operand = try parseCUnaryExpr(c, m, scope); | 5931 | const operand = try parseCCastExpr(c, m, scope); |
| 5797 | return Tag.address_of.create(c.arena, operand); | 5932 | return Tag.address_of.create(c.arena, operand); |
| 5798 | }, | 5933 | }, |
| 5799 | .Keyword_sizeof => { | 5934 | .Keyword_sizeof => { |
| ... | @@ -5834,7 +5969,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5834,7 +5969,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5834 | }, | 5969 | }, |
| 5835 | else => { | 5970 | else => { |
| 5836 | m.i -= 1; | 5971 | m.i -= 1; |
| 5837 | return try parseCPostfixExpr(c, m, scope); | 5972 | return try parseCPostfixExpr(c, m, scope, null); |
| 5838 | }, | 5973 | }, |
| 5839 | } | 5974 | } |
| 5840 | } | 5975 | } |