| ... | @@ -614,25 +614,21 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -614,25 +614,21 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 614 | return addTopLevelDecl(c, fn_name, &proto_node.base); | 614 | return addTopLevelDecl(c, fn_name, &proto_node.base); |
| 615 | } | 615 | } |
| 616 | | 616 | |
| 617 | fn transQualTypeMaybeInitialized(rp: RestorePoint, qt: clang.QualType, decl_init: ?*const clang.Expr, loc: clang.SourceLocation) TransError!*ast.Node { | 617 | fn transQualTypeMaybeInitialized(c: *Context, qt: clang.QualType, decl_init: ?*const clang.Expr, loc: clang.SourceLocation) TransError!Node { |
| 618 | return if (decl_init) |init_expr| | 618 | return if (decl_init) |init_expr| |
| 619 | transQualTypeInitialized(rp, qt, init_expr, loc) | 619 | transQualTypeInitialized(c, qt, init_expr, loc) |
| 620 | else | 620 | else |
| 621 | transQualType(rp, qt, loc); | 621 | transQualType(c, qt, loc); |
| 622 | } | 622 | } |
| | 623 | |
| 623 | /// if mangled_name is not null, this var decl was declared in a block scope. | 624 | /// if mangled_name is not null, this var decl was declared in a block scope. |
| 624 | fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]const u8) Error!void { | 625 | fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]const u8) Error!void { |
| 625 | const var_name = mangled_name orelse try c.str(@ptrCast(*const clang.NamedDecl, var_decl).getName_bytes_begin()); | 626 | const var_name = mangled_name orelse try c.str(@ptrCast(*const clang.NamedDecl, var_decl).getName_bytes_begin()); |
| 626 | if (c.global_scope.sym_table.contains(var_name)) | 627 | if (c.global_scope.sym_table.contains(var_name)) |
| 627 | return; // Avoid processing this decl twice | 628 | return; // Avoid processing this decl twice |
| 628 | const rp = makeRestorePoint(c); | | |
| 629 | const visib_tok = if (mangled_name) |_| null else try appendToken(c, .Keyword_pub, "pub"); | | |
| 630 | | | |
| 631 | const thread_local_token = if (var_decl.getTLSKind() == .None) | | |
| 632 | null | | |
| 633 | else | | |
| 634 | try appendToken(c, .Keyword_threadlocal, "threadlocal"); | | |
| 635 | | 629 | |
| | 630 | const is_pub = mangled_name == null; |
| | 631 | const is_thread_local = var_decl.getTLSKind() != .None; |
| 636 | const scope = &c.global_scope.base; | 632 | const scope = &c.global_scope.base; |
| 637 | | 633 | |
| 638 | // TODO https://github.com/ziglang/zig/issues/3756 | 634 | // TODO https://github.com/ziglang/zig/issues/3756 |
| ... | @@ -651,42 +647,27 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -651,42 +647,27 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 651 | // does the same as: | 647 | // does the same as: |
| 652 | // extern int foo; | 648 | // extern int foo; |
| 653 | // int foo = 2; | 649 | // int foo = 2; |
| 654 | const extern_tok = if (storage_class == .Extern and !has_init) | 650 | const is_extern = storage_class == .Extern and !has_init; |
| 655 | try appendToken(c, .Keyword_extern, "extern") | 651 | const is_export = !is_extern and storage_class != .Static; |
| 656 | else if (storage_class != .Static) | | |
| 657 | try appendToken(c, .Keyword_export, "export") | | |
| 658 | else | | |
| 659 | null; | | |
| 660 | | | |
| 661 | const mut_tok = if (is_const) | | |
| 662 | try appendToken(c, .Keyword_const, "const") | | |
| 663 | else | | |
| 664 | try appendToken(c, .Keyword_var, "var"); | | |
| 665 | | 652 | |
| 666 | const name_tok = try appendIdentifier(c, checked_name); | 653 | const type_node = transQualTypeMaybeInitialized(c, qual_type, decl_init, var_decl_loc) catch |err| switch (err) { |
| 667 | | | |
| 668 | _ = try appendToken(c, .Colon, ":"); | | |
| 669 | | | |
| 670 | const type_node = transQualTypeMaybeInitialized(rp, qual_type, decl_init, var_decl_loc) catch |err| switch (err) { | | |
| 671 | error.UnsupportedTranslation, error.UnsupportedType => { | 654 | error.UnsupportedTranslation, error.UnsupportedType => { |
| 672 | return failDecl(c, var_decl_loc, checked_name, "unable to resolve variable type", .{}); | 655 | return failDecl(c, var_decl_loc, checked_name, "unable to resolve variable type", .{}); |
| 673 | }, | 656 | }, |
| 674 | error.OutOfMemory => |e| return e, | 657 | error.OutOfMemory => |e| return e, |
| 675 | }; | 658 | }; |
| 676 | | 659 | |
| 677 | var eq_tok: ast.TokenIndex = undefined; | 660 | var init_node: ?Node = null; |
| 678 | var init_node: ?*ast.Node = null; | | |
| 679 | | 661 | |
| 680 | // If the initialization expression is not present, initialize with undefined. | 662 | // If the initialization expression is not present, initialize with undefined. |
| 681 | // If it is an integer literal, we can skip the @as since it will be redundant | 663 | // If it is an integer literal, we can skip the @as since it will be redundant |
| 682 | // with the variable type. | 664 | // with the variable type. |
| 683 | if (has_init) { | 665 | if (has_init) { |
| 684 | eq_tok = try appendToken(c, .Equal, "="); | | |
| 685 | if (decl_init) |expr| { | 666 | if (decl_init) |expr| { |
| 686 | const node_or_error = if (expr.getStmtClass() == .StringLiteralClass) | 667 | const node_or_error = if (expr.getStmtClass() == .StringLiteralClass) |
| 687 | transStringLiteralAsArray(rp, &c.global_scope.base, @ptrCast(*const clang.StringLiteral, expr), zigArraySize(rp.c, type_node) catch 0) | 668 | transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), zigArraySize(c, type_node) catch 0) |
| 688 | else | 669 | else |
| 689 | transExprCoercing(rp, scope, expr, .used, .r_value); | 670 | transExprCoercing(c, scope, expr, .used, .r_value); |
| 690 | init_node = node_or_error catch |err| switch (err) { | 671 | init_node = node_or_error catch |err| switch (err) { |
| 691 | error.UnsupportedTranslation, | 672 | error.UnsupportedTranslation, |
| 692 | error.UnsupportedType, | 673 | error.UnsupportedType, |
| ... | @@ -695,118 +676,83 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -695,118 +676,83 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 695 | }, | 676 | }, |
| 696 | error.OutOfMemory => |e| return e, | 677 | error.OutOfMemory => |e| return e, |
| 697 | }; | 678 | }; |
| | 679 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| | 680 | init_node = try Node.bool_to_int.create(c.arena, init_node); |
| | 681 | } |
| 698 | } else { | 682 | } else { |
| 699 | init_node = try transCreateNodeUndefinedLiteral(c); | 683 | init_node = Node.undefined_literal.init(); |
| 700 | } | 684 | } |
| 701 | } else if (storage_class != .Extern) { | 685 | } else if (storage_class != .Extern) { |
| 702 | eq_tok = try appendToken(c, .Equal, "="); | | |
| 703 | // The C language specification states that variables with static or threadlocal | 686 | // The C language specification states that variables with static or threadlocal |
| 704 | // storage without an initializer are initialized to a zero value. | 687 | // storage without an initializer are initialized to a zero value. |
| 705 | | 688 | |
| 706 | // @import("std").mem.zeroes(T) | 689 | // @import("std").mem.zeroes(T) |
| 707 | const import_fn_call = try c.createBuiltinCall("@import", 1); | 690 | init_node = try Node.std_mem_zeroes.create(c.arena, type_node); |
| 708 | const std_node = try transCreateNodeStringLiteral(c, "\"std\""); | | |
| 709 | import_fn_call.params()[0] = std_node; | | |
| 710 | import_fn_call.rparen_token = try appendToken(c, .RParen, ")"); | | |
| 711 | const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "mem"); | | |
| 712 | const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "zeroes"); | | |
| 713 | | | |
| 714 | const zero_init_call = try c.createCall(outer_field_access, 1); | | |
| 715 | zero_init_call.params()[0] = type_node; | | |
| 716 | zero_init_call.rtoken = try appendToken(c, .RParen, ")"); | | |
| 717 | | | |
| 718 | init_node = &zero_init_call.base; | | |
| 719 | } | 691 | } |
| 720 | | 692 | |
| 721 | const linksection_expr = blk: { | 693 | const linksection_string = blk: { |
| 722 | var str_len: usize = undefined; | 694 | var str_len: usize = undefined; |
| 723 | if (var_decl.getSectionAttribute(&str_len)) |str_ptr| { | 695 | if (var_decl.getSectionAttribute(&str_len)) |str_ptr| { |
| 724 | _ = try appendToken(rp.c, .Keyword_linksection, "linksection"); | 696 | break :blk str_ptr[0..str_len]; |
| 725 | _ = try appendToken(rp.c, .LParen, "("); | | |
| 726 | const expr = try transCreateNodeStringLiteral( | | |
| 727 | rp.c, | | |
| 728 | try std.fmt.allocPrint(rp.c.arena, "\"{s}\"", .{str_ptr[0..str_len]}), | | |
| 729 | ); | | |
| 730 | _ = try appendToken(rp.c, .RParen, ")"); | | |
| 731 | | | |
| 732 | break :blk expr; | | |
| 733 | } | 697 | } |
| 734 | break :blk null; | 698 | break :blk null; |
| 735 | }; | 699 | }; |
| 736 | | 700 | |
| 737 | const align_expr = blk: { | 701 | const alignment = blk: { |
| 738 | const alignment = var_decl.getAlignedAttribute(rp.c.clang_context); | 702 | const alignment = var_decl.getAlignedAttribute(c.clang_context); |
| 739 | if (alignment != 0) { | 703 | if (alignment != 0) { |
| 740 | _ = try appendToken(rp.c, .Keyword_align, "align"); | | |
| 741 | _ = try appendToken(rp.c, .LParen, "("); | | |
| 742 | // Clang reports the alignment in bits | 704 | // Clang reports the alignment in bits |
| 743 | const expr = try transCreateNodeInt(rp.c, alignment / 8); | 705 | break :blk alignment / 8; |
| 744 | _ = try appendToken(rp.c, .RParen, ")"); | | |
| 745 | | | |
| 746 | break :blk expr; | | |
| 747 | } | 706 | } |
| 748 | break :blk null; | 707 | break :blk null; |
| 749 | }; | 708 | }; |
| 750 | | 709 | |
| 751 | const node = try ast.Node.VarDecl.create(c.arena, .{ | 710 | const node = try Node.var_decl.create(c.arena, .{ |
| 752 | .name_token = name_tok, | 711 | .is_pub = is_pub, |
| 753 | .mut_token = mut_tok, | 712 | .is_const = is_const, |
| 754 | .semicolon_token = try appendToken(c, .Semicolon, ";"), | 713 | .is_extern = is_extern, |
| 755 | }, .{ | 714 | .is_export = is_export, |
| 756 | .visib_token = visib_tok, | 715 | .linksection_string = linksection_string, |
| 757 | .thread_local_token = thread_local_token, | 716 | .alignment = alignment, |
| 758 | .eq_token = eq_tok, | 717 | .name = checked_name, |
| 759 | .extern_export_token = extern_tok, | 718 | .type = type_node, |
| 760 | .type_node = type_node, | 719 | .init = init_node, |
| 761 | .align_node = align_expr, | | |
| 762 | .section_node = linksection_expr, | | |
| 763 | .init_node = init_node, | | |
| 764 | }); | 720 | }); |
| 765 | return addTopLevelDecl(c, checked_name, &node.base); | 721 | return addTopLevelDecl(c, checked_name, &node.base); |
| 766 | } | 722 | } |
| 767 | | 723 | |
| 768 | fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !*ast.Node { | 724 | fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !Node { |
| 769 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name); | 725 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name); |
| 770 | return transCreateNodeIdentifier(c, builtin_name); | 726 | return Node.identifier.create(c.arena, builtin_name); |
| 771 | } | 727 | } |
| 772 | | 728 | |
| 773 | fn checkForBuiltinTypedef(checked_name: []const u8) ?[]const u8 { | 729 | const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{ |
| 774 | const table = [_][2][]const u8{ | 730 | .{ "uint8_t", "u8" }, |
| 775 | .{ "uint8_t", "u8" }, | 731 | .{ "int8_t", "i8" }, |
| 776 | .{ "int8_t", "i8" }, | 732 | .{ "uint16_t", "u16" }, |
| 777 | .{ "uint16_t", "u16" }, | 733 | .{ "int16_t", "i16" }, |
| 778 | .{ "int16_t", "i16" }, | 734 | .{ "uint32_t", "u32" }, |
| 779 | .{ "uint32_t", "u32" }, | 735 | .{ "int32_t", "i32" }, |
| 780 | .{ "int32_t", "i32" }, | 736 | .{ "uint64_t", "u64" }, |
| 781 | .{ "uint64_t", "u64" }, | 737 | .{ "int64_t", "i64" }, |
| 782 | .{ "int64_t", "i64" }, | 738 | .{ "intptr_t", "isize" }, |
| 783 | .{ "intptr_t", "isize" }, | 739 | .{ "uintptr_t", "usize" }, |
| 784 | .{ "uintptr_t", "usize" }, | 740 | .{ "ssize_t", "isize" }, |
| 785 | .{ "ssize_t", "isize" }, | 741 | .{ "size_t", "usize" }, |
| 786 | .{ "size_t", "usize" }, | 742 | }); |
| 787 | }; | | |
| 788 | | | |
| 789 | for (table) |entry| { | | |
| 790 | if (mem.eql(u8, checked_name, entry[0])) { | | |
| 791 | return entry[1]; | | |
| 792 | } | | |
| 793 | } | | |
| 794 | | | |
| 795 | return null; | | |
| 796 | } | | |
| 797 | | 743 | |
| 798 | fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_level_visit: bool) Error!?*ast.Node { | 744 | fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_level_visit: bool) Error!?Node { |
| 799 | if (c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl()))) |name| | 745 | if (c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl()))) |name| |
| 800 | return transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 746 | return transCreateNodeIdentifier(c, name); // Avoid processing this decl twice |
| 801 | const rp = makeRestorePoint(c); | | |
| 802 | | 747 | |
| 803 | const typedef_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin()); | 748 | const typedef_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin()); |
| 804 | | 749 | |
| 805 | // TODO https://github.com/ziglang/zig/issues/3756 | 750 | // TODO https://github.com/ziglang/zig/issues/3756 |
| 806 | // TODO https://github.com/ziglang/zig/issues/1802 | 751 | // TODO https://github.com/ziglang/zig/issues/1802 |
| 807 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ typedef_name, c.getMangle() }) else typedef_name; | 752 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ typedef_name, c.getMangle() }) else typedef_name; |
| 808 | if (checkForBuiltinTypedef(checked_name)) |builtin| { | 753 | if (builtin_typedef_map.get(checked_name)) |builtin| { |
| 809 | return transTypeDefAsBuiltin(c, typedef_decl, builtin); | 754 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin); |
| | 755 | return Node.identifier.create(c.arena, builtin); |
| 810 | } | 756 | } |
| 811 | | 757 | |
| 812 | if (!top_level_visit) { | 758 | if (!top_level_visit) { |
| ... | @@ -814,42 +760,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev | ... | @@ -814,42 +760,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev |
| 814 | } | 760 | } |
| 815 | | 761 | |
| 816 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name); | 762 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name); |
| 817 | const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null; | 763 | const node = (try transCreateNodeTypedef(c, typedef_decl, true, checked_name)) orelse return null; |
| 818 | try addTopLevelDecl(c, checked_name, node); | 764 | try addTopLevelDecl(c, checked_name, node); |
| 819 | return transCreateNodeIdentifier(c, checked_name); | 765 | return transCreateNodeIdentifier(c, checked_name); |
| 820 | } | 766 | } |
| 821 | | 767 | |
| 822 | fn transCreateNodeTypedef( | 768 | fn transCreateNodeTypedef( |
| 823 | rp: RestorePoint, | 769 | c: *Context, |
| 824 | typedef_decl: *const clang.TypedefNameDecl, | 770 | typedef_decl: *const clang.TypedefNameDecl, |
| 825 | toplevel: bool, | 771 | toplevel: bool, |
| 826 | checked_name: []const u8, | 772 | checked_name: []const u8, |
| 827 | ) Error!?*ast.Node { | 773 | ) Error!?Node { |
| 828 | const visib_tok = if (toplevel) try appendToken(rp.c, .Keyword_pub, "pub") else null; | | |
| 829 | const mut_tok = try appendToken(rp.c, .Keyword_const, "const"); | | |
| 830 | const name_tok = try appendIdentifier(rp.c, checked_name); | | |
| 831 | const eq_token = try appendToken(rp.c, .Equal, "="); | | |
| 832 | const child_qt = typedef_decl.getUnderlyingType(); | 774 | const child_qt = typedef_decl.getUnderlyingType(); |
| 833 | const typedef_loc = typedef_decl.getLocation(); | 775 | const typedef_loc = typedef_decl.getLocation(); |
| 834 | const init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) { | 776 | const init_node = transQualType(c, child_qt, typedef_loc) catch |err| switch (err) { |
| 835 | error.UnsupportedType => { | 777 | error.UnsupportedType => { |
| 836 | try failDecl(rp.c, typedef_loc, checked_name, "unable to resolve typedef child type", .{}); | 778 | try failDecl(c, typedef_loc, checked_name, "unable to resolve typedef child type", .{}); |
| 837 | return null; | 779 | return null; |
| 838 | }, | 780 | }, |
| 839 | error.OutOfMemory => |e| return e, | 781 | error.OutOfMemory => |e| return e, |
| 840 | }; | 782 | }; |
| 841 | const semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | | |
| 842 | | 783 | |
| 843 | const node = try ast.Node.VarDecl.create(rp.c.arena, .{ | 784 | const payload = try c.arena.create(ast.Payload.Typedef); |
| 844 | .name_token = name_tok, | 785 | payload.* = .{ |
| 845 | .mut_token = mut_tok, | 786 | .base = .{ .tag = ([2]ast.Node.Tag{ .typedef, .pub_typedef })[toplevel] }, |
| 846 | .semicolon_token = semicolon_token, | 787 | .data = .{ |
| 847 | }, .{ | 788 | .name = checked_name, |
| 848 | .visib_token = visib_tok, | 789 | .init = init_node, |
| 849 | .eq_token = eq_token, | 790 | }, |
| 850 | .init_node = init_node, | 791 | }; |
| 851 | }); | 792 | return Node.initPayload(&payload.base); |
| 852 | return &node.base; | | |
| 853 | } | 793 | } |
| 854 | | 794 | |
| 855 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*ast.Node { | 795 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*ast.Node { |
| ... | @@ -1399,13 +1339,15 @@ fn transBinaryOperator( | ... | @@ -1399,13 +1339,15 @@ fn transBinaryOperator( |
| 1399 | const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); | 1339 | const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); |
| 1400 | const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); | 1340 | const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); |
| 1401 | | 1341 | |
| 1402 | const lhs = if (isBoolRes(lhs_uncasted)) | 1342 | const lhs = if (isBoolRes(lhs_uncasted)) |
| 1403 | try Node.bool_to_int.create(c.arena, lhs_uncasted) | 1343 | try Node.bool_to_int.create(c.arena, lhs_uncasted) |
| 1404 | else lhs_uncasted; | 1344 | else |
| | 1345 | lhs_uncasted; |
| 1405 | | 1346 | |
| 1406 | const rhs = if (isBoolRes(rhs_uncasted)) | 1347 | const rhs = if (isBoolRes(rhs_uncasted)) |
| 1407 | try Node.bool_to_int.create(c.arena, rhs_uncasted) | 1348 | try Node.bool_to_int.create(c.arena, rhs_uncasted) |
| 1408 | else rhs_uncasted; | 1349 | else |
| | 1350 | rhs_uncasted; |
| 1409 | | 1351 | |
| 1410 | const payload = try c.arena.create(ast.Payload.BinOp); | 1352 | const payload = try c.arena.create(ast.Payload.BinOp); |
| 1411 | payload.* = .{ | 1353 | payload.* = .{ |
| ... | @@ -1415,7 +1357,7 @@ fn transBinaryOperator( | ... | @@ -1415,7 +1357,7 @@ fn transBinaryOperator( |
| 1415 | .rhs = rhs, | 1357 | .rhs = rhs, |
| 1416 | }, | 1358 | }, |
| 1417 | }; | 1359 | }; |
| 1418 | return maybeSuppressResult(c, scope, used, &payload.base); | 1360 | return maybeSuppressResult(c, scope, used, Node.initPayload(&payload.base)); |
| 1419 | } | 1361 | } |
| 1420 | | 1362 | |
| 1421 | fn transCompoundStmtInline( | 1363 | fn transCompoundStmtInline( |
| ... | @@ -1459,13 +1401,11 @@ fn transCStyleCastExprClass( | ... | @@ -1459,13 +1401,11 @@ fn transCStyleCastExprClass( |
| 1459 | } | 1401 | } |
| 1460 | | 1402 | |
| 1461 | fn transDeclStmtOne( | 1403 | fn transDeclStmtOne( |
| 1462 | rp: RestorePoint, | 1404 | c: *Context, |
| 1463 | scope: *Scope, | 1405 | scope: *Scope, |
| 1464 | decl: *const clang.Decl, | 1406 | decl: *const clang.Decl, |
| 1465 | block_scope: *Scope.Block, | 1407 | block_scope: *Scope.Block, |
| 1466 | ) TransError!*ast.Node { | 1408 | ) TransError!Node { |
| 1467 | const c = rp.c; | | |
| 1468 | | | |
| 1469 | switch (decl.getKind()) { | 1409 | switch (decl.getKind()) { |
| 1470 | .Var => { | 1410 | .Var => { |
| 1471 | const var_decl = @ptrCast(*const clang.VarDecl, decl); | 1411 | const var_decl = @ptrCast(*const clang.VarDecl, decl); |
| ... | @@ -1479,47 +1419,38 @@ fn transDeclStmtOne( | ... | @@ -1479,47 +1419,38 @@ fn transDeclStmtOne( |
| 1479 | .Extern, .Static => { | 1419 | .Extern, .Static => { |
| 1480 | // This is actually a global variable, put it in the global scope and reference it. | 1420 | // This is actually a global variable, put it in the global scope and reference it. |
| 1481 | // `_ = mangled_name;` | 1421 | // `_ = mangled_name;` |
| 1482 | try visitVarDecl(rp.c, var_decl, mangled_name); | 1422 | try visitVarDecl(c, var_decl, mangled_name); |
| 1483 | return try maybeSuppressResult(rp, scope, .unused, try transCreateNodeIdentifier(rp.c, mangled_name)); | 1423 | return try maybeSuppressResult(c, scope, .unused, try Node.identifier.create(c.arena, mangled_name)); |
| 1484 | }, | 1424 | }, |
| 1485 | else => {}, | 1425 | else => {}, |
| 1486 | } | 1426 | } |
| 1487 | | 1427 | |
| 1488 | const mut_tok = if (qual_type.isConstQualified()) | 1428 | const is_const = qual_type.isConstQualified(); |
| 1489 | try appendToken(c, .Keyword_const, "const") | | |
| 1490 | else | | |
| 1491 | try appendToken(c, .Keyword_var, "var"); | | |
| 1492 | const name_tok = try appendIdentifier(c, mangled_name); | | |
| 1493 | | 1429 | |
| 1494 | _ = try appendToken(c, .Colon, ":"); | | |
| 1495 | const loc = decl.getLocation(); | 1430 | const loc = decl.getLocation(); |
| 1496 | const type_node = try transQualTypeMaybeInitialized(rp, qual_type, decl_init, loc); | 1431 | const type_node = try transQualTypeMaybeInitialized(c, qual_type, decl_init, loc); |
| 1497 | | 1432 | |
| 1498 | const eq_token = try appendToken(c, .Equal, "="); | | |
| 1499 | var init_node = if (decl_init) |expr| | 1433 | var init_node = if (decl_init) |expr| |
| 1500 | if (expr.getStmtClass() == .StringLiteralClass) | 1434 | if (expr.getStmtClass() == .StringLiteralClass) |
| 1501 | try transStringLiteralAsArray(rp, scope, @ptrCast(*const clang.StringLiteral, expr), try zigArraySize(rp.c, type_node)) | 1435 | try transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), try zigArraySize(c, type_node)) |
| 1502 | else | 1436 | else |
| 1503 | try transExprCoercing(rp, scope, expr, .used, .r_value) | 1437 | try transExprCoercing(c, scope, expr, .used, .r_value) |
| 1504 | else | 1438 | else |
| 1505 | try transCreateNodeUndefinedLiteral(c); | 1439 | try transCreateNodeUndefinedLiteral(c); |
| 1506 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { | 1440 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| 1507 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); | 1441 | init_node = try Node.bool_to_int.create(c.arena, init_node); |
| 1508 | builtin_node.params()[0] = init_node; | | |
| 1509 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 1510 | init_node = &builtin_node.base; | | |
| 1511 | } | 1442 | } |
| 1512 | const semicolon_token = try appendToken(c, .Semicolon, ";"); | 1443 | return Node.var_decl.create(c.arena, .{ |
| 1513 | const node = try ast.Node.VarDecl.create(c.arena, .{ | 1444 | .is_pub = false, |
| 1514 | .name_token = name_tok, | 1445 | .is_const = is_const, |
| 1515 | .mut_token = mut_tok, | 1446 | .is_extern = false, |
| 1516 | .semicolon_token = semicolon_token, | 1447 | .is_export = false, |
| 1517 | }, .{ | 1448 | .linksection_string = null, |
| 1518 | .eq_token = eq_token, | 1449 | .alignment = null, |
| 1519 | .type_node = type_node, | 1450 | .name = mangled_name, |
| 1520 | .init_node = init_node, | 1451 | .type = type_node, |
| | 1452 | .init = init_node, |
| 1521 | }); | 1453 | }); |
| 1522 | return &node.base; | | |
| 1523 | }, | 1454 | }, |
| 1524 | .Typedef => { | 1455 | .Typedef => { |
| 1525 | const typedef_decl = @ptrCast(*const clang.TypedefNameDecl, decl); | 1456 | const typedef_decl = @ptrCast(*const clang.TypedefNameDecl, decl); |
| ... | @@ -1529,7 +1460,7 @@ fn transDeclStmtOne( | ... | @@ -1529,7 +1460,7 @@ fn transDeclStmtOne( |
| 1529 | const underlying_type = underlying_qual.getTypePtr(); | 1460 | const underlying_type = underlying_qual.getTypePtr(); |
| 1530 | | 1461 | |
| 1531 | const mangled_name = try block_scope.makeMangledName(c, name); | 1462 | const mangled_name = try block_scope.makeMangledName(c, name); |
| 1532 | const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse | 1463 | const node = (try transCreateNodeTypedef(c, typedef_decl, false, mangled_name)) orelse |
| 1533 | return error.UnsupportedTranslation; | 1464 | return error.UnsupportedTranslation; |
| 1534 | return node; | 1465 | return node; |
| 1535 | }, | 1466 | }, |
| ... | @@ -1543,14 +1474,14 @@ fn transDeclStmtOne( | ... | @@ -1543,14 +1474,14 @@ fn transDeclStmtOne( |
| 1543 | } | 1474 | } |
| 1544 | } | 1475 | } |
| 1545 | | 1476 | |
| 1546 | fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.DeclStmt) TransError!*ast.Node { | 1477 | fn transDeclStmt(c: *Context, scope: *Scope, stmt: *const clang.DeclStmt) TransError!Node { |
| 1547 | const block_scope = scope.findBlockScope(rp.c) catch unreachable; | 1478 | const block_scope = scope.findBlockScope(c) catch unreachable; |
| 1548 | | 1479 | |
| 1549 | var it = stmt.decl_begin(); | 1480 | var it = stmt.decl_begin(); |
| 1550 | const end_it = stmt.decl_end(); | 1481 | const end_it = stmt.decl_end(); |
| 1551 | assert(it != end_it); | 1482 | assert(it != end_it); |
| 1552 | while (true) : (it += 1) { | 1483 | while (true) : (it += 1) { |
| 1553 | const node = try transDeclStmtOne(rp, scope, it[0], block_scope); | 1484 | const node = try transDeclStmtOne(c, scope, it[0], block_scope); |
| 1554 | | 1485 | |
| 1555 | if (it + 1 == end_it) { | 1486 | if (it + 1 == end_it) { |
| 1556 | return node; | 1487 | return node; |
| ... | @@ -1562,15 +1493,15 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.DeclStmt) T | ... | @@ -1562,15 +1493,15 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.DeclStmt) T |
| 1562 | } | 1493 | } |
| 1563 | | 1494 | |
| 1564 | fn transDeclRefExpr( | 1495 | fn transDeclRefExpr( |
| 1565 | rp: RestorePoint, | 1496 | c: *Context, |
| 1566 | scope: *Scope, | 1497 | scope: *Scope, |
| 1567 | expr: *const clang.DeclRefExpr, | 1498 | expr: *const clang.DeclRefExpr, |
| 1568 | lrvalue: LRValue, | 1499 | lrvalue: LRValue, |
| 1569 | ) TransError!*ast.Node { | 1500 | ) TransError!Node { |
| 1570 | const value_decl = expr.getDecl(); | 1501 | const value_decl = expr.getDecl(); |
| 1571 | const name = try rp.c.str(@ptrCast(*const clang.NamedDecl, value_decl).getName_bytes_begin()); | 1502 | const name = try c.str(@ptrCast(*const clang.NamedDecl, value_decl).getName_bytes_begin()); |
| 1572 | const mangled_name = scope.getAlias(name); | 1503 | const mangled_name = scope.getAlias(name); |
| 1573 | return transCreateNodeIdentifier(rp.c, mangled_name); | 1504 | return Node.identifier.create(c.arena, mangled_name); |
| 1574 | } | 1505 | } |
| 1575 | | 1506 | |
| 1576 | fn transImplicitCastExpr( | 1507 | fn transImplicitCastExpr( |
| ... | @@ -1642,52 +1573,29 @@ fn transImplicitCastExpr( | ... | @@ -1642,52 +1573,29 @@ fn transImplicitCastExpr( |
| 1642 | } | 1573 | } |
| 1643 | | 1574 | |
| 1644 | fn transBoolExpr( | 1575 | fn transBoolExpr( |
| 1645 | rp: RestorePoint, | 1576 | c: *Context, |
| 1646 | scope: *Scope, | 1577 | scope: *Scope, |
| 1647 | expr: *const clang.Expr, | 1578 | expr: *const clang.Expr, |
| 1648 | used: ResultUsed, | 1579 | used: ResultUsed, |
| 1649 | lrvalue: LRValue, | 1580 | lrvalue: LRValue, |
| 1650 | grouped: bool, | 1581 | ) TransError!Node { |
| 1651 | ) TransError!*ast.Node { | | |
| 1652 | if (@ptrCast(*const clang.Stmt, expr).getStmtClass() == .IntegerLiteralClass) { | 1582 | if (@ptrCast(*const clang.Stmt, expr).getStmtClass() == .IntegerLiteralClass) { |
| 1653 | var is_zero: bool = undefined; | 1583 | var is_zero: bool = undefined; |
| 1654 | if (!(@ptrCast(*const clang.IntegerLiteral, expr).isZero(&is_zero, rp.c.clang_context))) { | 1584 | if (!(@ptrCast(*const clang.IntegerLiteral, expr).isZero(&is_zero, c.clang_context))) { |
| 1655 | return revertAndWarn(rp, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid integer literal", .{}); | 1585 | return revertAndWarn(c, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid integer literal", .{}); |
| 1656 | } | 1586 | } |
| 1657 | return try transCreateNodeBoolLiteral(rp.c, !is_zero); | 1587 | return Node{ .tag = ([2]ast.Node.Tag{ .true_literal, .false_literal })[is_zero] }; |
| 1658 | } | 1588 | } |
| 1659 | | 1589 | |
| 1660 | const lparen = if (grouped) | 1590 | var res = try transExpr(c, scope, expr, used, lrvalue); |
| 1661 | try appendToken(rp.c, .LParen, "(") | | |
| 1662 | else | | |
| 1663 | undefined; | | |
| 1664 | var res = try transExpr(rp, scope, expr, used, lrvalue); | | |
| 1665 | | | |
| 1666 | if (isBoolRes(res)) { | 1591 | if (isBoolRes(res)) { |
| 1667 | if (!grouped and res.tag == .GroupedExpression) { | | |
| 1668 | const group = @fieldParentPtr(ast.Node.GroupedExpression, "base", res); | | |
| 1669 | res = group.expr; | | |
| 1670 | // get zig fmt to work properly | | |
| 1671 | tokenSlice(rp.c, group.lparen)[0] = ')'; | | |
| 1672 | } | | |
| 1673 | return res; | 1592 | return res; |
| 1674 | } | 1593 | } |
| 1675 | | 1594 | |
| 1676 | const ty = getExprQualType(rp.c, expr).getTypePtr(); | 1595 | const ty = getExprQualType(c, expr).getTypePtr(); |
| 1677 | const node = try finishBoolExpr(rp, scope, expr.getBeginLoc(), ty, res, used); | 1596 | const node = try finishBoolExpr(c, scope, expr.getBeginLoc(), ty, res, used); |
| 1678 | | 1597 | |
| 1679 | if (grouped) { | 1598 | return maybeSuppressResult(c, scope, used, node); |
| 1680 | const rparen = try appendToken(rp.c, .RParen, ")"); | | |
| 1681 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | | |
| 1682 | grouped_expr.* = .{ | | |
| 1683 | .lparen = lparen, | | |
| 1684 | .expr = node, | | |
| 1685 | .rparen = rparen, | | |
| 1686 | }; | | |
| 1687 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); | | |
| 1688 | } else { | | |
| 1689 | return maybeSuppressResult(rp, scope, used, node); | | |
| 1690 | } | | |
| 1691 | } | 1599 | } |
| 1692 | | 1600 | |
| 1693 | fn exprIsBooleanType(expr: *const clang.Expr) bool { | 1601 | fn exprIsBooleanType(expr: *const clang.Expr) bool { |
| ... | @@ -1713,34 +1621,32 @@ fn exprIsNarrowStringLiteral(expr: *const clang.Expr) bool { | ... | @@ -1713,34 +1621,32 @@ fn exprIsNarrowStringLiteral(expr: *const clang.Expr) bool { |
| 1713 | } | 1621 | } |
| 1714 | } | 1622 | } |
| 1715 | | 1623 | |
| 1716 | fn isBoolRes(res: *ast.Node) bool { | 1624 | fn isBoolRes(res: Node) bool { |
| 1717 | switch (res.tag) { | 1625 | switch (res.tag()) { |
| 1718 | .BoolOr, | 1626 | .@"or", |
| 1719 | .BoolAnd, | 1627 | .@"and", |
| 1720 | .EqualEqual, | 1628 | .equal, |
| 1721 | .BangEqual, | 1629 | .note_equal, |
| 1722 | .LessThan, | 1630 | .less_than, |
| 1723 | .GreaterThan, | 1631 | .less_than_equal, |
| 1724 | .LessOrEqual, | 1632 | .greater_than, |
| 1725 | .GreaterOrEqual, | 1633 | .greater_than_equal, |
| 1726 | .BoolNot, | 1634 | .not, |
| 1727 | .BoolLiteral, | 1635 | .false_literal, |
| | 1636 | .true_literal, |
| 1728 | => return true, | 1637 | => return true, |
| 1729 | | | |
| 1730 | .GroupedExpression => return isBoolRes(@fieldParentPtr(ast.Node.GroupedExpression, "base", res).expr), | | |
| 1731 | | | |
| 1732 | else => return false, | 1638 | else => return false, |
| 1733 | } | 1639 | } |
| 1734 | } | 1640 | } |
| 1735 | | 1641 | |
| 1736 | fn finishBoolExpr( | 1642 | fn finishBoolExpr( |
| 1737 | rp: RestorePoint, | 1643 | c: *Context, |
| 1738 | scope: *Scope, | 1644 | scope: *Scope, |
| 1739 | loc: clang.SourceLocation, | 1645 | loc: clang.SourceLocation, |
| 1740 | ty: *const clang.Type, | 1646 | ty: *const clang.Type, |
| 1741 | node: *ast.Node, | 1647 | node: Node, |
| 1742 | used: ResultUsed, | 1648 | used: ResultUsed, |
| 1743 | ) TransError!*ast.Node { | 1649 | ) TransError!Node { |
| 1744 | switch (ty.getTypeClass()) { | 1650 | switch (ty.getTypeClass()) { |
| 1745 | .Builtin => { | 1651 | .Builtin => { |
| 1746 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); | 1652 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| ... | @@ -1772,42 +1678,39 @@ fn finishBoolExpr( | ... | @@ -1772,42 +1678,39 @@ fn finishBoolExpr( |
| 1772 | .WChar_S, | 1678 | .WChar_S, |
| 1773 | .Float16, | 1679 | .Float16, |
| 1774 | => { | 1680 | => { |
| 1775 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1681 | // node != 0 |
| 1776 | const rhs_node = try transCreateNodeInt(rp.c, 0); | 1682 | return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init()}); |
| 1777 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false); | | |
| 1778 | }, | 1683 | }, |
| 1779 | .NullPtr => { | 1684 | .NullPtr => { |
| 1780 | const op_token = try appendToken(rp.c, .EqualEqual, "=="); | 1685 | // node == null |
| 1781 | const rhs_node = try transCreateNodeNullLiteral(rp.c); | 1686 | return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init()}); |
| 1782 | return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, false); | | |
| 1783 | }, | 1687 | }, |
| 1784 | else => {}, | 1688 | else => {}, |
| 1785 | } | 1689 | } |
| 1786 | }, | 1690 | }, |
| 1787 | .Pointer => { | 1691 | .Pointer => { |
| 1788 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1692 | // node == null |
| 1789 | const rhs_node = try transCreateNodeNullLiteral(rp.c); | 1693 | return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init()}); |
| 1790 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false); | | |
| 1791 | }, | 1694 | }, |
| 1792 | .Typedef => { | 1695 | .Typedef => { |
| 1793 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); | 1696 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| 1794 | const typedef_decl = typedef_ty.getDecl(); | 1697 | const typedef_decl = typedef_ty.getDecl(); |
| 1795 | const underlying_type = typedef_decl.getUnderlyingType(); | 1698 | const underlying_type = typedef_decl.getUnderlyingType(); |
| 1796 | return finishBoolExpr(rp, scope, loc, underlying_type.getTypePtr(), node, used); | 1699 | return finishBoolExpr(c, scope, loc, underlying_type.getTypePtr(), node, used); |
| 1797 | }, | 1700 | }, |
| 1798 | .Enum => { | 1701 | .Enum => { |
| 1799 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1702 | // node != 0 |
| 1800 | const rhs_node = try transCreateNodeInt(rp.c, 0); | 1703 | return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init()}); |
| 1801 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false); | 1704 | const op_token = try appendToken(c, .BangEqual, "!="); |
| 1802 | }, | 1705 | }, |
| 1803 | .Elaborated => { | 1706 | .Elaborated => { |
| 1804 | const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); | 1707 | const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); |
| 1805 | const named_type = elaborated_ty.getNamedType(); | 1708 | const named_type = elaborated_ty.getNamedType(); |
| 1806 | return finishBoolExpr(rp, scope, loc, named_type.getTypePtr(), node, used); | 1709 | return finishBoolExpr(c, scope, loc, named_type.getTypePtr(), node, used); |
| 1807 | }, | 1710 | }, |
| 1808 | else => {}, | 1711 | else => {}, |
| 1809 | } | 1712 | } |
| 1810 | return revertAndWarn(rp, error.UnsupportedType, loc, "unsupported bool expression type", .{}); | 1713 | return fail(c, error.UnsupportedType, loc, "unsupported bool expression type", .{}); |
| 1811 | } | 1714 | } |
| 1812 | | 1715 | |
| 1813 | const SuppressCast = enum { | 1716 | const SuppressCast = enum { |
| ... | @@ -4242,7 +4145,7 @@ fn transCreateNodeBoolInfixOp( | ... | @@ -4242,7 +4145,7 @@ fn transCreateNodeBoolInfixOp( |
| 4242 | .rhs = rhs, | 4145 | .rhs = rhs, |
| 4243 | }, | 4146 | }, |
| 4244 | }; | 4147 | }; |
| 4245 | return maybeSuppressResult(c, scope, used, &payload.base); | 4148 | return maybeSuppressResult(c, scope, used, Node.initPayload(&payload.base)); |
| 4246 | } | 4149 | } |
| 4247 | | 4150 | |
| 4248 | fn transCreateNodePtrType( | 4151 | fn transCreateNodePtrType( |
| ... | @@ -4654,7 +4557,7 @@ fn transCreateNodeShiftOp( | ... | @@ -4654,7 +4557,7 @@ fn transCreateNodeShiftOp( |
| 4654 | const lhs = try transExpr(c, scope, lhs_expr, .used, .l_value); | 4557 | const lhs = try transExpr(c, scope, lhs_expr, .used, .l_value); |
| 4655 | | 4558 | |
| 4656 | const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location); | 4559 | const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location); |
| 4657 | const rhs = try transExpr(c, scope, rhs_expr, .used, .r_value); | 4560 | const rhs = try transExprCoercing(c, scope, rhs_expr, .used, .r_value); |
| 4658 | const rhs_casted = try Node.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type }); | 4561 | const rhs_casted = try Node.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type }); |
| 4659 | | 4562 | |
| 4660 | const payload = try c.arena.create(ast.Payload.BinOp); | 4563 | const payload = try c.arena.create(ast.Payload.BinOp); |
| ... | @@ -4663,9 +4566,9 @@ fn transCreateNodeShiftOp( | ... | @@ -4663,9 +4566,9 @@ fn transCreateNodeShiftOp( |
| 4663 | .data = .{ | 4566 | .data = .{ |
| 4664 | .lhs = lhs, | 4567 | .lhs = lhs, |
| 4665 | .rhs = rhs_casted, | 4568 | .rhs = rhs_casted, |
| 4666 | } | 4569 | }, |
| 4667 | }; | 4570 | }; |
| 4668 | return &payload.base; | 4571 | return Node.initPayload(&payload.base); |
| 4669 | } | 4572 | } |
| 4670 | | 4573 | |
| 4671 | fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node { | 4574 | fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node { |
| ... | @@ -4961,7 +4864,7 @@ fn finishTransFnProto( | ... | @@ -4961,7 +4864,7 @@ fn finishTransFnProto( |
| 4961 | }; | 4864 | }; |
| 4962 | } | 4865 | } |
| 4963 | | 4866 | |
| 4964 | const link_section_string: ?[]const u8 = blk: { | 4867 | const linksection_string = blk: { |
| 4965 | if (fn_decl) |decl| { | 4868 | if (fn_decl) |decl| { |
| 4966 | var str_len: usize = undefined; | 4869 | var str_len: usize = undefined; |
| 4967 | if (decl.getSectionAttribute(&str_len)) |str_ptr| { | 4870 | if (decl.getSectionAttribute(&str_len)) |str_ptr| { |
| ... | @@ -5004,24 +4907,19 @@ fn finishTransFnProto( | ... | @@ -5004,24 +4907,19 @@ fn finishTransFnProto( |
| 5004 | } | 4907 | } |
| 5005 | }; | 4908 | }; |
| 5006 | | 4909 | |
| 5007 | const fn_proto = try c.arena.create(ast.Payload.Func); | 4910 | return Node.func.create(c.arena, .{ |
| 5008 | fn_proto.* = .{ | 4911 | .is_pub = is_pub, |
| 5009 | .base = .{ .tag = .func }, | 4912 | .is_extern = is_extern, |
| 5010 | .data = .{ | 4913 | .is_export = is_export, |
| 5011 | .is_pub = is_pub, | 4914 | .is_var_args = is_var_args, |
| 5012 | .is_extern = is_extern, | 4915 | .name = name, |
| 5013 | .is_export = is_export, | 4916 | .linksection_string = linksection_string, |
| 5014 | .is_var_args = is_var_args, | 4917 | .explicit_callconv = explicit_callconv, |
| 5015 | .name = name, | 4918 | .params = try c.arena.dupe(ast.Payload.Func.Param, fn_params.items), |
| 5016 | .link_section_string = link_section_string, | 4919 | .return_type = return_node, |
| 5017 | .explicit_callconv = explicit_callconv, | 4920 | .body = null, |
| 5018 | .params = c.arena.dupe(ast.Payload.Func.Param, fn_params.items), | 4921 | .alignment = alignment, |
| 5019 | .return_type = return_node, | 4922 | }); |
| 5020 | .body = null, | | |
| 5021 | .alignment = alignment, | | |
| 5022 | }, | | |
| 5023 | }; | | |
| 5024 | return fn_proto; | | |
| 5025 | } | 4923 | } |
| 5026 | | 4924 | |
| 5027 | fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { | 4925 | fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { |
| ... | @@ -5054,6 +4952,19 @@ pub fn freeErrors(errors: []ClangErrMsg) void { | ... | @@ -5054,6 +4952,19 @@ pub fn freeErrors(errors: []ClangErrMsg) void { |
| 5054 | errors.ptr.delete(errors.len); | 4952 | errors.ptr.delete(errors.len); |
| 5055 | } | 4953 | } |
| 5056 | | 4954 | |
| | 4955 | fn isZigPrimitiveType(name: []const u8) bool { |
| | 4956 | if (name.len > 1 and (name[0] == 'u' or name[0] == 'i')) { |
| | 4957 | for (name[1..]) |c| { |
| | 4958 | switch (c) { |
| | 4959 | '0'...'9' => {}, |
| | 4960 | else => return false, |
| | 4961 | } |
| | 4962 | } |
| | 4963 | return true; |
| | 4964 | } |
| | 4965 | return @import("astgen.zig").simple_types.has(name); |
| | 4966 | } |
| | 4967 | |
| 5057 | const MacroCtx = struct { | 4968 | const MacroCtx = struct { |
| 5058 | source: []const u8, | 4969 | source: []const u8, |
| 5059 | list: []const CToken, | 4970 | list: []const CToken, |