authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-08 11:52:21+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:05+02:00
log5dac3683c9e8819d6ceefb869577e3537d863c41
tree491c201e264afb8c8301fd48863ed76333c449f1
parentbb867b071a9e2fa69f39a45532dffa0f51ffdbfd
signature Commit is signed but in an unrecognized format.

translate-c: convert record and enum decls


2 files changed, 125 insertions(+), 229 deletions(-)

src/translate_c.zig+90-206
...@@ -783,7 +783,7 @@ fn transCreateNodeTypedef(...@@ -783,7 +783,7 @@ fn transCreateNodeTypedef(
783783
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}
794794
795fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*ast.Node {795fn 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 twice797 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 }
808808
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 }
821820
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);
824823
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 };
840830
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 else833 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();
850834
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
858842
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 }
866848
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 }
874854
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 };
895871
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 bits875 // 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 };
909880
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 }
927884
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 };
944902
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 });
954911
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}
960917
961fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node {918fn 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 twice920 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();
966922
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);
976932
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, "=");
981934
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 }
993946
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();
999949
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 enum951 // 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.
1004954
1005 // default to c_int since msvc and gcc default to different types955 // 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 and958 !isCBuiltinType(int_type, .Int))
1009 !isCBuiltinType(int_type, .UInt) and959 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, "{");
1024968
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());
1031974
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 else977 else
1035 enum_val_name;978 enum_val_name;
1036979
1037 const field_name_tok = try appendIdentifier(c, field_name);980 const int_node = if (!pure_enum)
1038981 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;
1044984
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, ",");
1057989
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 };
1100998
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 };
11181004
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 });
11291013
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}
13831267
1384fn transCStyleCastExprClass(1268fn 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}
14021286
1403fn transDeclStmtOne(1287fn transDeclStmtOne(
src/translate_c/ast.zig+35-23
...@@ -10,6 +10,7 @@ pub const Node = extern union {...@@ -10,6 +10,7 @@ pub const Node = extern union {
10 pub const Tag = enum {10 pub const Tag = enum {
11 null_literal,11 null_literal,
12 undefined_literal,12 undefined_literal,
13 /// opaque {}
13 opaque_literal,14 opaque_literal,
14 true_literal,15 true_literal,
15 false_literal,16 false_literal,
...@@ -42,6 +43,7 @@ pub const Node = extern union {...@@ -42,6 +43,7 @@ pub const Node = extern union {
42 func,43 func,
43 warning,44 warning,
44 failed_decl,45 failed_decl,
46 /// All enums are non-exhaustive
45 @"enum",47 @"enum",
46 @"struct",48 @"struct",
47 @"union",49 @"union",
...@@ -145,8 +147,12 @@ pub const Node = extern union {...@@ -145,8 +147,12 @@ pub const Node = extern union {
145 arg_redecl,147 arg_redecl,
146 /// const name = init;148 /// const name = init;
147 typedef,149 typedef,
150 var_simple,
148 /// pub const name = init;151 /// pub const name = init;
149 pub_typedef,152 pub_typedef,
153 pub_var_simple,
154 /// pub const enum_field_name = @enumToInt(enum_name.field_name);
155 enum_redecl,
150156
151 pub const last_no_payload_tag = Tag.usingnamespace_builtins;157 pub const last_no_payload_tag = Tag.usingnamespace_builtins;
152 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;158 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -266,7 +272,8 @@ pub const Node = extern union {...@@ -266,7 +272,8 @@ pub const Node = extern union {
266 .array_type => Payload.Array,272 .array_type => Payload.Array,
267 .arg_redecl => Payload.ArgRedecl,273 .arg_redecl => Payload.ArgRedecl,
268 .log2_int_type => Payload.Log2IntType,274 .log2_int_type => Payload.Log2IntType,
269 .typedef, .pub_typedef => Payload.Typedef,275 .typedef, .pub_typedef, .pub_var_simple => Payload.SimpleVarDecl,
276 .enum_redecl => Payload.EnumRedecl,
270 };277 };
271 }278 }
272279
...@@ -419,41 +426,37 @@ pub const Payload = struct {...@@ -419,41 +426,37 @@ pub const Payload = struct {
419 return_type: Node,426 return_type: Node,
420 body: ?Node,427 body: ?Node,
421 alignment: ?c_uint,428 alignment: ?c_uint,
422
423 pub const Param = struct {
424 is_noalias: bool,
425 name: ?[]const u8,
426 type: Node,
427 };
428 },429 },
430
431 pub const Param = struct {
432 is_noalias: bool,
433 name: ?[]const u8,
434 type: Node,
435 };
429 };436 };
430437
431 pub const Enum = struct {438 pub const Enum = struct {
432 base: Node = .{ .tag = .@"enum" },439 base: Node = .{ .tag = .@"enum" },
433 data: struct {440 data: []Field,
434 name: ?[]const u8,
435 fields: []Field,
436441
437 pub const Field = struct {442 pub const Field = struct {
438 name: []const u8,443 name: []const u8,
439 value: ?[]const u8,444 value: ?Node,
440 };445 };
441 },
442 };446 };
443447
444 pub const Record = struct {448 pub const Record = struct {
445 base: Node,449 base: Node,
446 data: struct {450 data: struct {
447 name: ?[]const u8,
448 @"packed": bool,451 @"packed": bool,
449 fields: []Field,452 fields: []Field,
450
451 pub const Field = struct {
452 name: []const u8,
453 type: Type,
454 alignment: c_uint,
455 };
456 },453 },
454
455 pub const Field = struct {
456 name: []const u8,
457 type: Node,
458 alignment: ?c_uint,
459 };
457 };460 };
458461
459 pub const ArrayInit = struct {462 pub const ArrayInit = struct {
...@@ -514,13 +517,22 @@ pub const Payload = struct {...@@ -514,13 +517,22 @@ pub const Payload = struct {
514 data: std.math.Log2Int(u64),517 data: std.math.Log2Int(u64),
515 };518 };
516519
517 pub const Typedef = struct {520 pub const SimpleVarDecl = struct {
518 base: Node,521 base: Node,
519 data: struct {522 data: struct {
520 name: []const u8,523 name: []const u8,
521 init: Node,524 init: Node,
522 },525 },
523 };526 };
527
528 pub const EnumRedecl = struct {
529 base: Node,
530 data: struct {
531 enum_val_name: []const u8,
532 field_name: []const u8,
533 enum_name: []const u8,
534 },
535 };
524};536};
525537
526/// Converts the nodes into a Zig ast.538/// Converts the nodes into a Zig ast.