| ... | @@ -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,133 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5655,8 +5589,133 @@ 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 | // 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"), |
| | 5632 | .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"); |
| | 5668 | }, |
| | 5669 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| | 5670 | // struct Foo will be declared as struct_Foo by transRecordDecl |
| | 5671 | const slice = m.slice(); |
| | 5672 | const next_id = m.next().?; |
| | 5673 | if (next_id != .Identifier) { |
| | 5674 | try m.fail(c, "unable to translate C expr: expected Identifier instead got: {s}", .{@tagName(next_id)}); |
| | 5675 | return error.ParseError; |
| | 5676 | } |
| | 5677 | |
| | 5678 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| | 5679 | return try Tag.identifier.create(c.arena, name); |
| | 5680 | }, |
| | 5681 | .Keyword_complex => {}, // TODO |
| | 5682 | else => {}, |
| | 5683 | } |
| | 5684 | |
| | 5685 | m.i -= 1; |
| | 5686 | return null; |
| | 5687 | } |
| | 5688 | |
| | 5689 | fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, scope: *Scope, node: Node) ParseError!Node { |
| | 5690 | switch (m.next().?) { |
| | 5691 | .Asterisk => { |
| | 5692 | // last token of `node` |
| | 5693 | const prev_id = m.list[m.i - 1].id; |
| | 5694 | |
| | 5695 | if (prev_id == .Keyword_void) { |
| | 5696 | const ptr = try Tag.single_pointer.create(c.arena, .{ |
| | 5697 | .is_const = false, |
| | 5698 | .is_volatile = false, |
| | 5699 | .elem_type = node, |
| | 5700 | }); |
| | 5701 | return Tag.optional_type.create(c.arena, ptr); |
| | 5702 | } else { |
| | 5703 | return Tag.c_pointer.create(c.arena, .{ |
| | 5704 | .is_const = false, |
| | 5705 | .is_volatile = false, |
| | 5706 | .elem_type = node, |
| | 5707 | }); |
| | 5708 | } |
| | 5709 | }, |
| | 5710 | else => { |
| | 5711 | m.i -= 1; |
| | 5712 | return node; |
| | 5713 | }, |
| | 5714 | } |
| | 5715 | } |
| | 5716 | |
| | 5717 | fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node { |
| | 5718 | var node = type_name orelse try parseCPrimaryExpr(c, m, scope); |
| 5660 | while (true) { | 5719 | while (true) { |
| 5661 | switch (m.next().?) { | 5720 | switch (m.next().?) { |
| 5662 | .Period => { | 5721 | .Period => { |
| ... | @@ -5776,24 +5835,24 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5776,24 +5835,24 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5776 | fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 5835 | fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5777 | switch (m.next().?) { | 5836 | switch (m.next().?) { |
| 5778 | .Bang => { | 5837 | .Bang => { |
| 5779 | const operand = try macroIntToBool(c, try parseCUnaryExpr(c, m, scope)); | 5838 | const operand = try macroIntToBool(c, try parseCCastExpr(c, m, scope)); |
| 5780 | return Tag.not.create(c.arena, operand); | 5839 | return Tag.not.create(c.arena, operand); |
| 5781 | }, | 5840 | }, |
| 5782 | .Minus => { | 5841 | .Minus => { |
| 5783 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5842 | const operand = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5784 | return Tag.negate.create(c.arena, operand); | 5843 | return Tag.negate.create(c.arena, operand); |
| 5785 | }, | 5844 | }, |
| 5786 | .Plus => return try parseCUnaryExpr(c, m, scope), | 5845 | .Plus => return try parseCCastExpr(c, m, scope), |
| 5787 | .Tilde => { | 5846 | .Tilde => { |
| 5788 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 5847 | const operand = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 5789 | return Tag.bit_not.create(c.arena, operand); | 5848 | return Tag.bit_not.create(c.arena, operand); |
| 5790 | }, | 5849 | }, |
| 5791 | .Asterisk => { | 5850 | .Asterisk => { |
| 5792 | const operand = try parseCUnaryExpr(c, m, scope); | 5851 | const operand = try parseCCastExpr(c, m, scope); |
| 5793 | return Tag.deref.create(c.arena, operand); | 5852 | return Tag.deref.create(c.arena, operand); |
| 5794 | }, | 5853 | }, |
| 5795 | .Ampersand => { | 5854 | .Ampersand => { |
| 5796 | const operand = try parseCUnaryExpr(c, m, scope); | 5855 | const operand = try parseCCastExpr(c, m, scope); |
| 5797 | return Tag.address_of.create(c.arena, operand); | 5856 | return Tag.address_of.create(c.arena, operand); |
| 5798 | }, | 5857 | }, |
| 5799 | .Keyword_sizeof => { | 5858 | .Keyword_sizeof => { |
| ... | @@ -5834,7 +5893,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5834,7 +5893,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5834 | }, | 5893 | }, |
| 5835 | else => { | 5894 | else => { |
| 5836 | m.i -= 1; | 5895 | m.i -= 1; |
| 5837 | return try parseCPostfixExpr(c, m, scope); | 5896 | return try parseCPostfixExpr(c, m, scope, null); |
| 5838 | }, | 5897 | }, |
| 5839 | } | 5898 | } |
| 5840 | } | 5899 | } |