authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-07 22:02:42+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:37:07+02:00
logf5041caa2e9d1e891bd93aa2721a4a283123f0d9
treed54ecc828fd0f04431939c31a5019c3820e14f78
parent4c0c9b07555bb69d05142dfe038a7cad79068ba9
signature Commit is signed but in an unrecognized format.

translate-c: more binaryoperator chagnes, blocks and unary type expressions


2 files changed, 156 insertions(+), 197 deletions(-)

src/translate_c.zig+98-175
...@@ -68,16 +68,15 @@ const Scope = struct {...@@ -68,16 +68,15 @@ const Scope = struct {
68 }68 }
69 };69 };
7070
71 /// Represents an in-progress ast.Node.Block. This struct is stack-allocated.71 /// Represents an in-progress Node.Block. This struct is stack-allocated.
72 /// When it is deinitialized, it produces an ast.Node.Block which is allocated72 /// When it is deinitialized, it produces an Node.Block which is allocated
73 /// into the main arena.73 /// into the main arena.
74 const Block = struct {74 const Block = struct {
75 base: Scope,75 base: Scope,
76 statements: std.ArrayList(*ast.Node),76 statements: std.ArrayList(Node),
77 variables: AliasList,77 variables: AliasList,
78 label: ?ast.TokenIndex,
79 mangle_count: u32 = 0,78 mangle_count: u32 = 0,
80 lbrace: ast.TokenIndex,79 label: ?[]const u8 = null,
8180
82 /// When the block corresponds to a function, keep track of the return type81 /// When the block corresponds to a function, keep track of the return type
83 /// so that the return expression can be cast, if necessary82 /// so that the return expression can be cast, if necessary
...@@ -89,14 +88,11 @@ const Scope = struct {...@@ -89,14 +88,11 @@ const Scope = struct {
89 .id = .Block,88 .id = .Block,
90 .parent = parent,89 .parent = parent,
91 },90 },
92 .statements = std.ArrayList(*ast.Node).init(c.gpa),91 .statements = std.ArrayList(Node).init(c.gpa),
93 .variables = AliasList.init(c.gpa),92 .variables = AliasList.init(c.gpa),
94 .label = null,
95 .lbrace = try appendToken(c, .LBrace, "{"),
96 };93 };
97 if (labeled) {94 if (labeled) {
98 blk.label = try appendIdentifier(c, try blk.makeMangledName(c, "blk"));95 blk.label = try blk.makeMangledName(c, "blk");
99 _ = try appendToken(c, .Colon, ":");
100 }96 }
101 return blk;97 return blk;
102 }98 }
...@@ -107,31 +103,16 @@ const Scope = struct {...@@ -107,31 +103,16 @@ const Scope = struct {
107 self.* = undefined;103 self.* = undefined;
108 }104 }
109105
110 fn complete(self: *Block, c: *Context) !*ast.Node {106 fn complete(self: *Block, c: *Context) !Node {
111 // We reserve 1 extra statement if the parent is a Loop. This is in case of107 // We reserve 1 extra statement if the parent is a Loop. This is in case of
112 // do while, we want to put `if (cond) break;` at the end.108 // do while, we want to put `if (cond) break;` at the end.
113 const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop);109 const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop);
114 const rbrace = try appendToken(c, .RBrace, "}");110 const stmts = try c.arena.alloc(Node, alloc_len);
115 if (self.label) |label| {111 mem.copy(Node, stmts, self.statements.items);
116 const node = try ast.Node.LabeledBlock.alloc(c.arena, alloc_len);112 return Node.block.create(c.arena, .{
117 node.* = .{113 .lable = self.label,
118 .statements_len = self.statements.items.len,114 .stmts = stmts,
119 .lbrace = self.lbrace,115 });
120 .rbrace = rbrace,
121 .label = label,
122 };
123 mem.copy(*ast.Node, node.statements(), self.statements.items);
124 return &node.base;
125 } else {
126 const node = try ast.Node.Block.alloc(c.arena, alloc_len);
127 node.* = .{
128 .statements_len = self.statements.items.len,
129 .lbrace = self.lbrace,
130 .rbrace = rbrace,
131 };
132 mem.copy(*ast.Node, node.statements(), self.statements.items);
133 return &node.base;
134 }
135 }116 }
136117
137 /// Given the desired name, return a name that does not shadow anything from outer scopes.118 /// Given the desired name, return a name that does not shadow anything from outer scopes.
...@@ -1390,7 +1371,7 @@ fn transBinaryOperator(...@@ -1390,7 +1371,7 @@ fn transBinaryOperator(
1390 // signed integer division uses @divTrunc1371 // signed integer division uses @divTrunc
1391 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);1372 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1392 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);1373 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1393 const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs});1374 const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
1394 return maybeSuppressResult(c, scope, result_used, div_trunc);1375 return maybeSuppressResult(c, scope, result_used, div_trunc);
1395 }1376 }
1396 },1377 },
...@@ -1399,7 +1380,7 @@ fn transBinaryOperator(...@@ -1399,7 +1380,7 @@ fn transBinaryOperator(
1399 // signed integer division uses @rem1380 // signed integer division uses @rem
1400 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);1381 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1401 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);1382 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1402 const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs});1383 const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
1403 return maybeSuppressResult(c, scope, result_used, rem);1384 return maybeSuppressResult(c, scope, result_used, rem);
1404 }1385 }
1405 },1386 },
...@@ -1411,6 +1392,12 @@ fn transBinaryOperator(...@@ -1411,6 +1392,12 @@ fn transBinaryOperator(
1411 const node = try transCreateNodeShiftOp(c, scope, stmt, .shr);1392 const node = try transCreateNodeShiftOp(c, scope, stmt, .shr);
1412 return maybeSuppressResult(c, scope, result_used, node);1393 return maybeSuppressResult(c, scope, result_used, node);
1413 },1394 },
1395 .LAnd => {
1396 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_and, result_used, true);
1397 },
1398 .LOr => {
1399 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_or, result_used, true);
1400 },
1414 else => {},1401 else => {},
1415 }1402 }
1416 var op_id: Node.Tag = undefined;1403 var op_id: Node.Tag = undefined;
...@@ -1471,17 +1458,19 @@ fn transBinaryOperator(...@@ -1471,17 +1458,19 @@ fn transBinaryOperator(
1471 .Or => {1458 .Or => {
1472 op_id = .bit_or;1459 op_id = .bit_or;
1473 },1460 },
1474 .LAnd => {
1475 op_id = .@"and";
1476 },
1477 .LOr => {
1478 op_id = .@"or";
1479 },
1480 else => unreachable,1461 else => unreachable,
1481 }1462 }
14821463
1483 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);1464 const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1484 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);1465 const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1466
1467 const lhs = if (isBoolRes(lhs_uncasted))
1468 try Node.bool_to_int.create(c.arena, lhs_uncasted)
1469 else lhs_uncasted;
1470
1471 const rhs = if (isBoolRes(rhs_uncasted))
1472 try Node.bool_to_int.create(c.arena, rhs_uncasted)
1473 else rhs_uncasted;
14851474
1486 const payload = try c.arena.create(ast.Payload.BinOp);1475 const payload = try c.arena.create(ast.Payload.BinOp);
1487 payload.* = .{1476 payload.* = .{
...@@ -1495,7 +1484,7 @@ fn transBinaryOperator(...@@ -1495,7 +1484,7 @@ fn transBinaryOperator(
1495}1484}
14961485
1497fn transCompoundStmtInline(1486fn transCompoundStmtInline(
1498 rp: RestorePoint,1487 c: *Context,
1499 parent_scope: *Scope,1488 parent_scope: *Scope,
1500 stmt: *const clang.CompoundStmt,1489 stmt: *const clang.CompoundStmt,
1501 block: *Scope.Block,1490 block: *Scope.Block,
...@@ -1503,16 +1492,16 @@ fn transCompoundStmtInline(...@@ -1503,16 +1492,16 @@ fn transCompoundStmtInline(
1503 var it = stmt.body_begin();1492 var it = stmt.body_begin();
1504 const end_it = stmt.body_end();1493 const end_it = stmt.body_end();
1505 while (it != end_it) : (it += 1) {1494 while (it != end_it) : (it += 1) {
1506 const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);1495 const result = try transStmt(c, parent_scope, it[0], .unused, .r_value);
1507 try block.statements.append(result);1496 try block.statements.append(result);
1508 }1497 }
1509}1498}
15101499
1511fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!*ast.Node {1500fn transCompoundStmt(c: *Context, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!Node {
1512 var block_scope = try Scope.Block.init(rp.c, scope, false);1501 var block_scope = try Scope.Block.init(c, scope, false);
1513 defer block_scope.deinit();1502 defer block_scope.deinit();
1514 try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope);1503 try transCompoundStmtInline(c, &block_scope.base, stmt, &block_scope);
1515 return try block_scope.complete(rp.c);1504 return try block_scope.complete(c);
1516}1505}
15171506
1518fn transCStyleCastExprClass(1507fn transCStyleCastExprClass(
...@@ -3233,22 +3222,18 @@ fn qualTypeGetFnProto(qt: clang.QualType, is_ptr: *bool) ?ClangFunctionType {...@@ -3233,22 +3222,18 @@ fn qualTypeGetFnProto(qt: clang.QualType, is_ptr: *bool) ?ClangFunctionType {
3233}3222}
32343223
3235fn transUnaryExprOrTypeTraitExpr(3224fn transUnaryExprOrTypeTraitExpr(
3236 rp: RestorePoint,3225 c: *Context,
3237 scope: *Scope,3226 scope: *Scope,
3238 stmt: *const clang.UnaryExprOrTypeTraitExpr,3227 stmt: *const clang.UnaryExprOrTypeTraitExpr,
3239 result_used: ResultUsed,3228 result_used: ResultUsed,
3240) TransError!*ast.Node {3229) TransError!Node {
3241 const loc = stmt.getBeginLoc();3230 const loc = stmt.getBeginLoc();
3242 const type_node = try transQualType(3231 const type_node = try transQualType(rp, stmt.getTypeOfArgument(), loc);
3243 rp,
3244 stmt.getTypeOfArgument(),
3245 loc,
3246 );
32473232
3248 const kind = stmt.getKind();3233 const kind = stmt.getKind();
3249 const kind_str = switch (kind) {3234 switch (kind) {
3250 .SizeOf => "@sizeOf",3235 .SizeOf => return Node.sizeof.create(c.arena, type_node),
3251 .AlignOf => "@alignOf",3236 .AlignOf => return Node.alignof.create(c.arena, type_node),
3252 .PreferredAlignOf,3237 .PreferredAlignOf,
3253 .VecStep,3238 .VecStep,
3254 .OpenMPRequiredSimdAlign,3239 .OpenMPRequiredSimdAlign,
...@@ -3259,12 +3244,7 @@ fn transUnaryExprOrTypeTraitExpr(...@@ -3259,12 +3244,7 @@ fn transUnaryExprOrTypeTraitExpr(
3259 "Unsupported type trait kind {}",3244 "Unsupported type trait kind {}",
3260 .{kind},3245 .{kind},
3261 ),3246 ),
3262 };3247 }
3263
3264 const builtin_node = try rp.c.createBuiltinCall(kind_str, 1);
3265 builtin_node.params()[0] = type_node;
3266 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3267 return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);
3268}3248}
32693249
3270fn qualTypeHasWrappingOverflow(qt: clang.QualType) bool {3250fn qualTypeHasWrappingOverflow(qt: clang.QualType) bool {
...@@ -3967,8 +3947,8 @@ fn transQualTypeInitialized(...@@ -3967,8 +3947,8 @@ fn transQualTypeInitialized(
3967 return transQualType(rp, qt, source_loc);3947 return transQualType(rp, qt, source_loc);
3968}3948}
39693949
3970fn transQualType(rp: RestorePoint, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!*ast.Node {3950fn transQualType(c: *Context, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!Node {
3971 return transType(rp, qt.getTypePtr(), source_loc);3951 return transType(c, qt.getTypePtr(), source_loc);
3972}3952}
39733953
3974/// Produces a Zig AST node by translating a Clang QualType, respecting the width, but modifying the signed-ness.3954/// Produces a Zig AST node by translating a Clang QualType, respecting the width, but modifying the signed-ness.
...@@ -4318,19 +4298,27 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c...@@ -4318,19 +4298,27 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c
4318 return &field_access_node.base;4298 return &field_access_node.base;
4319}4299}
43204300
4321fn transCreateNodeSimplePrefixOp(4301fn transCreateNodeBoolInfixOp(
4322 c: *Context,4302 c: *Context,
4323 comptime tag: ast.Node.Tag,4303 scope: *Scope,
4324 op_tok_id: std.zig.Token.Id,4304 stmt: *const clang.BinaryOperator,
4325 bytes: []const u8,4305 op: ast.Node.Tag,
4326) !*ast.Node.SimplePrefixOp {4306 used: ResultUsed,
4327 const node = try c.arena.create(ast.Node.SimplePrefixOp);4307) !Node {
4328 node.* = .{4308 std.debug.assert(op == .bool_and or op == .bool_or);
4329 .base = .{ .tag = tag },4309
4330 .op_token = try appendToken(c, op_tok_id, bytes),4310 const lhs = try transBoolExpr(rp, scope, stmt.getLHS(), .used, .l_value, true);
4331 .rhs = undefined, // translate and set afterward4311 const rhs = try transBoolExpr(rp, scope, stmt.getRHS(), .used, .r_value, true);
4312
4313 const payload = try c.arena.create(ast.Payload.BinOp);
4314 payload.* = .{
4315 .base = .{ .tag = op },
4316 .data = .{
4317 .lhs = lhs,
4318 .rhs = rhs,
4319 },
4332 };4320 };
4333 return node;4321 return maybeSuppressResult(c, scope, used, &payload.base);
4334}4322}
43354323
4336fn transCreateNodePtrType(4324fn transCreateNodePtrType(
...@@ -4784,30 +4772,30 @@ fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.ArrayAcces...@@ -4784,30 +4772,30 @@ fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.ArrayAcces
4784 return node;4772 return node;
4785}4773}
47864774
4787fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type {4775fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Node {
4788 switch (ty.getTypeClass()) {4776 switch (ty.getTypeClass()) {
4789 .Builtin => {4777 .Builtin => {
4790 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);4778 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
4791 return Type.initTag(switch (builtin_ty.getKind()) {4779 return Node.type.create(c.arena, switch (builtin_ty.getKind()) {
4792 .Void => .c_void,4780 .Void => "c_void",
4793 .Bool => .bool,4781 .Bool => "bool",
4794 .Char_U, .UChar, .Char_S, .Char8 => .u8,4782 .Char_U, .UChar, .Char_S, .Char8 => "u8",
4795 .SChar => .i8,4783 .SChar => "i8",
4796 .UShort => .c_ushort,4784 .UShort => "c_ushort",
4797 .UInt => .c_uint,4785 .UInt => "c_uint",
4798 .ULong => .c_ulong,4786 .ULong => "c_ulong",
4799 .ULongLong => .c_ulonglong,4787 .ULongLong => "c_ulonglong",
4800 .Short => .c_short,4788 .Short => "c_short",
4801 .Int => .c_int,4789 .Int => "c_int",
4802 .Long => .c_long,4790 .Long => "c_long",
4803 .LongLong => .c_longlong,4791 .LongLong => "c_longlong",
4804 .UInt128 => .u128,4792 .UInt128 => "u128",
4805 .Int128 => .i128,4793 .Int128 => "i128",
4806 .Float => .f32,4794 .Float => "f32",
4807 .Double => .f64,4795 .Double => "f64",
4808 .Float128 => .f128,4796 .Float128 => "f128",
4809 .Float16 => .f16,4797 .Float16 => "f16",
4810 .LongDouble => .c_longdouble,4798 .LongDouble => "c_longdouble",
4811 else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),4799 else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
4812 });4800 });
4813 },4801 },
...@@ -4826,61 +4814,25 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio...@@ -4826,61 +4814,25 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
4826 .Pointer => {4814 .Pointer => {
4827 const child_qt = ty.getPointeeType();4815 const child_qt = ty.getPointeeType();
4828 if (qualTypeChildIsFnProto(child_qt)) {4816 if (qualTypeChildIsFnProto(child_qt)) {
4829 return Type.optional_single_mut_pointer.create(c.arena, try transQualType(c, child_qt, source_loc));4817 return Node.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc));
4830 }4818 }
4831 const is_const = child_qt.isConstQualified();4819 const is_const = child_qt.isConstQualified();
4832 const is_volatile = child_qt.isVolatileQualified();4820 const is_volatile = child_qt.isVolatileQualified();
4833 const elem_type = try transQualType(c, child_qt, source_loc);4821 const elem_type = try transQualType(c, child_qt, source_loc);
4834 if (elem_type.zigTypeTag() == .Opaque) {4822 if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) {
4835 if (!is_volatile) {4823 return Node.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
4836 if (is_const) {
4837 return Type.optional_single_const_pointer.create(c.arena, elem_type);
4838 } else {
4839 return Type.optional_single_mut_pointer.create(c.arena, elem_type);
4840 }
4841 }
4842
4843 return Type.pointer.create(c.arena, .{
4844 .pointee_type = elem_type,
4845 .sentinel = null,
4846 .@"align" = 0,
4847 .bit_offset = 0,
4848 .host_size = 0,
4849 .@"allowzero" = false,
4850 .mutable = !is_const,
4851 .@"volatile" = true,
4852 .size = .Single,
4853 });
4854 }4824 }
48554825
4856 if (!is_volatile) {4826 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
4857 if (is_const) {
4858 return Type.c_const_pointer.create(c.arena, elem_type);
4859 } else {
4860 return Type.c_mut_pointer.create(c.arena, elem_type);
4861 }
4862 }
4863
4864 return Type.pointer.create(c.arena, .{
4865 .pointee_type = elem_type,
4866 .sentinel = null,
4867 .@"align" = 0,
4868 .bit_offset = 0,
4869 .host_size = 0,
4870 .@"allowzero" = false,
4871 .mutable = !is_const,
4872 .@"volatile" = true,
4873 .size = .C,
4874 });
4875 },4827 },
4876 .ConstantArray => {4828 .ConstantArray => {
4877 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);4829 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);
48784830
4879 const size_ap_int = const_arr_ty.getSize();4831 const size_ap_int = const_arr_ty.getSize();
4880 const size = size_ap_int.getLimitedValue(math.maxInt(usize));4832 const size = size_ap_int.getLimitedValue(math.maxInt(usize));
4881 const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc);4833 const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc);
4882 4834
4883 return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type });4835 return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type });
4884 },4836 },
4885 .IncompleteArray => {4837 .IncompleteArray => {
4886 const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);4838 const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);
...@@ -4890,25 +4842,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio...@@ -4890,25 +4842,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
4890 const is_volatile = child_qt.isVolatileQualified();4842 const is_volatile = child_qt.isVolatileQualified();
4891 const elem_type = try transQualType(c, child_qt, source_loc);4843 const elem_type = try transQualType(c, child_qt, source_loc);
48924844
4893 if (!is_volatile) {4845 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
4894 if (is_const) {
4895 return Type.c_const_pointer.create(c.arena, elem_type);
4896 } else {
4897 return Type.c_mut_pointer.create(c.arena, elem_type);
4898 }
4899 }
4900
4901 return Type.pointer.create(c.arena, .{
4902 .pointee_type = elem_type,
4903 .sentinel = null,
4904 .@"align" = 0,
4905 .bit_offset = 0,
4906 .host_size = 0,
4907 .@"allowzero" = false,
4908 .mutable = !is_const,
4909 .@"volatile" = true,
4910 .size = .C,
4911 });
4912 },4846 },
4913 .Typedef => {4847 .Typedef => {
4914 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);4848 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
...@@ -5233,25 +5167,14 @@ fn finishTransFnProto(...@@ -5233,25 +5167,14 @@ fn finishTransFnProto(
5233 return fn_proto;5167 return fn_proto;
5234}5168}
52355169
5236fn revertAndWarn(5170fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void {
5237 rp: RestorePoint,
5238 err: anytype,
5239 source_loc: clang.SourceLocation,
5240 comptime format: []const u8,
5241 args: anytype,
5242) (@TypeOf(err) || error{OutOfMemory}) {
5243 rp.activate();
5244 try emitWarning(rp.c, source_loc, format, args);
5245 return err;
5246}
5247
5248fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void {
5249 const args_prefix = .{c.locStr(loc)};5171 const args_prefix = .{c.locStr(loc)};
5250 _ = try appendTokenFmt(c, .LineComment, "// {s}: warning: " ++ format, args_prefix ++ args);5172 const value = std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args);
5173 try scope.appendNode(c.gpa, try Node.warning.create(c.arena, value));
5251}5174}
52525175
5253fn fail(5176fn fail(
5254 rp: RestorePoint,5177 c: *Context,
5255 err: anytype,5178 err: anytype,
5256 source_loc: clang.SourceLocation,5179 source_loc: clang.SourceLocation,
5257 comptime format: []const u8,5180 comptime format: []const u8,
src/translate_c/ast.zig+58-22
...@@ -107,6 +107,25 @@ pub const Node = extern union {...@@ -107,6 +107,25 @@ pub const Node = extern union {
107 rem,107 rem,
108 /// @divTrunc(lhs, rhs)108 /// @divTrunc(lhs, rhs)
109 div_trunc,109 div_trunc,
110 /// @boolToInt(lhs, rhs)
111 bool_to_int,
112
113 negate,
114 negate_wrap,
115 bit_not,
116 not,
117
118 block,
119 @"break",
120
121 sizeof,
122 alignof,
123 type,
124
125 optional_type,
126 c_pointer,
127 single_pointer,
128 array_type,
110129
111 pub const last_no_payload_tag = Tag.false_literal;130 pub const last_no_payload_tag = Tag.false_literal;
112 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;131 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -127,6 +146,14 @@ pub const Node = extern union {...@@ -127,6 +146,14 @@ pub const Node = extern union {
127 .@"return",146 .@"return",
128 .discard,147 .discard,
129 .std_math_Log2Int,148 .std_math_Log2Int,
149 .negate,
150 .negate_wrap,
151 .bit_not,
152 .not,
153 .optional_type,
154 .c_pointer,
155 .single_pointer,
156 .array_type,
130 => Payload.UnOp,157 => Payload.UnOp,
131158
132 .add,159 .add,
...@@ -180,6 +207,7 @@ pub const Node = extern union {...@@ -180,6 +207,7 @@ pub const Node = extern union {
180 .div_trunc,207 .div_trunc,
181 .rem,208 .rem,
182 .int_cast,209 .int_cast,
210 .bool_to_int,
183 => Payload.BinOp,211 => Payload.BinOp,
184212
185 .int,213 .int,
...@@ -191,6 +219,9 @@ pub const Node = extern union {...@@ -191,6 +219,9 @@ pub const Node = extern union {
191 .field_access_arrow,219 .field_access_arrow,
192 .warning,220 .warning,
193 .failed_decl,221 .failed_decl,
222 .sizeof,
223 .alignof,
224 .type,
194 => Payload.Value,225 => Payload.Value,
195 .@"if" => Payload.If,226 .@"if" => Payload.If,
196 .@"while" => Payload.While,227 .@"while" => Payload.While,
...@@ -234,8 +265,8 @@ pub const Payload = struct {...@@ -234,8 +265,8 @@ pub const Payload = struct {
234 pub const Infix = struct {265 pub const Infix = struct {
235 base: Node,266 base: Node,
236 data: struct {267 data: struct {
237 lhs: *Node,268 lhs: Node,
238 rhs: *Node,269 rhs: Node,
239 },270 },
240 };271 };
241272
...@@ -246,44 +277,44 @@ pub const Payload = struct {...@@ -246,44 +277,44 @@ pub const Payload = struct {
246277
247 pub const UnOp = struct {278 pub const UnOp = struct {
248 base: Node,279 base: Node,
249 data: *Node,280 data: Node,
250 };281 };
251282
252 pub const BinOp = struct {283 pub const BinOp = struct {
253 base: Node,284 base: Node,
254 data: struct {285 data: struct {
255 lhs: *Node,286 lhs: Node,
256 rhs: *Node,287 rhs: Node,
257 },288 },
258 };289 };
259290
260 pub const If = struct {291 pub const If = struct {
261 base: Node = .{ .tag = .@"if" },292 base: Node = .{ .tag = .@"if" },
262 data: struct {293 data: struct {
263 cond: *Node,294 cond: Node,
264 then: *Node,295 then: Node,
265 @"else": ?*Node,296 @"else": ?Node,
266 },297 },
267 };298 };
268299
269 pub const While = struct {300 pub const While = struct {
270 base: Node = .{ .tag = .@"while" },301 base: Node = .{ .tag = .@"while" },
271 data: struct {302 data: struct {
272 cond: *Node,303 cond: Node,
273 body: *Node,304 body: Node,
274 },305 },
275 };306 };
276307
277 pub const Switch = struct {308 pub const Switch = struct {
278 base: Node = .{ .tag = .@"switch" },309 base: Node = .{ .tag = .@"switch" },
279 data: struct {310 data: struct {
280 cond: *Node,311 cond: Node,
281 cases: []Prong,312 cases: []Prong,
282 default: ?[]const u8,313 default: ?[]const u8,
283314
284 pub const Prong = struct {315 pub const Prong = struct {
285 lhs: *Node,316 lhs: Node,
286 rhs: ?*Node,317 rhs: ?Node,
287 label: []const u8,318 label: []const u8,
288 };319 };
289 },320 },
...@@ -293,15 +324,15 @@ pub const Payload = struct {...@@ -293,15 +324,15 @@ pub const Payload = struct {
293 base: Node = .{ .tag = .@"break" },324 base: Node = .{ .tag = .@"break" },
294 data: struct {325 data: struct {
295 label: ?[]const u8,326 label: ?[]const u8,
296 rhs: ?*Node,327 rhs: ?Node,
297 },328 },
298 };329 };
299330
300 pub const Call = struct {331 pub const Call = struct {
301 base: Node = .{.call},332 base: Node = .{.call},
302 data: struct {333 data: struct {
303 lhs: *Node,334 lhs: Node,
304 args: []*Node,335 args: []Node,
305 },336 },
306 };337 };
307338
...@@ -314,7 +345,7 @@ pub const Payload = struct {...@@ -314,7 +345,7 @@ pub const Payload = struct {
314 @"export": bool,345 @"export": bool,
315 name: []const u8,346 name: []const u8,
316 type: Type,347 type: Type,
317 init: *Node,348 init: Node,
318 },349 },
319 };350 };
320351
...@@ -328,7 +359,7 @@ pub const Payload = struct {...@@ -328,7 +359,7 @@ pub const Payload = struct {
328 cc: std.builtin.CallingConvention,359 cc: std.builtin.CallingConvention,
329 params: []Param,360 params: []Param,
330 return_type: Type,361 return_type: Type,
331 body: ?*Node,362 body: ?Node,
332363
333 pub const Param = struct {364 pub const Param = struct {
334 @"noalias": bool,365 @"noalias": bool,
...@@ -368,7 +399,7 @@ pub const Payload = struct {...@@ -368,7 +399,7 @@ pub const Payload = struct {
368399
369 pub const ArrayInit = struct {400 pub const ArrayInit = struct {
370 base: Node = .{ .tag = .array_init },401 base: Node = .{ .tag = .array_init },
371 data: []*Node,402 data: []Node,
372 };403 };
373404
374 pub const ContainerInit = struct {405 pub const ContainerInit = struct {
...@@ -377,17 +408,22 @@ pub const Payload = struct {...@@ -377,17 +408,22 @@ pub const Payload = struct {
377408
378 pub const Initializer = struct {409 pub const Initializer = struct {
379 name: []const u8,410 name: []const u8,
380 value: *Node,411 value: Node,
381 };412 };
382 };413 };
383414
384 pub const Block = struct {415 pub const Block = struct {
385 base: Node = .{ .tag = .block },416 base: Node,
386 data: struct {417 data: struct {
387 label: ?[]const u8,418 label: ?[]const u8,
388 stmts: []*Node,419 stmts: []Node
389 },420 },
390 };421 };
422
423 pub const Break = struct {
424 base: Node = .{ .tag = .@"break" },
425 data: *Block
426 };
391};427};
392428
393/// Converts the nodes into a Zig ast and then renders it.429/// Converts the nodes into a Zig ast and then renders it.