| ... | @@ -783,7 +783,7 @@ fn transCreateNodeTypedef( | ... | @@ -783,7 +783,7 @@ fn transCreateNodeTypedef( |
| 783 | | 783 | |
| 784 | const payload = try c.arena.create(ast.Payload.Typedef); | 784 | const payload = try c.arena.create(ast.Payload.Typedef); |
| 785 | payload.* = .{ | 785 | payload.* = .{ |
| 786 | .base = .{ .tag = ([2]ast.Node.Tag{ .typedef, .pub_typedef })[toplevel] }, | 786 | .base = .{ .tag = ([2]ast.Node.Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] }, |
| 787 | .data = .{ | 787 | .data = .{ |
| 788 | .name = checked_name, | 788 | .name = checked_name, |
| 789 | .init = init_node, | 789 | .init = init_node, |
| ... | @@ -792,7 +792,7 @@ fn transCreateNodeTypedef( | ... | @@ -792,7 +792,7 @@ fn transCreateNodeTypedef( |
| 792 | return Node.initPayload(&payload.base); | 792 | return Node.initPayload(&payload.base); |
| 793 | } | 793 | } |
| 794 | | 794 | |
| 795 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*ast.Node { | 795 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Node { |
| 796 | if (c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl()))) |name| | 796 | if (c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl()))) |name| |
| 797 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 797 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice |
| 798 | const record_loc = record_decl.getLocation(); | 798 | const record_loc = record_decl.getLocation(); |
| ... | @@ -807,46 +807,30 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as | ... | @@ -807,46 +807,30 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as |
| 807 | } | 807 | } |
| 808 | | 808 | |
| 809 | var container_kind_name: []const u8 = undefined; | 809 | var container_kind_name: []const u8 = undefined; |
| 810 | var container_kind: std.zig.Token.Id = undefined; | 810 | var is_union = false; |
| 811 | if (record_decl.isUnion()) { | 811 | if (record_decl.isUnion()) { |
| 812 | container_kind_name = "union"; | 812 | container_kind_name = "union"; |
| 813 | container_kind = .Keyword_union; | 813 | is_union = true; |
| 814 | } else if (record_decl.isStruct()) { | 814 | } else if (record_decl.isStruct()) { |
| 815 | container_kind_name = "struct"; | 815 | container_kind_name = "struct"; |
| 816 | container_kind = .Keyword_struct; | | |
| 817 | } else { | 816 | } else { |
| 818 | try emitWarning(c, record_loc, "record {s} is not a struct or union", .{bare_name}); | 817 | try warn(c, record_loc, "record {s} is not a struct or union", .{bare_name}); |
| 819 | return null; | 818 | return null; |
| 820 | } | 819 | } |
| 821 | | 820 | |
| 822 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_kind_name, bare_name }); | 821 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_kind_name, bare_name }); |
| 823 | _ = try c.decl_table.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), name); | 822 | _ = try c.decl_table.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), name); |
| 824 | | 823 | |
| 825 | const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null; | 824 | const is_pub = !is_unnamed; |
| 826 | const mut_tok = try appendToken(c, .Keyword_const, "const"); | | |
| 827 | const name_tok = try appendIdentifier(c, name); | | |
| 828 | | | |
| 829 | const eq_token = try appendToken(c, .Equal, "="); | | |
| 830 | | | |
| 831 | var semicolon: ast.TokenIndex = undefined; | | |
| 832 | const init_node = blk: { | 825 | const init_node = blk: { |
| 833 | const rp = makeRestorePoint(c); | | |
| 834 | const record_def = record_decl.getDefinition() orelse { | 826 | const record_def = record_decl.getDefinition() orelse { |
| 835 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 827 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 836 | const opaque_type = try transCreateNodeOpaqueType(c); | 828 | break :blk Node.opaque_literal.init(); |
| 837 | semicolon = try appendToken(c, .Semicolon, ";"); | | |
| 838 | break :blk opaque_type; | | |
| 839 | }; | 829 | }; |
| 840 | | 830 | |
| 841 | const layout_tok = try if (record_decl.getPackedAttribute()) | 831 | const is_packed = record_decl.getPackedAttribute(); |
| 842 | appendToken(c, .Keyword_packed, "packed") | 832 | var fields = std.ArrayList(ast.Payload.Record.Field).init(c.gpa); |
| 843 | else | 833 | defer fields.deinit(); |
| 844 | appendToken(c, .Keyword_extern, "extern"); | | |
| 845 | const container_tok = try appendToken(c, container_kind, container_kind_name); | | |
| 846 | const lbrace_token = try appendToken(c, .LBrace, "{"); | | |
| 847 | | | |
| 848 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); | | |
| 849 | defer fields_and_decls.deinit(); | | |
| 850 | | 834 | |
| 851 | var unnamed_field_count: u32 = 0; | 835 | var unnamed_field_count: u32 = 0; |
| 852 | var it = record_def.field_begin(); | 836 | var it = record_def.field_begin(); |
| ... | @@ -858,110 +842,82 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as | ... | @@ -858,110 +842,82 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as |
| 858 | | 842 | |
| 859 | if (field_decl.isBitField()) { | 843 | if (field_decl.isBitField()) { |
| 860 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 844 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 861 | const opaque_type = try transCreateNodeOpaqueType(c); | 845 | try warn(c, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name}); |
| 862 | semicolon = try appendToken(c, .Semicolon, ";"); | 846 | break :blk Node.opaque_literal.init(); |
| 863 | try emitWarning(c, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name}); | | |
| 864 | break :blk opaque_type; | | |
| 865 | } | 847 | } |
| 866 | | 848 | |
| 867 | if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) { | 849 | if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) { |
| 868 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 850 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 869 | const opaque_type = try transCreateNodeOpaqueType(c); | 851 | try warn(c, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name}); |
| 870 | semicolon = try appendToken(c, .Semicolon, ";"); | 852 | break :blk Node.opaque_literal.init(); |
| 871 | try emitWarning(c, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name}); | | |
| 872 | break :blk opaque_type; | | |
| 873 | } | 853 | } |
| 874 | | 854 | |
| 875 | var is_anon = false; | 855 | var is_anon = false; |
| 876 | var raw_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin()); | 856 | var field_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin()); |
| 877 | if (field_decl.isAnonymousStructOrUnion() or raw_name.len == 0) { | 857 | if (field_decl.isAnonymousStructOrUnion() or field_name.len == 0) { |
| 878 | // Context.getMangle() is not used here because doing so causes unpredictable field names for anonymous fields. | 858 | // Context.getMangle() is not used here because doing so causes unpredictable field names for anonymous fields. |
| 879 | raw_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{unnamed_field_count}); | 859 | field_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{unnamed_field_count}); |
| 880 | unnamed_field_count += 1; | 860 | unnamed_field_count += 1; |
| 881 | is_anon = true; | 861 | is_anon = true; |
| 882 | } | 862 | } |
| 883 | const field_name = try appendIdentifier(c, raw_name); | 863 | const field_type = transQualType(c, field_qt, field_loc) catch |err| switch (err) { |
| 884 | _ = try appendToken(c, .Colon, ":"); | | |
| 885 | const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) { | | |
| 886 | error.UnsupportedType => { | 864 | error.UnsupportedType => { |
| 887 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 865 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 888 | const opaque_type = try transCreateNodeOpaqueType(c); | 866 | try warn(c, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, raw_name }); |
| 889 | semicolon = try appendToken(c, .Semicolon, ";"); | 867 | break :blk Node.opaque_literal.init(); |
| 890 | try emitWarning(c, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, raw_name }); | | |
| 891 | break :blk opaque_type; | | |
| 892 | }, | 868 | }, |
| 893 | else => |e| return e, | 869 | else => |e| return e, |
| 894 | }; | 870 | }; |
| 895 | | 871 | |
| 896 | const align_expr = blk_2: { | 872 | const alignment = blk_2: { |
| 897 | const alignment = field_decl.getAlignedAttribute(c.clang_context); | 873 | const alignment = field_decl.getAlignedAttribute(c.clang_context); |
| 898 | if (alignment != 0) { | 874 | if (alignment != 0) { |
| 899 | _ = try appendToken(c, .Keyword_align, "align"); | | |
| 900 | _ = try appendToken(c, .LParen, "("); | | |
| 901 | // Clang reports the alignment in bits | 875 | // Clang reports the alignment in bits |
| 902 | const expr = try transCreateNodeInt(c, alignment / 8); | 876 | break :blk_2 alignment / 8; |
| 903 | _ = try appendToken(c, .RParen, ")"); | | |
| 904 | | | |
| 905 | break :blk_2 expr; | | |
| 906 | } | 877 | } |
| 907 | break :blk_2 null; | 878 | break :blk_2 null; |
| 908 | }; | 879 | }; |
| 909 | | 880 | |
| 910 | const field_node = try c.arena.create(ast.Node.ContainerField); | | |
| 911 | field_node.* = .{ | | |
| 912 | .doc_comments = null, | | |
| 913 | .comptime_token = null, | | |
| 914 | .name_token = field_name, | | |
| 915 | .type_expr = field_type, | | |
| 916 | .value_expr = null, | | |
| 917 | .align_expr = align_expr, | | |
| 918 | }; | | |
| 919 | | | |
| 920 | if (is_anon) { | 881 | if (is_anon) { |
| 921 | _ = try c.decl_table.put( | 882 | _ = try c.decl_table.put(c.gpa, @ptrToInt(field_decl.getCanonicalDecl()), field_name); |
| 922 | c.gpa, | | |
| 923 | @ptrToInt(field_decl.getCanonicalDecl()), | | |
| 924 | raw_name, | | |
| 925 | ); | | |
| 926 | } | 883 | } |
| 927 | | 884 | |
| 928 | try fields_and_decls.append(&field_node.base); | 885 | try fields.append(.{ |
| 929 | _ = try appendToken(c, .Comma, ","); | 886 | .name = field_name, |
| | 887 | .type = field_type, |
| | 888 | .alignment = alignment, |
| | 889 | }); |
| 930 | } | 890 | } |
| 931 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, fields_and_decls.items.len); | 891 | |
| | 892 | const payload = try c.arena.create(ast.Payload.Record); |
| 932 | container_node.* = .{ | 893 | container_node.* = .{ |
| 933 | .layout_token = layout_tok, | 894 | .base = .{ .tag = ([2]ast.Node.Tag{ .@"struct", .@"union" })[@boolToInt(is_union)] }, |
| 934 | .kind_token = container_tok, | 895 | .data = .{ |
| 935 | .init_arg_expr = .None, | 896 | .is_packed = is_packed, |
| 936 | .fields_and_decls_len = fields_and_decls.items.len, | 897 | .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items), |
| 937 | .lbrace_token = lbrace_token, | 898 | }, |
| 938 | .rbrace_token = try appendToken(c, .RBrace, "}"), | | |
| 939 | }; | 899 | }; |
| 940 | mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items); | 900 | break :blk Node.initPayload(&container_node.base); |
| 941 | semicolon = try appendToken(c, .Semicolon, ";"); | | |
| 942 | break :blk &container_node.base; | | |
| 943 | }; | 901 | }; |
| 944 | | 902 | |
| 945 | const node = try ast.Node.VarDecl.create(c.arena, .{ | 903 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); |
| 946 | .name_token = name_tok, | 904 | payload.* = .{ |
| 947 | .mut_token = mut_tok, | 905 | .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, |
| 948 | .semicolon_token = semicolon, | 906 | .data = .{ |
| 949 | }, .{ | 907 | .name = name, |
| 950 | .visib_token = visib_tok, | 908 | .init = init_node, |
| 951 | .eq_token = eq_token, | 909 | }, |
| 952 | .init_node = init_node, | 910 | }; |
| 953 | }); | | |
| 954 | | 911 | |
| 955 | try addTopLevelDecl(c, name, &node.base); | 912 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); |
| 956 | if (!is_unnamed) | 913 | if (!is_unnamed) |
| 957 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); | 914 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); |
| 958 | return transCreateNodeIdentifier(c, name); | 915 | return Node.identifier.create(c.arena, name); |
| 959 | } | 916 | } |
| 960 | | 917 | |
| 961 | fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node { | 918 | fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { |
| 962 | if (c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl()))) |name| | 919 | if (c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl()))) |name| |
| 963 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 920 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice |
| 964 | const rp = makeRestorePoint(c); | | |
| 965 | const enum_loc = enum_decl.getLocation(); | 921 | const enum_loc = enum_decl.getLocation(); |
| 966 | | 922 | |
| 967 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_decl).getName_bytes_begin()); | 923 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_decl).getName_bytes_begin()); |
| ... | @@ -974,10 +930,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node | ... | @@ -974,10 +930,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node |
| 974 | const name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name}); | 930 | const name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name}); |
| 975 | _ = try c.decl_table.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name); | 931 | _ = try c.decl_table.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name); |
| 976 | | 932 | |
| 977 | const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null; | 933 | const is_pub = !is_unnamed; |
| 978 | const mut_tok = try appendToken(c, .Keyword_const, "const"); | | |
| 979 | const name_tok = try appendIdentifier(c, name); | | |
| 980 | const eq_token = try appendToken(c, .Equal, "="); | | |
| 981 | | 934 | |
| 982 | const init_node = if (enum_decl.getDefinition()) |enum_def| blk: { | 935 | const init_node = if (enum_decl.getDefinition()) |enum_def| blk: { |
| 983 | var pure_enum = true; | 936 | var pure_enum = true; |
| ... | @@ -991,11 +944,8 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node | ... | @@ -991,11 +944,8 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node |
| 991 | } | 944 | } |
| 992 | } | 945 | } |
| 993 | | 946 | |
| 994 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); | 947 | var fields = std.ArrayList(ast.Payload.Enum.Field).init(c.gpa); |
| 995 | const container_tok = try appendToken(c, .Keyword_enum, "enum"); | 948 | defer fields.deinit(); |
| 996 | | | |
| 997 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); | | |
| 998 | defer fields_and_decls.deinit(); | | |
| 999 | | 949 | |
| 1000 | const int_type = enum_decl.getIntegerType(); | 950 | const int_type = enum_decl.getIntegerType(); |
| 1001 | // The underlying type may be null in case of forward-declared enum | 951 | // The underlying type may be null in case of forward-declared enum |
| ... | @@ -1003,30 +953,23 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node | ... | @@ -1003,30 +953,23 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node |
| 1003 | // default to the usual integer type used for all the enums. | 953 | // default to the usual integer type used for all the enums. |
| 1004 | | 954 | |
| 1005 | // default to c_int since msvc and gcc default to different types | 955 | // default to c_int since msvc and gcc default to different types |
| 1006 | _ = try appendToken(c, .LParen, "("); | 956 | const init_arg_expr = if (int_type.ptr != null and |
| 1007 | const init_arg_expr = ast.Node.ContainerDecl.InitArg{ | 957 | !isCBuiltinType(int_type, .UInt) and |
| 1008 | .Type = if (int_type.ptr != null and | 958 | !isCBuiltinType(int_type, .Int)) |
| 1009 | !isCBuiltinType(int_type, .UInt) and | 959 | transQualType(c, int_type, enum_loc) catch |err| switch (err) { |
| 1010 | !isCBuiltinType(int_type, .Int)) | 960 | error.UnsupportedType => { |
| 1011 | transQualType(rp, int_type, enum_loc) catch |err| switch (err) { | 961 | try failDecl(c, enum_loc, name, "unable to translate enum tag type", .{}); |
| 1012 | error.UnsupportedType => { | 962 | return null; |
| 1013 | try failDecl(c, enum_loc, name, "unable to translate enum tag type", .{}); | 963 | }, |
| 1014 | return null; | 964 | else => |e| return e, |
| 1015 | }, | 965 | } |
| 1016 | else => |e| return e, | 966 | else |
| 1017 | } | 967 | try Node.type.create(c.arena, "c_int"); |
| 1018 | else | | |
| 1019 | try transCreateNodeIdentifier(c, "c_int"), | | |
| 1020 | }; | | |
| 1021 | _ = try appendToken(c, .RParen, ")"); | | |
| 1022 | | | |
| 1023 | const lbrace_token = try appendToken(c, .LBrace, "{"); | | |
| 1024 | | 968 | |
| 1025 | it = enum_def.enumerator_begin(); | 969 | it = enum_def.enumerator_begin(); |
| 1026 | end_it = enum_def.enumerator_end(); | 970 | end_it = enum_def.enumerator_end(); |
| 1027 | while (it.neq(end_it)) : (it = it.next()) { | 971 | while (it.neq(end_it)) : (it = it.next()) { |
| 1028 | const enum_const = it.deref(); | 972 | const enum_const = it.deref(); |
| 1029 | | | |
| 1030 | const enum_val_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_const).getName_bytes_begin()); | 973 | const enum_val_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_const).getName_bytes_begin()); |
| 1031 | | 974 | |
| 1032 | const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name)) | 975 | const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name)) |
| ... | @@ -1034,100 +977,41 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node | ... | @@ -1034,100 +977,41 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node |
| 1034 | else | 977 | else |
| 1035 | enum_val_name; | 978 | enum_val_name; |
| 1036 | | 979 | |
| 1037 | const field_name_tok = try appendIdentifier(c, field_name); | 980 | const int_node = if (!pure_enum) |
| 1038 | | 981 | try transCreateNodeAPInt(c, enum_const.getInitVal()) |
| 1039 | const int_node = if (!pure_enum) blk_2: { | 982 | else |
| 1040 | _ = try appendToken(c, .Colon, "="); | | |
| 1041 | break :blk_2 try transCreateNodeAPInt(c, enum_const.getInitVal()); | | |
| 1042 | } else | | |
| 1043 | null; | 983 | null; |
| 1044 | | 984 | |
| 1045 | const field_node = try c.arena.create(ast.Node.ContainerField); | 985 | try fields_and_decls.append(.{ |
| 1046 | field_node.* = .{ | 986 | .name = field_name, |
| 1047 | .doc_comments = null, | 987 | .value = int_node, |
| 1048 | .comptime_token = null, | 988 | }); |
| 1049 | .name_token = field_name_tok, | | |
| 1050 | .type_expr = null, | | |
| 1051 | .value_expr = int_node, | | |
| 1052 | .align_expr = null, | | |
| 1053 | }; | | |
| 1054 | | | |
| 1055 | try fields_and_decls.append(&field_node.base); | | |
| 1056 | _ = try appendToken(c, .Comma, ","); | | |
| 1057 | | 989 | |
| 1058 | // In C each enum value is in the global namespace. So we put them there too. | 990 | // In C each enum value is in the global namespace. So we put them there too. |
| 1059 | // At this point we can rely on the enum emitting successfully. | 991 | // At this point we can rely on the enum emitting successfully. |
| 1060 | const tld_visib_tok = try appendToken(c, .Keyword_pub, "pub"); | 992 | try addTopLevelDecl(c, field_name, try Node.enum_redecl.create(c.arena, .{ |
| 1061 | const tld_mut_tok = try appendToken(c, .Keyword_const, "const"); | 993 | .enum_val_name = enum_val_name, |
| 1062 | const tld_name_tok = try appendIdentifier(c, enum_val_name); | 994 | .field_name = field_name, |
| 1063 | const tld_eq_token = try appendToken(c, .Equal, "="); | 995 | .enum_name = name, |
| 1064 | const cast_node = try rp.c.createBuiltinCall("@enumToInt", 1); | 996 | })); |
| 1065 | const enum_ident = try transCreateNodeIdentifier(c, name); | | |
| 1066 | const period_tok = try appendToken(c, .Period, "."); | | |
| 1067 | const field_ident = try transCreateNodeIdentifier(c, field_name); | | |
| 1068 | const field_access_node = try c.arena.create(ast.Node.SimpleInfixOp); | | |
| 1069 | field_access_node.* = .{ | | |
| 1070 | .base = .{ .tag = .Period }, | | |
| 1071 | .op_token = period_tok, | | |
| 1072 | .lhs = enum_ident, | | |
| 1073 | .rhs = field_ident, | | |
| 1074 | }; | | |
| 1075 | cast_node.params()[0] = &field_access_node.base; | | |
| 1076 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | | |
| 1077 | const tld_init_node = &cast_node.base; | | |
| 1078 | const tld_semicolon_token = try appendToken(c, .Semicolon, ";"); | | |
| 1079 | const tld_node = try ast.Node.VarDecl.create(c.arena, .{ | | |
| 1080 | .name_token = tld_name_tok, | | |
| 1081 | .mut_token = tld_mut_tok, | | |
| 1082 | .semicolon_token = tld_semicolon_token, | | |
| 1083 | }, .{ | | |
| 1084 | .visib_token = tld_visib_tok, | | |
| 1085 | .eq_token = tld_eq_token, | | |
| 1086 | .init_node = tld_init_node, | | |
| 1087 | }); | | |
| 1088 | try addTopLevelDecl(c, field_name, &tld_node.base); | | |
| 1089 | } | 997 | } |
| 1090 | // make non exhaustive | | |
| 1091 | const field_node = try c.arena.create(ast.Node.ContainerField); | | |
| 1092 | field_node.* = .{ | | |
| 1093 | .doc_comments = null, | | |
| 1094 | .comptime_token = null, | | |
| 1095 | .name_token = try appendIdentifier(c, "_"), | | |
| 1096 | .type_expr = null, | | |
| 1097 | .value_expr = null, | | |
| 1098 | .align_expr = null, | | |
| 1099 | }; | | |
| 1100 | | 998 | |
| 1101 | try fields_and_decls.append(&field_node.base); | 999 | break :blk try Node.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items)); |
| 1102 | _ = try appendToken(c, .Comma, ","); | | |
| 1103 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, fields_and_decls.items.len); | | |
| 1104 | container_node.* = .{ | | |
| 1105 | .layout_token = extern_tok, | | |
| 1106 | .kind_token = container_tok, | | |
| 1107 | .init_arg_expr = init_arg_expr, | | |
| 1108 | .fields_and_decls_len = fields_and_decls.items.len, | | |
| 1109 | .lbrace_token = lbrace_token, | | |
| 1110 | .rbrace_token = try appendToken(c, .RBrace, "}"), | | |
| 1111 | }; | | |
| 1112 | mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items); | | |
| 1113 | break :blk &container_node.base; | | |
| 1114 | } else blk: { | 1000 | } else blk: { |
| 1115 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {}); | 1001 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {}); |
| 1116 | break :blk try transCreateNodeOpaqueType(c); | 1002 | break :blk Node.opaque_literal.init(); |
| 1117 | }; | 1003 | }; |
| 1118 | | 1004 | |
| 1119 | const semicolon_token = try appendToken(c, .Semicolon, ";"); | 1005 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); |
| 1120 | const node = try ast.Node.VarDecl.create(c.arena, .{ | 1006 | payload.* = .{ |
| 1121 | .name_token = name_tok, | 1007 | .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, |
| 1122 | .mut_token = mut_tok, | 1008 | .data = .{ |
| 1123 | .semicolon_token = semicolon_token, | 1009 | .name = name, |
| 1124 | }, .{ | 1010 | .init = init_node, |
| 1125 | .visib_token = visib_tok, | 1011 | }, |
| 1126 | .eq_token = eq_token, | 1012 | }; |
| 1127 | .init_node = init_node, | | |
| 1128 | }); | | |
| 1129 | | 1013 | |
| 1130 | try addTopLevelDecl(c, name, &node.base); | 1014 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); |
| 1131 | if (!is_unnamed) | 1015 | if (!is_unnamed) |
| 1132 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); | 1016 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); |
| 1133 | return transCreateNodeIdentifier(c, name); | 1017 | return transCreateNodeIdentifier(c, name); |
| ... | @@ -1382,22 +1266,22 @@ fn transCompoundStmt(c: *Context, scope: *Scope, stmt: *const clang.CompoundStmt | ... | @@ -1382,22 +1266,22 @@ fn transCompoundStmt(c: *Context, scope: *Scope, stmt: *const clang.CompoundStmt |
| 1382 | } | 1266 | } |
| 1383 | | 1267 | |
| 1384 | fn transCStyleCastExprClass( | 1268 | fn transCStyleCastExprClass( |
| 1385 | rp: RestorePoint, | 1269 | c: *Context, |
| 1386 | scope: *Scope, | 1270 | scope: *Scope, |
| 1387 | stmt: *const clang.CStyleCastExpr, | 1271 | stmt: *const clang.CStyleCastExpr, |
| 1388 | result_used: ResultUsed, | 1272 | result_used: ResultUsed, |
| 1389 | lrvalue: LRValue, | 1273 | lrvalue: LRValue, |
| 1390 | ) TransError!*ast.Node { | 1274 | ) TransError!Node { |
| 1391 | const sub_expr = stmt.getSubExpr(); | 1275 | const sub_expr = stmt.getSubExpr(); |
| 1392 | const cast_node = (try transCCast( | 1276 | const cast_node = (try transCCast( |
| 1393 | rp, | 1277 | c, |
| 1394 | scope, | 1278 | scope, |
| 1395 | stmt.getBeginLoc(), | 1279 | stmt.getBeginLoc(), |
| 1396 | stmt.getType(), | 1280 | stmt.getType(), |
| 1397 | sub_expr.getType(), | 1281 | sub_expr.getType(), |
| 1398 | try transExpr(rp, scope, sub_expr, .used, lrvalue), | 1282 | try transExpr(c, scope, sub_expr, .used, lrvalue), |
| 1399 | )); | 1283 | )); |
| 1400 | return maybeSuppressResult(rp, scope, result_used, cast_node); | 1284 | return maybeSuppressResult(c, scope, result_used, cast_node); |
| 1401 | } | 1285 | } |
| 1402 | | 1286 | |
| 1403 | fn transDeclStmtOne( | 1287 | fn transDeclStmtOne( |