authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-10-31 15:25:14+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-10-31 15:25:14+02:00
log9ca9819488db580241a93ded7b93a054de2db8af
tree8ec0a042513823c789ab28bcca6a004c2163e6f8
parent7c8d9cfa40ab96aede2a7fe8ec9dce6f10bc910a
parent28a0583b844654bec108a456eb619efb2af201a1
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6883 from Vexu/translate-c

translate-c: correctly handle pointers to opaque demoted structs

5 files changed, 169 insertions(+), 103 deletions(-)

src/codegen/c.zig+1-1
......@@ -91,7 +91,7 @@ fn genArray(file: *C, decl: *Decl) !void {
9191 if (tv.val.cast(Value.Payload.Bytes)) |payload|
9292 if (tv.ty.sentinel()) |sentinel|
9393 if (sentinel.toUnsignedInt() == 0)
94 // TODO: static by default
94 // TODO: static by default
9595 try file.constants.writer().print("const char *const {} = \"{}\";\n", .{ name, payload.data })
9696 else
9797 return file.fail(decl.src(), "TODO byte arrays with non-zero sentinels", .{})
src/translate_c.zig+82-35
......@@ -19,8 +19,6 @@ pub const Error = error{OutOfMemory};
1919const TypeError = Error || error{UnsupportedType};
2020const TransError = TypeError || error{UnsupportedTranslation};
2121
22const DeclTable = std.AutoArrayHashMap(usize, []const u8);
23
2422const SymbolTable = std.StringArrayHashMap(*ast.Node);
2523const AliasList = std.ArrayList(struct {
2624 alias: []const u8,
......@@ -254,24 +252,25 @@ const Scope = struct {
254252pub const Context = struct {
255253 gpa: *mem.Allocator,
256254 arena: *mem.Allocator,
257 token_ids: std.ArrayListUnmanaged(Token.Id),
258 token_locs: std.ArrayListUnmanaged(Token.Loc),
259 errors: std.ArrayListUnmanaged(ast.Error),
255 token_ids: std.ArrayListUnmanaged(Token.Id) = .{},
256 token_locs: std.ArrayListUnmanaged(Token.Loc) = .{},
257 errors: std.ArrayListUnmanaged(ast.Error) = .{},
260258 source_buffer: *std.ArrayList(u8),
261259 err: Error,
262260 source_manager: *clang.SourceManager,
263 decl_table: DeclTable,
261 decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},
264262 alias_list: AliasList,
265263 global_scope: *Scope.Root,
266264 clang_context: *clang.ASTContext,
267265 mangle_count: u32 = 0,
268 root_decls: std.ArrayListUnmanaged(*ast.Node),
266 root_decls: std.ArrayListUnmanaged(*ast.Node) = .{},
267 opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{},
269268
270269 /// This one is different than the root scope's name table. This contains
271270 /// a list of names that we found by visiting all the top level decls without
272271 /// translating them. The other maps are updated as we translate; this one is updated
273272 /// up front in a pre-processing step.
274 global_names: std.StringArrayHashMap(void),
273 global_names: std.StringArrayHashMapUnmanaged(void) = .{},
275274
276275 fn getMangle(c: *Context) u32 {
277276 c.mangle_count += 1;
......@@ -362,24 +361,21 @@ pub fn translate(
362361 .source_buffer = &source_buffer,
363362 .source_manager = ast_unit.getSourceManager(),
364363 .err = undefined,
365 .decl_table = DeclTable.init(gpa),
366364 .alias_list = AliasList.init(gpa),
367365 .global_scope = try arena.allocator.create(Scope.Root),
368366 .clang_context = ast_unit.getASTContext(),
369 .global_names = std.StringArrayHashMap(void).init(gpa),
370 .token_ids = .{},
371 .token_locs = .{},
372 .errors = .{},
373 .root_decls = .{},
374367 };
375368 context.global_scope.* = Scope.Root.init(&context);
376 defer context.decl_table.deinit();
377 defer context.alias_list.deinit();
378 defer context.token_ids.deinit(gpa);
379 defer context.token_locs.deinit(gpa);
380 defer context.errors.deinit(gpa);
381 defer context.global_names.deinit();
382 defer context.root_decls.deinit(gpa);
369 defer {
370 context.decl_table.deinit(gpa);
371 context.alias_list.deinit();
372 context.token_ids.deinit(gpa);
373 context.token_locs.deinit(gpa);
374 context.errors.deinit(gpa);
375 context.global_names.deinit(gpa);
376 context.root_decls.deinit(gpa);
377 context.opaque_demotes.deinit(gpa);
378 }
383379
384380 try prepopulateGlobalNameTable(ast_unit, &context);
385381
......@@ -437,7 +433,7 @@ fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void {
437433 const macro = @ptrCast(*clang.MacroDefinitionRecord, entity);
438434 const raw_name = macro.getName_getNameStart();
439435 const name = try c.str(raw_name);
440 _ = try c.global_names.put(name, {});
436 _ = try c.global_names.put(c.gpa, name, {});
441437 },
442438 else => {},
443439 }
......@@ -465,7 +461,7 @@ fn declVisitorC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool {
465461fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void {
466462 if (decl.castToNamedDecl()) |named_decl| {
467463 const decl_name = try c.str(named_decl.getName_bytes_begin());
468 _ = try c.global_names.put(decl_name, {});
464 _ = try c.global_names.put(c.gpa, decl_name, {});
469465 }
470466}
471467
......@@ -804,7 +800,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
804800}
805801
806802fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !*ast.Node {
807 _ = try c.decl_table.put(@ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name);
803 _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name);
808804 return transCreateNodeIdentifier(c, builtin_name);
809805}
810806
......@@ -851,7 +847,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev
851847 return transCreateNodeIdentifier(c, checked_name);
852848 }
853849
854 _ = try c.decl_table.put(@ptrToInt(typedef_decl.getCanonicalDecl()), checked_name);
850 _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name);
855851 const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
856852 try addTopLevelDecl(c, checked_name, node);
857853 return transCreateNodeIdentifier(c, checked_name);
......@@ -918,7 +914,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
918914 }
919915
920916 const name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ container_kind_name, bare_name });
921 _ = try c.decl_table.put(@ptrToInt(record_decl.getCanonicalDecl()), name);
917 _ = try c.decl_table.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), name);
922918
923919 const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null;
924920 const mut_tok = try appendToken(c, .Keyword_const, "const");
......@@ -930,6 +926,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
930926 const init_node = blk: {
931927 const rp = makeRestorePoint(c);
932928 const record_def = record_decl.getDefinition() orelse {
929 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
933930 const opaque_type = try transCreateNodeOpaqueType(c);
934931 semicolon = try appendToken(c, .Semicolon, ";");
935932 break :blk opaque_type;
......@@ -954,6 +951,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
954951 const field_qt = field_decl.getType();
955952
956953 if (field_decl.isBitField()) {
954 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
957955 const opaque_type = try transCreateNodeOpaqueType(c);
958956 semicolon = try appendToken(c, .Semicolon, ";");
959957 try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name});
......@@ -961,6 +959,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
961959 }
962960
963961 if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) {
962 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
964963 const opaque_type = try transCreateNodeOpaqueType(c);
965964 semicolon = try appendToken(c, .Semicolon, ";");
966965 try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name});
......@@ -979,6 +978,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
979978 _ = try appendToken(c, .Colon, ":");
980979 const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) {
981980 error.UnsupportedType => {
981 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
982982 const opaque_type = try transCreateNodeOpaqueType(c);
983983 semicolon = try appendToken(c, .Semicolon, ";");
984984 try emitWarning(c, record_loc, "{} demoted to opaque type - unable to translate type of field {}", .{ container_kind_name, raw_name });
......@@ -988,13 +988,13 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
988988 };
989989
990990 const align_expr = blk_2: {
991 const alignment = field_decl.getAlignedAttribute(rp.c.clang_context);
991 const alignment = field_decl.getAlignedAttribute(c.clang_context);
992992 if (alignment != 0) {
993 _ = try appendToken(rp.c, .Keyword_align, "align");
994 _ = try appendToken(rp.c, .LParen, "(");
993 _ = try appendToken(c, .Keyword_align, "align");
994 _ = try appendToken(c, .LParen, "(");
995995 // Clang reports the alignment in bits
996 const expr = try transCreateNodeInt(rp.c, alignment / 8);
997 _ = try appendToken(rp.c, .RParen, ")");
996 const expr = try transCreateNodeInt(c, alignment / 8);
997 _ = try appendToken(c, .RParen, ")");
998998
999999 break :blk_2 expr;
10001000 }
......@@ -1013,6 +1013,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
10131013
10141014 if (is_anon) {
10151015 _ = try c.decl_table.put(
1016 c.gpa,
10161017 @ptrToInt(field_decl.getCanonicalDecl()),
10171018 raw_name,
10181019 );
......@@ -1065,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node
10651066 }
10661067
10671068 const name = try std.fmt.allocPrint(c.arena, "enum_{}", .{bare_name});
1068 _ = try c.decl_table.put(@ptrToInt(enum_decl.getCanonicalDecl()), name);
1069 _ = try c.decl_table.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name);
10691070
10701071 const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null;
10711072 const mut_tok = try appendToken(c, .Keyword_const, "const");
......@@ -1204,8 +1205,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node
12041205 };
12051206 mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items);
12061207 break :blk &container_node.base;
1207 } else
1208 try transCreateNodeOpaqueType(c);
1208 } else blk: {
1209 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
1210 break :blk try transCreateNodeOpaqueType(c);
1211 };
12091212
12101213 const semicolon_token = try appendToken(c, .Semicolon, ";");
12111214 const node = try ast.Node.VarDecl.create(c.arena, .{
......@@ -4767,7 +4770,7 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
47674770 optional_node.rhs = try transQualType(rp, child_qt, source_loc);
47684771 return &optional_node.base;
47694772 }
4770 if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc)) {
4773 if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) {
47714774 const optional_node = try transCreateNodeSimplePrefixOp(rp.c, .OptionalType, .QuestionMark, "?");
47724775 const pointer_node = try transCreateNodePtrType(
47734776 rp.c,
......@@ -4853,6 +4856,50 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
48534856 }
48544857}
48554858
4859fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool {
4860 const ty = qt.getTypePtr();
4861 switch (qt.getTypeClass()) {
4862 .Typedef => {
4863 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
4864
4865 const typedef_decl = typedef_ty.getDecl();
4866 const underlying_type = typedef_decl.getUnderlyingType();
4867 return qualTypeWasDemotedToOpaque(c, underlying_type);
4868 },
4869 .Record => {
4870 const record_ty = @ptrCast(*const clang.RecordType, ty);
4871
4872 const record_decl = record_ty.getDecl();
4873 const canonical = @ptrToInt(record_decl.getCanonicalDecl());
4874 return c.opaque_demotes.contains(canonical);
4875 },
4876 .Enum => {
4877 const enum_ty = @ptrCast(*const clang.EnumType, ty);
4878
4879 const enum_decl = enum_ty.getDecl();
4880 const canonical = @ptrToInt(enum_decl.getCanonicalDecl());
4881 return c.opaque_demotes.contains(canonical);
4882 },
4883 .Elaborated => {
4884 const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);
4885 return qualTypeWasDemotedToOpaque(c, elaborated_ty.getNamedType());
4886 },
4887 .Decayed => {
4888 const decayed_ty = @ptrCast(*const clang.DecayedType, ty);
4889 return qualTypeWasDemotedToOpaque(c, decayed_ty.getDecayedType());
4890 },
4891 .Attributed => {
4892 const attributed_ty = @ptrCast(*const clang.AttributedType, ty);
4893 return qualTypeWasDemotedToOpaque(c, attributed_ty.getEquivalentType());
4894 },
4895 .MacroQualified => {
4896 const macroqualified_ty = @ptrCast(*const clang.MacroQualifiedType, ty);
4897 return qualTypeWasDemotedToOpaque(c, macroqualified_ty.getModifiedType());
4898 },
4899 else => return false,
4900 }
4901}
4902
48564903fn isCVoid(qt: clang.QualType) bool {
48574904 const ty = qt.getTypePtr();
48584905 if (ty.getTypeClass() == .Builtin) {
test/gen_h.zig+8-8
......@@ -10,7 +10,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
1010 \\ B = 1,
1111 \\ C = 2
1212 \\};
13 ,
13 ,
1414 \\void entry(enum Foo foo);
1515 });
1616
......@@ -33,7 +33,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
3333 \\ uint64_t E;
3434 \\ uint64_t F;
3535 \\};
36 ,
36 ,
3737 \\void entry(struct Foo foo);
3838 \\
3939 });
......@@ -68,7 +68,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
6868 \\ bool C;
6969 \\ struct Big D;
7070 \\};
71 ,
71 ,
7272 \\void entry(union Foo foo);
7373 \\
7474 });
......@@ -79,7 +79,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
7979 \\export fn entry(foo: ?*Foo) void { }
8080 , &[_][]const u8{
8181 \\struct Foo;
82 ,
82 ,
8383 \\void entry(struct Foo * foo);
8484 });
8585
......@@ -94,7 +94,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
9494 \\ int32_t A[2];
9595 \\ uint32_t * B[4];
9696 \\};
97 ,
97 ,
9898 \\void entry(struct Foo foo, uint8_t bar[]);
9999 \\
100100 });
......@@ -109,7 +109,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
109109 \\}
110110 , &[_][]const u8{
111111 \\struct S;
112 ,
112 ,
113113 \\uint8_t a(struct S * s);
114114 \\
115115 });
......@@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
125125 \\}
126126 , &[_][]const u8{
127127 \\union U;
128 ,
128 ,
129129 \\uint8_t a(union U * s);
130130 \\
131131 });
......@@ -141,7 +141,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
141141 \\}
142142 , &[_][]const u8{
143143 \\enum E;
144 ,
144 ,
145145 \\uint8_t a(enum E * s);
146146 \\
147147 });
test/stage2/zir.zig+1-1
......@@ -156,7 +156,7 @@ pub fn addCases(ctx: *TestContext) !void {
156156 \\ %0 = call(@a, [])
157157 \\ %1 = returnvoid()
158158 \\})
159 ,
159 ,
160160 &[_][]const u8{
161161 ":18:21: error: message",
162162 },
test/translate_c.zig+77-58
......@@ -3,6 +3,26 @@ const std = @import("std");
33const CrossTarget = std.zig.CrossTarget;
44
55pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("pointer to opaque demoted struct",
7 \\typedef struct {
8 \\ _Atomic int foo;
9 \\} Foo;
10 \\
11 \\typedef struct {
12 \\ Foo *bar;
13 \\} Bar;
14 , &[_][]const u8{
15 \\const struct_unnamed_1 = //
16 ,
17 \\warning: unsupported type: 'Atomic'
18 \\ opaque {}; //
19 ,
20 \\pub const Foo = struct_unnamed_1;
21 \\const struct_unnamed_2 = extern struct {
22 \\ bar: ?*Foo,
23 \\};
24 });
25
626 cases.add("macro expressions respect C operator precedence",
727 \\#define FOO *((foo) + 2)
828 \\#define VALUE (1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9)
......@@ -11,9 +31,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1131 \\ | (*((unsigned char *)(p) + 2) << 16))
1232 , &[_][]const u8{
1333 \\pub const FOO = (foo + 2).*;
14 ,
34 ,
1535 \\pub const VALUE = ((((1 + (2 * 3)) + (4 * 5)) + 6) << 7) | @boolToInt(8 == 9);
16 ,
36 ,
1737 \\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf(((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16)) {
1838 \\ return ((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16);
1939 \\}
......@@ -81,11 +101,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
81101 \\ a: u8,
82102 \\};
83103 \\pub const Color = struct_Color;
84 ,
104 ,
85105 \\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
86106 \\ return type_1;
87107 \\}
88 ,
108 ,
89109 \\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ 200, 200, 200, 255 });
90110 });
91111
......@@ -119,7 +139,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
119139 \\pub inline fn FOO(x: anytype) @TypeOf(@boolToInt(x >= 0) + @boolToInt(x >= 0)) {
120140 \\ return @boolToInt(x >= 0) + @boolToInt(x >= 0);
121141 \\}
122 ,
142 ,
123143 \\pub const BAR = (1 != 0) and (2 > 4);
124144 });
125145
......@@ -138,7 +158,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
138158 \\struct bar { int x; int y[0]; };
139159 , &[_][]const u8{
140160 \\pub const struct_foo = opaque {};
141 ,
161 ,
142162 \\pub const struct_bar = opaque {};
143163 });
144164
......@@ -166,7 +186,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
166186 \\ _ = foo;
167187 \\ break :blk bar;
168188 \\};
169 ,
189 ,
170190 \\pub inline fn bar(x: anytype) @TypeOf(baz(1, 2)) {
171191 \\ return blk: {
172192 \\ _ = &x;
......@@ -185,7 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
185205 \\#define inline 2
186206 , &[_][]const u8{
187207 \\pub const foo = 1;
188 ,
208 ,
189209 \\pub const @"inline" = 2;
190210 });
191211
......@@ -205,12 +225,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
205225 \\};
206226 , &[_][]const u8{
207227 \\pub const struct_arcan_shmif_page = //
208 ,
228 ,
209229 \\warning: unsupported type: 'Atomic'
210230 \\ opaque {}; //
211 ,
231 ,
212232 \\ warning: struct demoted to opaque type - unable to translate type of field abufused
213 , // TODO should be `addr: *struct_arcan_shmif_page`
233 , // TODO should be `addr: *struct_arcan_shmif_page`
214234 \\pub const struct_arcan_shmif_cont = extern struct {
215235 \\ addr: [*c]struct_arcan_shmif_page,
216236 \\};
......@@ -529,7 +549,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
529549 \\Foo fun(Foo *a);
530550 , &[_][]const u8{
531551 \\pub const Foo = c_void;
532 ,
552 ,
533553 \\pub extern fn fun(a: ?*Foo) Foo;
534554 });
535555
......@@ -629,7 +649,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
629649 \\};
630650 , &[_][]const u8{
631651 \\pub const struct_Foo = opaque {};
632 ,
652 ,
633653 \\pub const struct_Bar = extern struct {
634654 \\ foo: ?*struct_Foo,
635655 \\};
......@@ -646,7 +666,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
646666 \\#define FLASH_BANK_SIZE (FLASH_SIZE >> 1) /* 1 MB */
647667 , &[_][]const u8{
648668 \\pub const FLASH_SIZE = @as(c_ulong, 0x200000);
649 ,
669 ,
650670 \\pub const FLASH_BANK_SIZE = FLASH_SIZE >> 1;
651671 });
652672
......@@ -665,13 +685,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
665685 \\pub const struct_Foo = extern struct {
666686 \\ a: [*c]Foo,
667687 \\};
668 ,
688 ,
669689 \\pub const Foo = struct_Foo;
670 ,
690 ,
671691 \\pub const struct_Bar = extern struct {
672692 \\ a: [*c]Foo,
673693 \\};
674 ,
694 ,
675695 \\pub const Bar = struct_Bar;
676696 });
677697
......@@ -685,7 +705,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
685705 \\ x: c_int,
686706 \\ y: [*c]u8,
687707 \\};
688 ,
708 ,
689709 \\pub const Foo = struct_Foo;
690710 });
691711
......@@ -697,7 +717,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
697717 \\pub const struct_Foo = extern struct {
698718 \\ derp: ?fn ([*c]struct_Foo) callconv(.C) void,
699719 \\};
700 ,
720 ,
701721 \\pub const Foo = struct_Foo;
702722 });
703723
......@@ -706,9 +726,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
706726 \\struct Foo *some_func(struct Foo *foo, int x);
707727 , &[_][]const u8{
708728 \\pub const struct_Foo = opaque {};
709 ,
729 ,
710730 \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
711 ,
731 ,
712732 \\pub const Foo = struct_Foo;
713733 });
714734
......@@ -723,7 +743,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
723743 \\#define THING1 1234
724744 , &[_][]const u8{
725745 \\pub const THING1 = 1234;
726 ,
746 ,
727747 \\pub const THING2 = THING1;
728748 });
729749
......@@ -741,7 +761,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
741761 \\pub const struct_Bar = extern struct {
742762 \\ next: [*c]struct_Foo,
743763 \\};
744 ,
764 ,
745765 \\pub const struct_Foo = extern struct {
746766 \\ next: [*c]struct_Bar,
747767 \\};
......@@ -761,7 +781,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
761781 \\pub const struct_comptime = extern struct {
762782 \\ @"defer": c_int,
763783 \\};
764 ,
784 ,
765785 \\pub const @"comptime" = struct_comptime;
766786 });
767787
......@@ -1003,7 +1023,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10031023 \\ x: c_int,
10041024 \\ y: f64,
10051025 \\};
1006 ,
1026 ,
10071027 \\pub const Foo = union_Foo;
10081028 });
10091029
......@@ -1446,7 +1466,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14461466 \\ p,
14471467 \\ _,
14481468 \\};
1449 ,
1469 ,
14501470 \\pub const Baz = struct_Baz;
14511471 });
14521472
......@@ -1512,13 +1532,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15121532 \\#define bar fn_ptr2
15131533 , &[_][]const u8{
15141534 \\pub extern var fn_ptr: ?fn () callconv(.C) void;
1515 ,
1535 ,
15161536 \\pub inline fn foo() void {
15171537 \\ return fn_ptr.?();
15181538 \\}
1519 ,
1539 ,
15201540 \\pub extern var fn_ptr2: ?fn (c_int, f32) callconv(.C) u8;
1521 ,
1541 ,
15221542 \\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 {
15231543 \\ return fn_ptr2.?(arg_1, arg_2);
15241544 \\}
......@@ -1549,13 +1569,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15491569 \\ gl: struct_unnamed_1,
15501570 \\};
15511571 \\pub extern var glProcs: union_OpenGLProcs;
1552 ,
1572 ,
15531573 \\pub const glClearPFN = PFNGLCLEARPROC;
1554 ,
1574 ,
15551575 \\pub inline fn glClearUnion(arg_2: GLbitfield) void {
15561576 \\ return glProcs.gl.Clear.?(arg_2);
15571577 \\}
1558 ,
1578 ,
15591579 \\pub const OpenGLProcs = union_OpenGLProcs;
15601580 });
15611581
......@@ -1571,11 +1591,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15711591 \\#define FOO(L,b) (L + b)
15721592 , &[_][]const u8{
15731593 \\pub extern var c: c_int;
1574 ,
1594 ,
15751595 \\pub inline fn BASIC(c_1: anytype) @TypeOf(c_1 * 2) {
15761596 \\ return c_1 * 2;
15771597 \\}
1578 ,
1598 ,
15791599 \\pub inline fn FOO(L: anytype, b: anytype) @TypeOf(L + b) {
15801600 \\ return L + b;
15811601 \\}
......@@ -1587,9 +1607,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15871607 \\#define FOO_CHAR '\xfF'
15881608 , &[_][]const u8{
15891609 \\pub const FOO = "aoeu\xab derp";
1590 ,
1610 ,
15911611 \\pub const FOO2 = "aoeu\x7a derp";
1592 ,
1612 ,
15931613 \\pub const FOO_CHAR = '\xff';
15941614 });
15951615
......@@ -1599,9 +1619,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15991619 \\#define RCC_BASE (D3_AHB1PERIPH_BASE + 0x4400UL)
16001620 , &[_][]const u8{
16011621 \\pub const PERIPH_BASE = @as(c_ulong, 0x40000000);
1602 ,
1622 ,
16031623 \\pub const D3_APB1PERIPH_BASE = PERIPH_BASE + @as(c_ulong, 0x18000000);
1604 ,
1624 ,
16051625 \\pub const RCC_BASE = D3_AHB1PERIPH_BASE + @as(c_ulong, 0x4400);
16061626 });
16071627
......@@ -1738,7 +1758,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17381758 , &[_][]const u8{
17391759 \\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2));
17401760 ,
1741
17421761 \\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
17431762 });
17441763
......@@ -2011,7 +2030,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20112030 \\ var p: c_int = @boolToInt(((c != null) and (td != 0)));
20122031 \\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
20132032 \\}
2014 ,
2033 ,
20152034 \\pub const Foo = enum_Foo;
20162035 });
20172036
......@@ -2030,14 +2049,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20302049 \\ x: c_int,
20312050 \\ y: c_int,
20322051 \\};
2033 ,
2052 ,
20342053 \\pub const enum_Bar = extern enum(c_int) {
20352054 \\ A,
20362055 \\ B,
20372056 \\ _,
20382057 \\};
20392058 \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
2040 ,
2059 ,
20412060 \\pub const Foo = struct_Foo;
20422061 \\pub const Bar = enum_Bar;
20432062 });
......@@ -2153,9 +2172,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
21532172 \\ _ = a.b;
21542173 \\ _ = c.*.b;
21552174 \\}
2156 ,
2175 ,
21572176 \\pub const DOT = a.b;
2158 ,
2177 ,
21592178 \\pub const ARROW = a.*.b;
21602179 });
21612180
......@@ -2171,7 +2190,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
21712190 \\ var index = arg_index;
21722191 \\ return array[@intCast(c_uint, index)];
21732192 \\}
2174 ,
2193 ,
21752194 \\pub const ACCESS = array[2];
21762195 });
21772196
......@@ -2748,9 +2767,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
27482767 \\#define FOO_CHAR '\077'
27492768 , &[_][]const u8{
27502769 \\pub const FOO = "aoeu\x13 derp";
2751 ,
2770 ,
27522771 \\pub const FOO2 = "aoeu\x134 derp";
2753 ,
2772 ,
27542773 \\pub const FOO_CHAR = '\x3f';
27552774 });
27562775
......@@ -2770,7 +2789,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
27702789 \\ @"1" = 6,
27712790 \\ _,
27722791 \\};
2773 ,
2792 ,
27742793 \\pub const Foo = enum_Foo;
27752794 });
27762795
......@@ -2782,9 +2801,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
27822801 \\pub inline fn FOO(bar: anytype) @TypeOf(baz((@import("std").meta.cast(?*c_void, baz)))) {
27832802 \\ return baz((@import("std").meta.cast(?*c_void, baz)));
27842803 \\}
2785 ,
2804 ,
27862805 \\pub const BAR = (@import("std").meta.cast(?*c_void, a));
2787 ,
2806 ,
27882807 \\pub const BAZ = (@import("std").meta.cast(u32, 2));
27892808 });
27902809
......@@ -2824,7 +2843,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
28242843 \\pub inline fn MIN(a: anytype, b: anytype) @TypeOf(if (b < a) b else a) {
28252844 \\ return if (b < a) b else a;
28262845 \\}
2827 ,
2846 ,
28282847 \\pub inline fn MAX(a: anytype, b: anytype) @TypeOf(if (b > a) b else a) {
28292848 \\ return if (b > a) b else a;
28302849 \\}
......@@ -2892,7 +2911,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
28922911 \\ var bar_1 = arg_bar_1;
28932912 \\ bar_1 = 2;
28942913 \\}
2895 ,
2914 ,
28962915 \\pub const bar = 4;
28972916 });
28982917
......@@ -2964,9 +2983,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
29642983 \\#define BAZ "oh, " FOO
29652984 , &[_][]const u8{
29662985 \\pub const FOO = "hello";
2967 ,
2986 ,
29682987 \\pub const BAR = FOO ++ " world";
2969 ,
2988 ,
29702989 \\pub const BAZ = "oh, " ++ FOO;
29712990 });
29722991
......@@ -2976,9 +2995,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
29762995 \\#define BAR FOO BAZ
29772996 , &[_][]const u8{
29782997 \\pub const FOO = "hello";
2979 ,
2998 ,
29802999 \\pub const BAZ = " world";
2981 ,
3000 ,
29823001 \\pub const BAR = FOO ++ BAZ;
29833002 });
29843003
......@@ -2987,7 +3006,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
29873006 \\#define BAR FOO "c"
29883007 , &[_][]const u8{
29893008 \\pub const FOO = "a" ++ "b";
2990 ,
3009 ,
29913010 \\pub const BAR = FOO ++ "c";
29923011 });
29933012
......@@ -3023,7 +3042,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
30233042 \\#define FOO ((int)0x8000)
30243043 , &[_][]const u8{
30253044 \\pub const NULL = (@import("std").meta.cast(?*c_void, 0));
3026 ,
3045 ,
30273046 \\pub const FOO = (@import("std").meta.cast(c_int, 0x8000));
30283047 });
30293048