| ... | ... | @@ -68,16 +68,15 @@ const Scope = struct { |
| 68 | 68 | } |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | | /// Represents an in-progress ast.Node.Block. This struct is stack-allocated. |
| 72 | | /// When it is deinitialized, it produces an ast.Node.Block which is allocated |
| 71 | /// Represents an in-progress Node.Block. This struct is stack-allocated. |
| 72 | /// When it is deinitialized, it produces an Node.Block which is allocated |
| 73 | 73 | /// into the main arena. |
| 74 | 74 | const Block = struct { |
| 75 | 75 | base: Scope, |
| 76 | | statements: std.ArrayList(*ast.Node), |
| 76 | statements: std.ArrayList(Node), |
| 77 | 77 | variables: AliasList, |
| 78 | | label: ?ast.TokenIndex, |
| 79 | 78 | mangle_count: u32 = 0, |
| 80 | | lbrace: ast.TokenIndex, |
| 79 | label: ?[]const u8 = null, |
| 81 | 80 | |
| 82 | 81 | /// When the block corresponds to a function, keep track of the return type |
| 83 | 82 | /// so that the return expression can be cast, if necessary |
| ... | ... | @@ -89,14 +88,11 @@ const Scope = struct { |
| 89 | 88 | .id = .Block, |
| 90 | 89 | .parent = parent, |
| 91 | 90 | }, |
| 92 | | .statements = std.ArrayList(*ast.Node).init(c.gpa), |
| 91 | .statements = std.ArrayList(Node).init(c.gpa), |
| 93 | 92 | .variables = AliasList.init(c.gpa), |
| 94 | | .label = null, |
| 95 | | .lbrace = try appendToken(c, .LBrace, "{"), |
| 96 | 93 | }; |
| 97 | 94 | if (labeled) { |
| 98 | | blk.label = try appendIdentifier(c, try blk.makeMangledName(c, "blk")); |
| 99 | | _ = try appendToken(c, .Colon, ":"); |
| 95 | blk.label = try blk.makeMangledName(c, "blk"); |
| 100 | 96 | } |
| 101 | 97 | return blk; |
| 102 | 98 | } |
| ... | ... | @@ -107,31 +103,16 @@ const Scope = struct { |
| 107 | 103 | self.* = undefined; |
| 108 | 104 | } |
| 109 | 105 | |
| 110 | | fn complete(self: *Block, c: *Context) !*ast.Node { |
| 106 | fn complete(self: *Block, c: *Context) !Node { |
| 111 | 107 | // We reserve 1 extra statement if the parent is a Loop. This is in case of |
| 112 | 108 | // do while, we want to put `if (cond) break;` at the end. |
| 113 | 109 | const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop); |
| 114 | | const rbrace = try appendToken(c, .RBrace, "}"); |
| 115 | | if (self.label) |label| { |
| 116 | | const node = try ast.Node.LabeledBlock.alloc(c.arena, alloc_len); |
| 117 | | node.* = .{ |
| 118 | | .statements_len = self.statements.items.len, |
| 119 | | .lbrace = self.lbrace, |
| 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 | | } |
| 110 | const stmts = try c.arena.alloc(Node, alloc_len); |
| 111 | mem.copy(Node, stmts, self.statements.items); |
| 112 | return Node.block.create(c.arena, .{ |
| 113 | .lable = self.label, |
| 114 | .stmts = stmts, |
| 115 | }); |
| 135 | 116 | } |
| 136 | 117 | |
| 137 | 118 | /// Given the desired name, return a name that does not shadow anything from outer scopes. |
| ... | ... | @@ -1390,7 +1371,7 @@ fn transBinaryOperator( |
| 1390 | 1371 | // signed integer division uses @divTrunc |
| 1391 | 1372 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); |
| 1392 | 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 | 1375 | return maybeSuppressResult(c, scope, result_used, div_trunc); |
| 1395 | 1376 | } |
| 1396 | 1377 | }, |
| ... | ... | @@ -1399,7 +1380,7 @@ fn transBinaryOperator( |
| 1399 | 1380 | // signed integer division uses @rem |
| 1400 | 1381 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); |
| 1401 | 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 | 1384 | return maybeSuppressResult(c, scope, result_used, rem); |
| 1404 | 1385 | } |
| 1405 | 1386 | }, |
| ... | ... | @@ -1411,6 +1392,12 @@ fn transBinaryOperator( |
| 1411 | 1392 | const node = try transCreateNodeShiftOp(c, scope, stmt, .shr); |
| 1412 | 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 | 1401 | else => {}, |
| 1415 | 1402 | } |
| 1416 | 1403 | var op_id: Node.Tag = undefined; |
| ... | ... | @@ -1471,17 +1458,19 @@ fn transBinaryOperator( |
| 1471 | 1458 | .Or => { |
| 1472 | 1459 | op_id = .bit_or; |
| 1473 | 1460 | }, |
| 1474 | | .LAnd => { |
| 1475 | | op_id = .@"and"; |
| 1476 | | }, |
| 1477 | | .LOr => { |
| 1478 | | op_id = .@"or"; |
| 1479 | | }, |
| 1480 | 1461 | else => unreachable, |
| 1481 | 1462 | } |
| 1482 | 1463 | |
| 1483 | | const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); |
| 1484 | | const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); |
| 1464 | const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_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; |
| 1485 | 1474 | |
| 1486 | 1475 | const payload = try c.arena.create(ast.Payload.BinOp); |
| 1487 | 1476 | payload.* = .{ |
| ... | ... | @@ -1495,7 +1484,7 @@ fn transBinaryOperator( |
| 1495 | 1484 | } |
| 1496 | 1485 | |
| 1497 | 1486 | fn transCompoundStmtInline( |
| 1498 | | rp: RestorePoint, |
| 1487 | c: *Context, |
| 1499 | 1488 | parent_scope: *Scope, |
| 1500 | 1489 | stmt: *const clang.CompoundStmt, |
| 1501 | 1490 | block: *Scope.Block, |
| ... | ... | @@ -1503,16 +1492,16 @@ fn transCompoundStmtInline( |
| 1503 | 1492 | var it = stmt.body_begin(); |
| 1504 | 1493 | const end_it = stmt.body_end(); |
| 1505 | 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 | 1496 | try block.statements.append(result); |
| 1508 | 1497 | } |
| 1509 | 1498 | } |
| 1510 | 1499 | |
| 1511 | | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!*ast.Node { |
| 1512 | | var block_scope = try Scope.Block.init(rp.c, scope, false); |
| 1500 | fn transCompoundStmt(c: *Context, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!Node { |
| 1501 | var block_scope = try Scope.Block.init(c, scope, false); |
| 1513 | 1502 | defer block_scope.deinit(); |
| 1514 | | try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope); |
| 1515 | | return try block_scope.complete(rp.c); |
| 1503 | try transCompoundStmtInline(c, &block_scope.base, stmt, &block_scope); |
| 1504 | return try block_scope.complete(c); |
| 1516 | 1505 | } |
| 1517 | 1506 | |
| 1518 | 1507 | fn transCStyleCastExprClass( |
| ... | ... | @@ -3233,22 +3222,18 @@ fn qualTypeGetFnProto(qt: clang.QualType, is_ptr: *bool) ?ClangFunctionType { |
| 3233 | 3222 | } |
| 3234 | 3223 | |
| 3235 | 3224 | fn transUnaryExprOrTypeTraitExpr( |
| 3236 | | rp: RestorePoint, |
| 3225 | c: *Context, |
| 3237 | 3226 | scope: *Scope, |
| 3238 | 3227 | stmt: *const clang.UnaryExprOrTypeTraitExpr, |
| 3239 | 3228 | result_used: ResultUsed, |
| 3240 | | ) TransError!*ast.Node { |
| 3229 | ) TransError!Node { |
| 3241 | 3230 | const loc = stmt.getBeginLoc(); |
| 3242 | | const type_node = try transQualType( |
| 3243 | | rp, |
| 3244 | | stmt.getTypeOfArgument(), |
| 3245 | | loc, |
| 3246 | | ); |
| 3231 | const type_node = try transQualType(rp, stmt.getTypeOfArgument(), loc); |
| 3247 | 3232 | |
| 3248 | 3233 | const kind = stmt.getKind(); |
| 3249 | | const kind_str = switch (kind) { |
| 3250 | | .SizeOf => "@sizeOf", |
| 3251 | | .AlignOf => "@alignOf", |
| 3234 | switch (kind) { |
| 3235 | .SizeOf => return Node.sizeof.create(c.arena, type_node), |
| 3236 | .AlignOf => return Node.alignof.create(c.arena, type_node), |
| 3252 | 3237 | .PreferredAlignOf, |
| 3253 | 3238 | .VecStep, |
| 3254 | 3239 | .OpenMPRequiredSimdAlign, |
| ... | ... | @@ -3259,12 +3244,7 @@ fn transUnaryExprOrTypeTraitExpr( |
| 3259 | 3244 | "Unsupported type trait kind {}", |
| 3260 | 3245 | .{kind}, |
| 3261 | 3246 | ), |
| 3262 | | }; |
| 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); |
| 3247 | } |
| 3268 | 3248 | } |
| 3269 | 3249 | |
| 3270 | 3250 | fn qualTypeHasWrappingOverflow(qt: clang.QualType) bool { |
| ... | ... | @@ -3967,8 +3947,8 @@ fn transQualTypeInitialized( |
| 3967 | 3947 | return transQualType(rp, qt, source_loc); |
| 3968 | 3948 | } |
| 3969 | 3949 | |
| 3970 | | fn transQualType(rp: RestorePoint, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!*ast.Node { |
| 3971 | | return transType(rp, qt.getTypePtr(), source_loc); |
| 3950 | fn transQualType(c: *Context, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!Node { |
| 3951 | return transType(c, qt.getTypePtr(), source_loc); |
| 3972 | 3952 | } |
| 3973 | 3953 | |
| 3974 | 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 | 4298 | return &field_access_node.base; |
| 4319 | 4299 | } |
| 4320 | 4300 | |
| 4321 | | fn transCreateNodeSimplePrefixOp( |
| 4301 | fn transCreateNodeBoolInfixOp( |
| 4322 | 4302 | c: *Context, |
| 4323 | | comptime tag: ast.Node.Tag, |
| 4324 | | op_tok_id: std.zig.Token.Id, |
| 4325 | | bytes: []const u8, |
| 4326 | | ) !*ast.Node.SimplePrefixOp { |
| 4327 | | const node = try c.arena.create(ast.Node.SimplePrefixOp); |
| 4328 | | node.* = .{ |
| 4329 | | .base = .{ .tag = tag }, |
| 4330 | | .op_token = try appendToken(c, op_tok_id, bytes), |
| 4331 | | .rhs = undefined, // translate and set afterward |
| 4303 | scope: *Scope, |
| 4304 | stmt: *const clang.BinaryOperator, |
| 4305 | op: ast.Node.Tag, |
| 4306 | used: ResultUsed, |
| 4307 | ) !Node { |
| 4308 | std.debug.assert(op == .bool_and or op == .bool_or); |
| 4309 | |
| 4310 | const lhs = try transBoolExpr(rp, scope, stmt.getLHS(), .used, .l_value, true); |
| 4311 | 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 | } |
| 4335 | 4323 | |
| 4336 | 4324 | fn transCreateNodePtrType( |
| ... | ... | @@ -4784,30 +4772,30 @@ fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.ArrayAcces |
| 4784 | 4772 | return node; |
| 4785 | 4773 | } |
| 4786 | 4774 | |
| 4787 | | fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type { |
| 4775 | fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Node { |
| 4788 | 4776 | switch (ty.getTypeClass()) { |
| 4789 | 4777 | .Builtin => { |
| 4790 | 4778 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| 4791 | | return Type.initTag(switch (builtin_ty.getKind()) { |
| 4792 | | .Void => .c_void, |
| 4793 | | .Bool => .bool, |
| 4794 | | .Char_U, .UChar, .Char_S, .Char8 => .u8, |
| 4795 | | .SChar => .i8, |
| 4796 | | .UShort => .c_ushort, |
| 4797 | | .UInt => .c_uint, |
| 4798 | | .ULong => .c_ulong, |
| 4799 | | .ULongLong => .c_ulonglong, |
| 4800 | | .Short => .c_short, |
| 4801 | | .Int => .c_int, |
| 4802 | | .Long => .c_long, |
| 4803 | | .LongLong => .c_longlong, |
| 4804 | | .UInt128 => .u128, |
| 4805 | | .Int128 => .i128, |
| 4806 | | .Float => .f32, |
| 4807 | | .Double => .f64, |
| 4808 | | .Float128 => .f128, |
| 4809 | | .Float16 => .f16, |
| 4810 | | .LongDouble => .c_longdouble, |
| 4779 | return Node.type.create(c.arena, switch (builtin_ty.getKind()) { |
| 4780 | .Void => "c_void", |
| 4781 | .Bool => "bool", |
| 4782 | .Char_U, .UChar, .Char_S, .Char8 => "u8", |
| 4783 | .SChar => "i8", |
| 4784 | .UShort => "c_ushort", |
| 4785 | .UInt => "c_uint", |
| 4786 | .ULong => "c_ulong", |
| 4787 | .ULongLong => "c_ulonglong", |
| 4788 | .Short => "c_short", |
| 4789 | .Int => "c_int", |
| 4790 | .Long => "c_long", |
| 4791 | .LongLong => "c_longlong", |
| 4792 | .UInt128 => "u128", |
| 4793 | .Int128 => "i128", |
| 4794 | .Float => "f32", |
| 4795 | .Double => "f64", |
| 4796 | .Float128 => "f128", |
| 4797 | .Float16 => "f16", |
| 4798 | .LongDouble => "c_longdouble", |
| 4811 | 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 | 4814 | .Pointer => { |
| 4827 | 4815 | const child_qt = ty.getPointeeType(); |
| 4828 | 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 | 4819 | const is_const = child_qt.isConstQualified(); |
| 4832 | 4820 | const is_volatile = child_qt.isVolatileQualified(); |
| 4833 | 4821 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 4834 | | if (elem_type.zigTypeTag() == .Opaque) { |
| 4835 | | if (!is_volatile) { |
| 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 | | }); |
| 4822 | if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) { |
| 4823 | return Node.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 4854 | 4824 | } |
| 4855 | 4825 | |
| 4856 | | if (!is_volatile) { |
| 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 | | }); |
| 4826 | return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 4875 | 4827 | }, |
| 4876 | 4828 | .ConstantArray => { |
| 4877 | 4829 | const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty); |
| 4878 | 4830 | |
| 4879 | 4831 | const size_ap_int = const_arr_ty.getSize(); |
| 4880 | 4832 | const size = size_ap_int.getLimitedValue(math.maxInt(usize)); |
| 4881 | | const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc); |
| 4882 | | |
| 4883 | | return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type }); |
| 4833 | const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc); |
| 4834 | |
| 4835 | return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type }); |
| 4884 | 4836 | }, |
| 4885 | 4837 | .IncompleteArray => { |
| 4886 | 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 | 4842 | const is_volatile = child_qt.isVolatileQualified(); |
| 4891 | 4843 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 4892 | 4844 | |
| 4893 | | if (!is_volatile) { |
| 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 | | }); |
| 4845 | return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 4912 | 4846 | }, |
| 4913 | 4847 | .Typedef => { |
| 4914 | 4848 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| ... | ... | @@ -5233,25 +5167,14 @@ fn finishTransFnProto( |
| 5233 | 5167 | return fn_proto; |
| 5234 | 5168 | } |
| 5235 | 5169 | |
| 5236 | | fn revertAndWarn( |
| 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 | | |
| 5248 | | fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { |
| 5170 | fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { |
| 5249 | 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 | } |
| 5252 | 5175 | |
| 5253 | 5176 | fn fail( |
| 5254 | | rp: RestorePoint, |
| 5177 | c: *Context, |
| 5255 | 5178 | err: anytype, |
| 5256 | 5179 | source_loc: clang.SourceLocation, |
| 5257 | 5180 | comptime format: []const u8, |