| ... | @@ -10,12 +10,13 @@ const mem = std.mem; | ... | @@ -10,12 +10,13 @@ const mem = std.mem; |
| 10 | const math = std.math; | 10 | const math = std.math; |
| 11 | const ast = @import("translate_c/ast.zig"); | 11 | const ast = @import("translate_c/ast.zig"); |
| 12 | const Node = ast.Node; | 12 | const Node = ast.Node; |
| | 13 | const Tag = Node.Tag; |
| 13 | | 14 | |
| 14 | const CallingConvention = std.builtin.CallingConvention; | 15 | const CallingConvention = std.builtin.CallingConvention; |
| 15 | | 16 | |
| 16 | pub const ClangErrMsg = clang.Stage2ErrorMsg; | 17 | pub const ClangErrMsg = clang.Stage2ErrorMsg; |
| 17 | | 18 | |
| 18 | pub const Error = error{OutOfMemory}; | 19 | pub const Error = std.mem.Allocator.Error; |
| 19 | const TypeError = Error || error{UnsupportedType}; | 20 | const TypeError = Error || error{UnsupportedType}; |
| 20 | const TransError = TypeError || error{UnsupportedTranslation}; | 21 | const TransError = TypeError || error{UnsupportedTranslation}; |
| 21 | | 22 | |
| ... | @@ -30,11 +31,11 @@ const Scope = struct { | ... | @@ -30,11 +31,11 @@ const Scope = struct { |
| 30 | parent: ?*Scope, | 31 | parent: ?*Scope, |
| 31 | | 32 | |
| 32 | const Id = enum { | 33 | const Id = enum { |
| 33 | Switch, | 34 | @"switch", |
| 34 | Block, | 35 | block, |
| 35 | Root, | 36 | root, |
| 36 | Condition, | 37 | condition, |
| 37 | Loop, | 38 | loop, |
| 38 | }; | 39 | }; |
| 39 | | 40 | |
| 40 | /// Represents an in-progress Node.Switch. This struct is stack-allocated. | 41 | /// Represents an in-progress Node.Switch. This struct is stack-allocated. |
| ... | @@ -44,7 +45,6 @@ const Scope = struct { | ... | @@ -44,7 +45,6 @@ const Scope = struct { |
| 44 | base: Scope, | 45 | base: Scope, |
| 45 | pending_block: Block, | 46 | pending_block: Block, |
| 46 | cases: std.ArrayList(Node), | 47 | cases: std.ArrayList(Node), |
| 47 | case_index: usize, | | |
| 48 | switch_label: ?[]const u8, | 48 | switch_label: ?[]const u8, |
| 49 | default_label: ?[]const u8, | 49 | default_label: ?[]const u8, |
| 50 | }; | 50 | }; |
| ... | @@ -84,7 +84,7 @@ const Scope = struct { | ... | @@ -84,7 +84,7 @@ const Scope = struct { |
| 84 | fn init(c: *Context, parent: *Scope, labeled: bool) !Block { | 84 | fn init(c: *Context, parent: *Scope, labeled: bool) !Block { |
| 85 | var blk = Block{ | 85 | var blk = Block{ |
| 86 | .base = .{ | 86 | .base = .{ |
| 87 | .id = .Block, | 87 | .id = .block, |
| 88 | .parent = parent, | 88 | .parent = parent, |
| 89 | }, | 89 | }, |
| 90 | .statements = std.ArrayList(Node).init(c.gpa), | 90 | .statements = std.ArrayList(Node).init(c.gpa), |
| ... | @@ -105,12 +105,12 @@ const Scope = struct { | ... | @@ -105,12 +105,12 @@ const Scope = struct { |
| 105 | fn complete(self: *Block, c: *Context) !Node { | 105 | fn complete(self: *Block, c: *Context) !Node { |
| 106 | // We reserve 1 extra statement if the parent is a Loop. This is in case of | 106 | // We reserve 1 extra statement if the parent is a Loop. This is in case of |
| 107 | // do while, we want to put `if (cond) break;` at the end. | 107 | // do while, we want to put `if (cond) break;` at the end. |
| 108 | const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop); | 108 | const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .loop); |
| 109 | const stmts = try c.arena.alloc(Node, alloc_len); | 109 | var stmts = try c.arena.alloc(Node, alloc_len); |
| 110 | stmts.len -= 1; | 110 | stmts.len -= 1; |
| 111 | mem.copy(Node, stmts, self.statements.items); | 111 | mem.copy(Node, stmts, self.statements.items); |
| 112 | return Node.block.create(c.arena, .{ | 112 | return Tag.block.create(c.arena, .{ |
| 113 | .lable = self.label, | 113 | .label = self.label, |
| 114 | .stmts = stmts, | 114 | .stmts = stmts, |
| 115 | }); | 115 | }); |
| 116 | } | 116 | } |
| ... | @@ -161,7 +161,7 @@ const Scope = struct { | ... | @@ -161,7 +161,7 @@ const Scope = struct { |
| 161 | fn init(c: *Context) Root { | 161 | fn init(c: *Context) Root { |
| 162 | return .{ | 162 | return .{ |
| 163 | .base = .{ | 163 | .base = .{ |
| 164 | .id = .Root, | 164 | .id = .root, |
| 165 | .parent = null, | 165 | .parent = null, |
| 166 | }, | 166 | }, |
| 167 | .sym_table = SymbolTable.init(c.gpa), | 167 | .sym_table = SymbolTable.init(c.gpa), |
| ... | @@ -195,9 +195,9 @@ const Scope = struct { | ... | @@ -195,9 +195,9 @@ const Scope = struct { |
| 195 | var scope = inner; | 195 | var scope = inner; |
| 196 | while (true) { | 196 | while (true) { |
| 197 | switch (scope.id) { | 197 | switch (scope.id) { |
| 198 | .Root => unreachable, | 198 | .root => unreachable, |
| 199 | .Block => return @fieldParentPtr(Block, "base", scope), | 199 | .block => return @fieldParentPtr(Block, "base", scope), |
| 200 | .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c), | 200 | .condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c), |
| 201 | else => scope = scope.parent.?, | 201 | else => scope = scope.parent.?, |
| 202 | } | 202 | } |
| 203 | } | 203 | } |
| ... | @@ -207,8 +207,8 @@ const Scope = struct { | ... | @@ -207,8 +207,8 @@ const Scope = struct { |
| 207 | var scope = inner; | 207 | var scope = inner; |
| 208 | while (true) { | 208 | while (true) { |
| 209 | switch (scope.id) { | 209 | switch (scope.id) { |
| 210 | .Root => unreachable, | 210 | .root => unreachable, |
| 211 | .Block => { | 211 | .block => { |
| 212 | const block = @fieldParentPtr(Block, "base", scope); | 212 | const block = @fieldParentPtr(Block, "base", scope); |
| 213 | if (block.return_type) |qt| return qt; | 213 | if (block.return_type) |qt| return qt; |
| 214 | scope = scope.parent.?; | 214 | scope = scope.parent.?; |
| ... | @@ -220,17 +220,17 @@ const Scope = struct { | ... | @@ -220,17 +220,17 @@ const Scope = struct { |
| 220 | | 220 | |
| 221 | fn getAlias(scope: *Scope, name: []const u8) []const u8 { | 221 | fn getAlias(scope: *Scope, name: []const u8) []const u8 { |
| 222 | return switch (scope.id) { | 222 | return switch (scope.id) { |
| 223 | .Root => return name, | 223 | .root => return name, |
| 224 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), | 224 | .block => @fieldParentPtr(Block, "base", scope).getAlias(name), |
| 225 | .Switch, .Loop, .Condition => scope.parent.?.getAlias(name), | 225 | .@"switch", .loop, .condition => scope.parent.?.getAlias(name), |
| 226 | }; | 226 | }; |
| 227 | } | 227 | } |
| 228 | | 228 | |
| 229 | fn contains(scope: *Scope, name: []const u8) bool { | 229 | fn contains(scope: *Scope, name: []const u8) bool { |
| 230 | return switch (scope.id) { | 230 | return switch (scope.id) { |
| 231 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), | 231 | .root => @fieldParentPtr(Root, "base", scope).contains(name), |
| 232 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), | 232 | .block => @fieldParentPtr(Block, "base", scope).contains(name), |
| 233 | .Switch, .Loop, .Condition => scope.parent.?.contains(name), | 233 | .@"switch", .loop, .condition => scope.parent.?.contains(name), |
| 234 | }; | 234 | }; |
| 235 | } | 235 | } |
| 236 | | 236 | |
| ... | @@ -238,9 +238,9 @@ const Scope = struct { | ... | @@ -238,9 +238,9 @@ const Scope = struct { |
| 238 | var scope = inner; | 238 | var scope = inner; |
| 239 | while (true) { | 239 | while (true) { |
| 240 | switch (scope.id) { | 240 | switch (scope.id) { |
| 241 | .Root => unreachable, | 241 | .root => unreachable, |
| 242 | .Switch => return scope, | 242 | .@"switch" => return scope, |
| 243 | .Loop => return scope, | 243 | .loop => return scope, |
| 244 | else => scope = scope.parent.?, | 244 | else => scope = scope.parent.?, |
| 245 | } | 245 | } |
| 246 | } | 246 | } |
| ... | @@ -250,24 +250,24 @@ const Scope = struct { | ... | @@ -250,24 +250,24 @@ const Scope = struct { |
| 250 | var scope = inner; | 250 | var scope = inner; |
| 251 | while (true) { | 251 | while (true) { |
| 252 | switch (scope.id) { | 252 | switch (scope.id) { |
| 253 | .Root => unreachable, | 253 | .root => unreachable, |
| 254 | .Switch => return @fieldParentPtr(Switch, "base", scope), | 254 | .@"switch" => return @fieldParentPtr(Switch, "base", scope), |
| 255 | else => scope = scope.parent.?, | 255 | else => scope = scope.parent.?, |
| 256 | } | 256 | } |
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | | 259 | |
| 260 | /// Appends a node to the first block scope if inside a function, or to the root tree if not. | 260 | /// Appends a node to the first block scope if inside a function, or to the root tree if not. |
| 261 | fn appendNode(scope: *Scope, node: Node) !void { | 261 | fn appendNode(inner: *Scope, node: Node) !void { |
| 262 | var scope = inner; | 262 | var scope = inner; |
| 263 | while (true) { | 263 | while (true) { |
| 264 | switch (scope.id) { | 264 | switch (scope.id) { |
| 265 | .Root => { | 265 | .root => { |
| 266 | const root = @fieldParentPtr(Root, "base", scope).contains(name); | 266 | const root = @fieldParentPtr(Root, "base", scope); |
| 267 | return root.nodes.append(node); | 267 | return root.nodes.append(node); |
| 268 | }, | 268 | }, |
| 269 | .Block => { | 269 | .block => { |
| 270 | const block = @fieldParentPtr(Block, "base", scope).contains(name); | 270 | const block = @fieldParentPtr(Block, "base", scope); |
| 271 | return block.statements.append(node); | 271 | return block.statements.append(node); |
| 272 | }, | 272 | }, |
| 273 | else => scope = scope.parent.?, | 273 | else => scope = scope.parent.?, |
| ... | @@ -321,7 +321,7 @@ pub fn translate( | ... | @@ -321,7 +321,7 @@ pub fn translate( |
| 321 | args_end: [*]?[*]const u8, | 321 | args_end: [*]?[*]const u8, |
| 322 | errors: *[]ClangErrMsg, | 322 | errors: *[]ClangErrMsg, |
| 323 | resources_path: [*:0]const u8, | 323 | resources_path: [*:0]const u8, |
| 324 | ) !ast.Tree { | 324 | ) !std.zig.ast.Tree { |
| 325 | const ast_unit = clang.LoadFromCommandLine( | 325 | const ast_unit = clang.LoadFromCommandLine( |
| 326 | args_begin, | 326 | args_begin, |
| 327 | args_end, | 327 | args_end, |
| ... | @@ -339,14 +339,6 @@ pub fn translate( | ... | @@ -339,14 +339,6 @@ pub fn translate( |
| 339 | var arena = std.heap.ArenaAllocator.init(gpa); | 339 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 340 | errdefer arena.deinit(); | 340 | errdefer arena.deinit(); |
| 341 | | 341 | |
| 342 | if (true) { | | |
| 343 | var x = false; | | |
| 344 | if (x) { | | |
| 345 | return error.OutOfMemory; | | |
| 346 | } | | |
| 347 | @panic("TODO update translate-c"); | | |
| 348 | } | | |
| 349 | | | |
| 350 | var context = Context{ | 342 | var context = Context{ |
| 351 | .gpa = gpa, | 343 | .gpa = gpa, |
| 352 | .arena = &arena.allocator, | 344 | .arena = &arena.allocator, |
| ... | @@ -361,15 +353,15 @@ pub fn translate( | ... | @@ -361,15 +353,15 @@ pub fn translate( |
| 361 | context.alias_list.deinit(); | 353 | context.alias_list.deinit(); |
| 362 | context.global_names.deinit(gpa); | 354 | context.global_names.deinit(gpa); |
| 363 | context.opaque_demotes.deinit(gpa); | 355 | context.opaque_demotes.deinit(gpa); |
| 364 | context.global_scope.deini(); | 356 | context.global_scope.deinit(); |
| 365 | } | 357 | } |
| 366 | | 358 | |
| 367 | try context.global_scope.nodes.append(try Node.usingnamespace_builtins.init()); | 359 | try context.global_scope.nodes.append(Tag.usingnamespace_builtins.init()); |
| 368 | | 360 | |
| 369 | try prepopulateGlobalNameTable(ast_unit, &context); | 361 | try prepopulateGlobalNameTable(ast_unit, &context); |
| 370 | | 362 | |
| 371 | if (!ast_unit.visitLocalTopLevelDecls(&context, declVisitorC)) { | 363 | if (!ast_unit.visitLocalTopLevelDecls(&context, declVisitorC)) { |
| 372 | return context.err; | 364 | return error.OutOfMemory; |
| 373 | } | 365 | } |
| 374 | | 366 | |
| 375 | try transPreprocessorEntities(&context, ast_unit); | 367 | try transPreprocessorEntities(&context, ast_unit); |
| ... | @@ -377,16 +369,17 @@ pub fn translate( | ... | @@ -377,16 +369,17 @@ pub fn translate( |
| 377 | try addMacros(&context); | 369 | try addMacros(&context); |
| 378 | for (context.alias_list.items) |alias| { | 370 | for (context.alias_list.items) |alias| { |
| 379 | if (!context.global_scope.sym_table.contains(alias.alias)) { | 371 | if (!context.global_scope.sym_table.contains(alias.alias)) { |
| 380 | try createAlias(&context, alias); | 372 | const node = try Tag.alias.create(context.arena, .{ .actual = alias.alias, .mangled = alias.name }); |
| | 373 | try addTopLevelDecl(&context, alias.alias, node); |
| 381 | } | 374 | } |
| 382 | } | 375 | } |
| 383 | | 376 | |
| 384 | return ast.render(context.global_scope.nodes.items); | 377 | return ast.render(gpa, context.global_scope.nodes.items); |
| 385 | } | 378 | } |
| 386 | | 379 | |
| 387 | fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void { | 380 | fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void { |
| 388 | if (!ast_unit.visitLocalTopLevelDecls(c, declVisitorNamesOnlyC)) { | 381 | if (!ast_unit.visitLocalTopLevelDecls(c, declVisitorNamesOnlyC)) { |
| 389 | return c.err; | 382 | return error.OutOfMemory; |
| 390 | } | 383 | } |
| 391 | | 384 | |
| 392 | // TODO if we see #undef, delete it from the table | 385 | // TODO if we see #undef, delete it from the table |
| ... | @@ -409,19 +402,13 @@ fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void { | ... | @@ -409,19 +402,13 @@ fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void { |
| 409 | | 402 | |
| 410 | fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool { | 403 | fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool { |
| 411 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); | 404 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); |
| 412 | declVisitorNamesOnly(c, decl) catch |err| { | 405 | declVisitorNamesOnly(c, decl) catch return false; |
| 413 | c.err = err; | | |
| 414 | return false; | | |
| 415 | }; | | |
| 416 | return true; | 406 | return true; |
| 417 | } | 407 | } |
| 418 | | 408 | |
| 419 | fn declVisitorC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool { | 409 | fn declVisitorC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool { |
| 420 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); | 410 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); |
| 421 | declVisitor(c, decl) catch |err| { | 411 | declVisitor(c, decl) catch return false; |
| 422 | c.err = err; | | |
| 423 | return false; | | |
| 424 | }; | | |
| 425 | return true; | 412 | return true; |
| 426 | } | 413 | } |
| 427 | | 414 | |
| ... | @@ -454,7 +441,7 @@ fn declVisitor(c: *Context, decl: *const clang.Decl) Error!void { | ... | @@ -454,7 +441,7 @@ fn declVisitor(c: *Context, decl: *const clang.Decl) Error!void { |
| 454 | }, | 441 | }, |
| 455 | else => { | 442 | else => { |
| 456 | const decl_name = try c.str(decl.getDeclKindName()); | 443 | const decl_name = try c.str(decl.getDeclKindName()); |
| 457 | try warn(c, decl.getLocation(), "ignoring {s} declaration", .{decl_name}); | 444 | try warn(c, &c.global_scope.base, decl.getLocation(), "ignoring {s} declaration", .{decl_name}); |
| 458 | }, | 445 | }, |
| 459 | } | 446 | } |
| 460 | } | 447 | } |
| ... | @@ -513,7 +500,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -513,7 +500,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 513 | decl_ctx.has_body = false; | 500 | decl_ctx.has_body = false; |
| 514 | decl_ctx.storage_class = .Extern; | 501 | decl_ctx.storage_class = .Extern; |
| 515 | decl_ctx.is_export = false; | 502 | decl_ctx.is_export = false; |
| 516 | try warn(c, fn_decl_loc, "TODO unable to translate variadic function, demoted to declaration", .{}); | 503 | try warn(c, &c.global_scope.base, fn_decl_loc, "TODO unable to translate variadic function, demoted to declaration", .{}); |
| 517 | } | 504 | } |
| 518 | break :blk transFnProto(c, fn_decl, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { | 505 | break :blk transFnProto(c, fn_decl, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { |
| 519 | error.UnsupportedType => { | 506 | error.UnsupportedType => { |
| ... | @@ -535,7 +522,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -535,7 +522,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 535 | }; | 522 | }; |
| 536 | | 523 | |
| 537 | if (!decl_ctx.has_body) { | 524 | if (!decl_ctx.has_body) { |
| 538 | return addTopLevelDecl(c, fn_name, &proto_node.base); | 525 | return addTopLevelDecl(c, fn_name, Node.initPayload(&proto_node.base)); |
| 539 | } | 526 | } |
| 540 | | 527 | |
| 541 | // actual function definition with body | 528 | // actual function definition with body |
| ... | @@ -547,10 +534,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -547,10 +534,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 547 | var scope = &block_scope.base; | 534 | var scope = &block_scope.base; |
| 548 | | 535 | |
| 549 | var param_id: c_uint = 0; | 536 | var param_id: c_uint = 0; |
| 550 | for (proto_node.params()) |*param, i| { | 537 | for (proto_node.data.params) |*param, i| { |
| 551 | const param_name = if (param.name_token) |name_tok| | 538 | const param_name = param.name orelse |
| 552 | tokenSlice(c, name_tok) | | |
| 553 | else | | |
| 554 | return failDecl(c, fn_decl_loc, fn_name, "function {s} parameter has no name", .{fn_name}); | 539 | return failDecl(c, fn_decl_loc, fn_name, "function {s} parameter has no name", .{fn_name}); |
| 555 | | 540 | |
| 556 | const c_param = fn_decl.getParamDecl(param_id); | 541 | const c_param = fn_decl.getParamDecl(param_id); |
| ... | @@ -565,7 +550,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -565,7 +550,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 565 | const arg_name = try block_scope.makeMangledName(c, bare_arg_name); | 550 | const arg_name = try block_scope.makeMangledName(c, bare_arg_name); |
| 566 | param.name = arg_name; | 551 | param.name = arg_name; |
| 567 | | 552 | |
| 568 | const redecl_node = try Node.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name }); | 553 | const redecl_node = try Tag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name }); |
| 569 | try block_scope.statements.append(redecl_node); | 554 | try block_scope.statements.append(redecl_node); |
| 570 | } | 555 | } |
| 571 | | 556 | |
| ... | @@ -607,12 +592,12 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { | ... | @@ -607,12 +592,12 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void { |
| 607 | error.UnsupportedType, | 592 | error.UnsupportedType, |
| 608 | => return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}), | 593 | => return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}), |
| 609 | }; | 594 | }; |
| 610 | const ret = try Node.@"return".create(c.arena, rhs); | 595 | const ret = try Tag.@"return".create(c.arena, rhs); |
| 611 | try block_scope.statements.append(ret); | 596 | try block_scope.statements.append(ret); |
| 612 | } | 597 | } |
| 613 | | 598 | |
| 614 | proto_node.body = try block_scope.complete(c); | 599 | proto_node.data.body = try block_scope.complete(c); |
| 615 | return addTopLevelDecl(c, fn_name, &proto_node.base); | 600 | return addTopLevelDecl(c, fn_name, Node.initPayload(&proto_node.base)); |
| 616 | } | 601 | } |
| 617 | | 602 | |
| 618 | fn transQualTypeMaybeInitialized(c: *Context, qt: clang.QualType, decl_init: ?*const clang.Expr, loc: clang.SourceLocation) TransError!Node { | 603 | fn transQualTypeMaybeInitialized(c: *Context, qt: clang.QualType, decl_init: ?*const clang.Expr, loc: clang.SourceLocation) TransError!Node { |
| ... | @@ -668,7 +653,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -668,7 +653,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 668 | const node_or_error = if (expr.getStmtClass() == .StringLiteralClass) | 653 | const node_or_error = if (expr.getStmtClass() == .StringLiteralClass) |
| 669 | transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), zigArraySize(c, type_node) catch 0) | 654 | transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), zigArraySize(c, type_node) catch 0) |
| 670 | else | 655 | else |
| 671 | transExprCoercing(c, scope, expr, .used, .r_value); | 656 | transExprCoercing(c, scope, expr, .used); |
| 672 | init_node = node_or_error catch |err| switch (err) { | 657 | init_node = node_or_error catch |err| switch (err) { |
| 673 | error.UnsupportedTranslation, | 658 | error.UnsupportedTranslation, |
| 674 | error.UnsupportedType, | 659 | error.UnsupportedType, |
| ... | @@ -677,18 +662,18 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -677,18 +662,18 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 677 | }, | 662 | }, |
| 678 | error.OutOfMemory => |e| return e, | 663 | error.OutOfMemory => |e| return e, |
| 679 | }; | 664 | }; |
| 680 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { | 665 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node.?)) { |
| 681 | init_node = try Node.bool_to_int.create(c.arena, init_node); | 666 | init_node = try Tag.bool_to_int.create(c.arena, init_node.?); |
| 682 | } | 667 | } |
| 683 | } else { | 668 | } else { |
| 684 | init_node = Node.undefined_literal.init(); | 669 | init_node = Tag.undefined_literal.init(); |
| 685 | } | 670 | } |
| 686 | } else if (storage_class != .Extern) { | 671 | } else if (storage_class != .Extern) { |
| 687 | // The C language specification states that variables with static or threadlocal | 672 | // The C language specification states that variables with static or threadlocal |
| 688 | // storage without an initializer are initialized to a zero value. | 673 | // storage without an initializer are initialized to a zero value. |
| 689 | | 674 | |
| 690 | // @import("std").mem.zeroes(T) | 675 | // @import("std").mem.zeroes(T) |
| 691 | init_node = try Node.std_mem_zeroes.create(c.arena, type_node); | 676 | init_node = try Tag.std_mem_zeroes.create(c.arena, type_node); |
| 692 | } | 677 | } |
| 693 | | 678 | |
| 694 | const linksection_string = blk: { | 679 | const linksection_string = blk: { |
| ... | @@ -708,7 +693,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -708,7 +693,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 708 | break :blk null; | 693 | break :blk null; |
| 709 | }; | 694 | }; |
| 710 | | 695 | |
| 711 | const node = try Node.var_decl.create(c.arena, .{ | 696 | const node = try Tag.var_decl.create(c.arena, .{ |
| 712 | .is_pub = is_pub, | 697 | .is_pub = is_pub, |
| 713 | .is_const = is_const, | 698 | .is_const = is_const, |
| 714 | .is_extern = is_extern, | 699 | .is_extern = is_extern, |
| ... | @@ -719,12 +704,12 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co | ... | @@ -719,12 +704,12 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co |
| 719 | .type = type_node, | 704 | .type = type_node, |
| 720 | .init = init_node, | 705 | .init = init_node, |
| 721 | }); | 706 | }); |
| 722 | return addTopLevelDecl(c, checked_name, &node.base); | 707 | return addTopLevelDecl(c, checked_name, node); |
| 723 | } | 708 | } |
| 724 | | 709 | |
| 725 | fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !Node { | 710 | fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !Node { |
| 726 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name); | 711 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name); |
| 727 | return Node.identifier.create(c.arena, builtin_name); | 712 | return Tag.identifier.create(c.arena, builtin_name); |
| 728 | } | 713 | } |
| 729 | | 714 | |
| 730 | const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{ | 715 | const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{ |
| ... | @@ -744,7 +729,7 @@ const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{ | ... | @@ -744,7 +729,7 @@ const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{ |
| 744 | | 729 | |
| 745 | fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_level_visit: bool) Error!?Node { | 730 | fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_level_visit: bool) Error!?Node { |
| 746 | if (c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl()))) |name| | 731 | if (c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl()))) |name| |
| 747 | return transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 732 | return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice |
| 748 | | 733 | |
| 749 | const typedef_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin()); | 734 | const typedef_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin()); |
| 750 | | 735 | |
| ... | @@ -753,17 +738,17 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev | ... | @@ -753,17 +738,17 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev |
| 753 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ typedef_name, c.getMangle() }) else typedef_name; | 738 | const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ typedef_name, c.getMangle() }) else typedef_name; |
| 754 | if (builtin_typedef_map.get(checked_name)) |builtin| { | 739 | if (builtin_typedef_map.get(checked_name)) |builtin| { |
| 755 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin); | 740 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin); |
| 756 | return Node.identifier.create(c.arena, builtin); | 741 | return try Tag.identifier.create(c.arena, builtin); |
| 757 | } | 742 | } |
| 758 | | 743 | |
| 759 | if (!top_level_visit) { | 744 | if (!top_level_visit) { |
| 760 | return transCreateNodeIdentifier(c, checked_name); | 745 | return try Tag.identifier.create(c.arena, checked_name); |
| 761 | } | 746 | } |
| 762 | | 747 | |
| 763 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name); | 748 | _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name); |
| 764 | const node = (try transCreateNodeTypedef(c, typedef_decl, true, checked_name)) orelse return null; | 749 | const node = (try transCreateNodeTypedef(c, typedef_decl, true, checked_name)) orelse return null; |
| 765 | try addTopLevelDecl(c, checked_name, node); | 750 | try addTopLevelDecl(c, checked_name, node); |
| 766 | return transCreateNodeIdentifier(c, checked_name); | 751 | return try Tag.identifier.create(c.arena, checked_name); |
| 767 | } | 752 | } |
| 768 | | 753 | |
| 769 | fn transCreateNodeTypedef( | 754 | fn transCreateNodeTypedef( |
| ... | @@ -782,9 +767,9 @@ fn transCreateNodeTypedef( | ... | @@ -782,9 +767,9 @@ fn transCreateNodeTypedef( |
| 782 | error.OutOfMemory => |e| return e, | 767 | error.OutOfMemory => |e| return e, |
| 783 | }; | 768 | }; |
| 784 | | 769 | |
| 785 | const payload = try c.arena.create(ast.Payload.Typedef); | 770 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); |
| 786 | payload.* = .{ | 771 | payload.* = .{ |
| 787 | .base = .{ .tag = ([2]ast.Node.Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] }, | 772 | .base = .{ .tag = ([2]Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] }, |
| 788 | .data = .{ | 773 | .data = .{ |
| 789 | .name = checked_name, | 774 | .name = checked_name, |
| 790 | .init = init_node, | 775 | .init = init_node, |
| ... | @@ -795,7 +780,7 @@ fn transCreateNodeTypedef( | ... | @@ -795,7 +780,7 @@ fn transCreateNodeTypedef( |
| 795 | | 780 | |
| 796 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Node { | 781 | fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Node { |
| 797 | if (c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl()))) |name| | 782 | if (c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl()))) |name| |
| 798 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 783 | return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice |
| 799 | const record_loc = record_decl.getLocation(); | 784 | const record_loc = record_decl.getLocation(); |
| 800 | | 785 | |
| 801 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, record_decl).getName_bytes_begin()); | 786 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, record_decl).getName_bytes_begin()); |
| ... | @@ -815,7 +800,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -815,7 +800,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 815 | } else if (record_decl.isStruct()) { | 800 | } else if (record_decl.isStruct()) { |
| 816 | container_kind_name = "struct"; | 801 | container_kind_name = "struct"; |
| 817 | } else { | 802 | } else { |
| 818 | try warn(c, record_loc, "record {s} is not a struct or union", .{bare_name}); | 803 | try warn(c, &c.global_scope.base, record_loc, "record {s} is not a struct or union", .{bare_name}); |
| 819 | return null; | 804 | return null; |
| 820 | } | 805 | } |
| 821 | | 806 | |
| ... | @@ -826,7 +811,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -826,7 +811,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 826 | const init_node = blk: { | 811 | const init_node = blk: { |
| 827 | const record_def = record_decl.getDefinition() orelse { | 812 | const record_def = record_decl.getDefinition() orelse { |
| 828 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 813 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 829 | break :blk Node.opaque_literal.init(); | 814 | break :blk Tag.opaque_literal.init(); |
| 830 | }; | 815 | }; |
| 831 | | 816 | |
| 832 | const is_packed = record_decl.getPackedAttribute(); | 817 | const is_packed = record_decl.getPackedAttribute(); |
| ... | @@ -843,14 +828,14 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -843,14 +828,14 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 843 | | 828 | |
| 844 | if (field_decl.isBitField()) { | 829 | if (field_decl.isBitField()) { |
| 845 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 830 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 846 | try warn(c, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name}); | 831 | try warn(c, &c.global_scope.base, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name}); |
| 847 | break :blk Node.opaque_literal.init(); | 832 | break :blk Tag.opaque_literal.init(); |
| 848 | } | 833 | } |
| 849 | | 834 | |
| 850 | if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) { | 835 | if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) { |
| 851 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 836 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 852 | try warn(c, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name}); | 837 | try warn(c, &c.global_scope.base, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name}); |
| 853 | break :blk Node.opaque_literal.init(); | 838 | break :blk Tag.opaque_literal.init(); |
| 854 | } | 839 | } |
| 855 | | 840 | |
| 856 | var is_anon = false; | 841 | var is_anon = false; |
| ... | @@ -864,8 +849,8 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -864,8 +849,8 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 864 | const field_type = transQualType(c, field_qt, field_loc) catch |err| switch (err) { | 849 | const field_type = transQualType(c, field_qt, field_loc) catch |err| switch (err) { |
| 865 | error.UnsupportedType => { | 850 | error.UnsupportedType => { |
| 866 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); | 851 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {}); |
| 867 | try warn(c, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, raw_name }); | 852 | try warn(c, &c.global_scope.base, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, field_name }); |
| 868 | break :blk Node.opaque_literal.init(); | 853 | break :blk Tag.opaque_literal.init(); |
| 869 | }, | 854 | }, |
| 870 | else => |e| return e, | 855 | else => |e| return e, |
| 871 | }; | 856 | }; |
| ... | @@ -890,20 +875,20 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -890,20 +875,20 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 890 | }); | 875 | }); |
| 891 | } | 876 | } |
| 892 | | 877 | |
| 893 | const payload = try c.arena.create(ast.Payload.Record); | 878 | const record_payload = try c.arena.create(ast.Payload.Record); |
| 894 | container_node.* = .{ | 879 | record_payload.* = .{ |
| 895 | .base = .{ .tag = ([2]ast.Node.Tag{ .@"struct", .@"union" })[@boolToInt(is_union)] }, | 880 | .base = .{ .tag = ([2]Tag{ .@"struct", .@"union" })[@boolToInt(is_union)] }, |
| 896 | .data = .{ | 881 | .data = .{ |
| 897 | .is_packed = is_packed, | 882 | .is_packed = is_packed, |
| 898 | .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items), | 883 | .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items), |
| 899 | }, | 884 | }, |
| 900 | }; | 885 | }; |
| 901 | break :blk Node.initPayload(&container_node.base); | 886 | break :blk Node.initPayload(&record_payload.base); |
| 902 | }; | 887 | }; |
| 903 | | 888 | |
| 904 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); | 889 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); |
| 905 | payload.* = .{ | 890 | payload.* = .{ |
| 906 | .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, | 891 | .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, |
| 907 | .data = .{ | 892 | .data = .{ |
| 908 | .name = name, | 893 | .name = name, |
| 909 | .init = init_node, | 894 | .init = init_node, |
| ... | @@ -913,12 +898,12 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod | ... | @@ -913,12 +898,12 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod |
| 913 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); | 898 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); |
| 914 | if (!is_unnamed) | 899 | if (!is_unnamed) |
| 915 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); | 900 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); |
| 916 | return Node.identifier.create(c.arena, name); | 901 | return try Tag.identifier.create(c.arena, name); |
| 917 | } | 902 | } |
| 918 | | 903 | |
| 919 | fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { | 904 | fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { |
| 920 | if (c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl()))) |name| | 905 | if (c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl()))) |name| |
| 921 | return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice | 906 | return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice |
| 922 | const enum_loc = enum_decl.getLocation(); | 907 | const enum_loc = enum_decl.getLocation(); |
| 923 | | 908 | |
| 924 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_decl).getName_bytes_begin()); | 909 | var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_decl).getName_bytes_begin()); |
| ... | @@ -965,7 +950,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { | ... | @@ -965,7 +950,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { |
| 965 | else => |e| return e, | 950 | else => |e| return e, |
| 966 | } | 951 | } |
| 967 | else | 952 | else |
| 968 | try Node.type.create(c.arena, "c_int"); | 953 | try Tag.type.create(c.arena, "c_int"); |
| 969 | | 954 | |
| 970 | it = enum_def.enumerator_begin(); | 955 | it = enum_def.enumerator_begin(); |
| 971 | end_it = enum_def.enumerator_end(); | 956 | end_it = enum_def.enumerator_end(); |
| ... | @@ -983,29 +968,29 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { | ... | @@ -983,29 +968,29 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { |
| 983 | else | 968 | else |
| 984 | null; | 969 | null; |
| 985 | | 970 | |
| 986 | try fields_and_decls.append(.{ | 971 | try fields.append(.{ |
| 987 | .name = field_name, | 972 | .name = field_name, |
| 988 | .value = int_node, | 973 | .value = int_node, |
| 989 | }); | 974 | }); |
| 990 | | 975 | |
| 991 | // In C each enum value is in the global namespace. So we put them there too. | 976 | // In C each enum value is in the global namespace. So we put them there too. |
| 992 | // At this point we can rely on the enum emitting successfully. | 977 | // At this point we can rely on the enum emitting successfully. |
| 993 | try addTopLevelDecl(c, field_name, try Node.enum_redecl.create(c.arena, .{ | 978 | try addTopLevelDecl(c, field_name, try Tag.enum_redecl.create(c.arena, .{ |
| 994 | .enum_val_name = enum_val_name, | 979 | .enum_val_name = enum_val_name, |
| 995 | .field_name = field_name, | 980 | .field_name = field_name, |
| 996 | .enum_name = name, | 981 | .enum_name = name, |
| 997 | })); | 982 | })); |
| 998 | } | 983 | } |
| 999 | | 984 | |
| 1000 | break :blk try Node.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items)); | 985 | break :blk try Tag.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items)); |
| 1001 | } else blk: { | 986 | } else blk: { |
| 1002 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {}); | 987 | _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {}); |
| 1003 | break :blk Node.opaque_literal.init(); | 988 | break :blk Tag.opaque_literal.init(); |
| 1004 | }; | 989 | }; |
| 1005 | | 990 | |
| 1006 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); | 991 | const payload = try c.arena.create(ast.Payload.SimpleVarDecl); |
| 1007 | payload.* = .{ | 992 | payload.* = .{ |
| 1008 | .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, | 993 | .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] }, |
| 1009 | .data = .{ | 994 | .data = .{ |
| 1010 | .name = name, | 995 | .name = name, |
| 1011 | .init = init_node, | 996 | .init = init_node, |
| ... | @@ -1015,7 +1000,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { | ... | @@ -1015,7 +1000,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node { |
| 1015 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); | 1000 | try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); |
| 1016 | if (!is_unnamed) | 1001 | if (!is_unnamed) |
| 1017 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); | 1002 | try c.alias_list.append(.{ .alias = bare_name, .name = name }); |
| 1018 | return transCreateNodeIdentifier(c, name); | 1003 | return try Tag.identifier.create(c.arena, name); |
| 1019 | } | 1004 | } |
| 1020 | | 1005 | |
| 1021 | const ResultUsed = enum { | 1006 | const ResultUsed = enum { |
| ... | @@ -1023,31 +1008,25 @@ const ResultUsed = enum { | ... | @@ -1023,31 +1008,25 @@ const ResultUsed = enum { |
| 1023 | unused, | 1008 | unused, |
| 1024 | }; | 1009 | }; |
| 1025 | | 1010 | |
| 1026 | const LRValue = enum { | | |
| 1027 | l_value, | | |
| 1028 | r_value, | | |
| 1029 | }; | | |
| 1030 | | | |
| 1031 | fn transStmt( | 1011 | fn transStmt( |
| 1032 | c: *Context, | 1012 | c: *Context, |
| 1033 | scope: *Scope, | 1013 | scope: *Scope, |
| 1034 | stmt: *const clang.Stmt, | 1014 | stmt: *const clang.Stmt, |
| 1035 | result_used: ResultUsed, | 1015 | result_used: ResultUsed, |
| 1036 | lrvalue: LRValue, | | |
| 1037 | ) TransError!Node { | 1016 | ) TransError!Node { |
| 1038 | const sc = stmt.getStmtClass(); | 1017 | const sc = stmt.getStmtClass(); |
| 1039 | switch (sc) { | 1018 | switch (sc) { |
| 1040 | .BinaryOperatorClass => return transBinaryOperator(c, scope, @ptrCast(*const clang.BinaryOperator, stmt), result_used), | 1019 | .BinaryOperatorClass => return transBinaryOperator(c, scope, @ptrCast(*const clang.BinaryOperator, stmt), result_used), |
| 1041 | .CompoundStmtClass => return transCompoundStmt(c, scope, @ptrCast(*const clang.CompoundStmt, stmt)), | 1020 | .CompoundStmtClass => return transCompoundStmt(c, scope, @ptrCast(*const clang.CompoundStmt, stmt)), |
| 1042 | .CStyleCastExprClass => return transCStyleCastExprClass(c, scope, @ptrCast(*const clang.CStyleCastExpr, stmt), result_used, lrvalue), | 1021 | .CStyleCastExprClass => return transCStyleCastExprClass(c, scope, @ptrCast(*const clang.CStyleCastExpr, stmt), result_used), |
| 1043 | .DeclStmtClass => return transDeclStmt(c, scope, @ptrCast(*const clang.DeclStmt, stmt)), | 1022 | .DeclStmtClass => return transDeclStmt(c, scope, @ptrCast(*const clang.DeclStmt, stmt)), |
| 1044 | .DeclRefExprClass => return transDeclRefExpr(c, scope, @ptrCast(*const clang.DeclRefExpr, stmt), lrvalue), | 1023 | .DeclRefExprClass => return transDeclRefExpr(c, scope, @ptrCast(*const clang.DeclRefExpr, stmt)), |
| 1045 | .ImplicitCastExprClass => return transImplicitCastExpr(c, scope, @ptrCast(*const clang.ImplicitCastExpr, stmt), result_used), | 1024 | .ImplicitCastExprClass => return transImplicitCastExpr(c, scope, @ptrCast(*const clang.ImplicitCastExpr, stmt), result_used), |
| 1046 | .IntegerLiteralClass => return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, stmt), result_used, .with_as), | 1025 | .IntegerLiteralClass => return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, stmt), result_used, .with_as), |
| 1047 | .ReturnStmtClass => return transReturnStmt(c, scope, @ptrCast(*const clang.ReturnStmt, stmt)), | 1026 | .ReturnStmtClass => return transReturnStmt(c, scope, @ptrCast(*const clang.ReturnStmt, stmt)), |
| 1048 | .StringLiteralClass => return transStringLiteral(c, scope, @ptrCast(*const clang.StringLiteral, stmt), result_used), | 1027 | .StringLiteralClass => return transStringLiteral(c, scope, @ptrCast(*const clang.StringLiteral, stmt), result_used), |
| 1049 | .ParenExprClass => { | 1028 | .ParenExprClass => { |
| 1050 | const expr = try transExpr(c, scope, @ptrCast(*const clang.ParenExpr, stmt).getSubExpr(), .used, lrvalue); | 1029 | const expr = try transExpr(c, scope, @ptrCast(*const clang.ParenExpr, stmt).getSubExpr(), .used); |
| 1051 | return maybeSuppressResult(c, scope, result_used, expr); | 1030 | return maybeSuppressResult(c, scope, result_used, expr); |
| 1052 | }, | 1031 | }, |
| 1053 | .InitListExprClass => return transInitListExpr(c, scope, @ptrCast(*const clang.InitListExpr, stmt), result_used), | 1032 | .InitListExprClass => return transInitListExpr(c, scope, @ptrCast(*const clang.InitListExpr, stmt), result_used), |
| ... | @@ -1056,9 +1035,9 @@ fn transStmt( | ... | @@ -1056,9 +1035,9 @@ fn transStmt( |
| 1056 | .WhileStmtClass => return transWhileLoop(c, scope, @ptrCast(*const clang.WhileStmt, stmt)), | 1035 | .WhileStmtClass => return transWhileLoop(c, scope, @ptrCast(*const clang.WhileStmt, stmt)), |
| 1057 | .DoStmtClass => return transDoWhileLoop(c, scope, @ptrCast(*const clang.DoStmt, stmt)), | 1036 | .DoStmtClass => return transDoWhileLoop(c, scope, @ptrCast(*const clang.DoStmt, stmt)), |
| 1058 | .NullStmtClass => { | 1037 | .NullStmtClass => { |
| 1059 | return Node.empty_block.init(); | 1038 | return Tag.empty_block.init(); |
| 1060 | }, | 1039 | }, |
| 1061 | .ContinueStmtClass => return try transCreateNodeContinue(c), | 1040 | .ContinueStmtClass => return Tag.@"continue".init(), |
| 1062 | .BreakStmtClass => return transBreak(c, scope), | 1041 | .BreakStmtClass => return transBreak(c, scope), |
| 1063 | .ForStmtClass => return transForLoop(c, scope, @ptrCast(*const clang.ForStmt, stmt)), | 1042 | .ForStmtClass => return transForLoop(c, scope, @ptrCast(*const clang.ForStmt, stmt)), |
| 1064 | .FloatingLiteralClass => return transFloatingLiteral(c, scope, @ptrCast(*const clang.FloatingLiteral, stmt), result_used), | 1043 | .FloatingLiteralClass => return transFloatingLiteral(c, scope, @ptrCast(*const clang.FloatingLiteral, stmt), result_used), |
| ... | @@ -1083,12 +1062,12 @@ fn transStmt( | ... | @@ -1083,12 +1062,12 @@ fn transStmt( |
| 1083 | .CompoundAssignOperatorClass => return transCompoundAssignOperator(c, scope, @ptrCast(*const clang.CompoundAssignOperator, stmt), result_used), | 1062 | .CompoundAssignOperatorClass => return transCompoundAssignOperator(c, scope, @ptrCast(*const clang.CompoundAssignOperator, stmt), result_used), |
| 1084 | .OpaqueValueExprClass => { | 1063 | .OpaqueValueExprClass => { |
| 1085 | const source_expr = @ptrCast(*const clang.OpaqueValueExpr, stmt).getSourceExpr().?; | 1064 | const source_expr = @ptrCast(*const clang.OpaqueValueExpr, stmt).getSourceExpr().?; |
| 1086 | const expr = try transExpr(c, scope, source_expr, .used, lrvalue); | 1065 | const expr = try transExpr(c, scope, source_expr, .used); |
| 1087 | return maybeSuppressResult(c, scope, result_used, expr); | 1066 | return maybeSuppressResult(c, scope, result_used, expr); |
| 1088 | }, | 1067 | }, |
| 1089 | else => { | 1068 | else => { |
| 1090 | return fail( | 1069 | return fail( |
| 1091 | rp, | 1070 | c, |
| 1092 | error.UnsupportedTranslation, | 1071 | error.UnsupportedTranslation, |
| 1093 | stmt.getBeginLoc(), | 1072 | stmt.getBeginLoc(), |
| 1094 | "TODO implement translation of stmt class {s}", | 1073 | "TODO implement translation of stmt class {s}", |
| ... | @@ -1109,37 +1088,36 @@ fn transBinaryOperator( | ... | @@ -1109,37 +1088,36 @@ fn transBinaryOperator( |
| 1109 | switch (op) { | 1088 | switch (op) { |
| 1110 | .Assign => return try transCreateNodeAssign(c, scope, result_used, stmt.getLHS(), stmt.getRHS()), | 1089 | .Assign => return try transCreateNodeAssign(c, scope, result_used, stmt.getLHS(), stmt.getRHS()), |
| 1111 | .Comma => { | 1090 | .Comma => { |
| 1112 | var block_scope = try Scope.Block.init(rp.c, scope, true); | 1091 | var block_scope = try Scope.Block.init(c, scope, true); |
| 1113 | defer block_scope.deinit(); | 1092 | defer block_scope.deinit(); |
| 1114 | | 1093 | |
| 1115 | | 1094 | const lhs = try transExpr(c, &block_scope.base, stmt.getLHS(), .unused); |
| 1116 | const lhs = try transExpr(c, &block_scope.base, stmt.getLHS(), .unused, .r_value); | | |
| 1117 | try block_scope.statements.append(lhs); | 1095 | try block_scope.statements.append(lhs); |
| 1118 | | 1096 | |
| 1119 | const rhs = try transExpr(rp, &block_scope.base, stmt.getRHS(), .used, .r_value); | 1097 | const rhs = try transExpr(c, &block_scope.base, stmt.getRHS(), .used); |
| 1120 | const break_node = try Node.break_val.create(c.arena, .{ | 1098 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 1121 | .label = block_scope.label, | 1099 | .label = block_scope.label, |
| 1122 | .val = rhs, | 1100 | .val = rhs, |
| 1123 | }); | 1101 | }); |
| 1124 | try block_scope.statements.append(break_node); | 1102 | try block_scope.statements.append(break_node); |
| 1125 | const block_node = try block_scope.complete(rp.c); | 1103 | const block_node = try block_scope.complete(c); |
| 1126 | return maybeSuppressResult(rp, scope, result_used, block_node); | 1104 | return maybeSuppressResult(c, scope, result_used, block_node); |
| 1127 | }, | 1105 | }, |
| 1128 | .Div => { | 1106 | .Div => { |
| 1129 | if (cIsSignedInteger(qt)) { | 1107 | if (cIsSignedInteger(qt)) { |
| 1130 | // signed integer division uses @divTrunc | 1108 | // signed integer division uses @divTrunc |
| 1131 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); | 1109 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used); |
| 1132 | const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); | 1110 | const rhs = try transExpr(c, scope, stmt.getRHS(), .used); |
| 1133 | const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 1111 | const div_trunc = try Tag.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 1134 | return maybeSuppressResult(c, scope, result_used, div_trunc); | 1112 | return maybeSuppressResult(c, scope, result_used, div_trunc); |
| 1135 | } | 1113 | } |
| 1136 | }, | 1114 | }, |
| 1137 | .Rem => { | 1115 | .Rem => { |
| 1138 | if (cIsSignedInteger(qt)) { | 1116 | if (cIsSignedInteger(qt)) { |
| 1139 | // signed integer division uses @rem | 1117 | // signed integer division uses @rem |
| 1140 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); | 1118 | const lhs = try transExpr(c, scope, stmt.getLHS(), .used); |
| 1141 | const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); | 1119 | const rhs = try transExpr(c, scope, stmt.getRHS(), .used); |
| 1142 | const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 1120 | const rem = try Tag.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 1143 | return maybeSuppressResult(c, scope, result_used, rem); | 1121 | return maybeSuppressResult(c, scope, result_used, rem); |
| 1144 | } | 1122 | } |
| 1145 | }, | 1123 | }, |
| ... | @@ -1150,14 +1128,14 @@ fn transBinaryOperator( | ... | @@ -1150,14 +1128,14 @@ fn transBinaryOperator( |
| 1150 | return transCreateNodeShiftOp(c, scope, stmt, .shr, result_used); | 1128 | return transCreateNodeShiftOp(c, scope, stmt, .shr, result_used); |
| 1151 | }, | 1129 | }, |
| 1152 | .LAnd => { | 1130 | .LAnd => { |
| 1153 | return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_and, result_used); | 1131 | return transCreateNodeBoolInfixOp(c, scope, stmt, .@"and", result_used); |
| 1154 | }, | 1132 | }, |
| 1155 | .LOr => { | 1133 | .LOr => { |
| 1156 | return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_or, result_used); | 1134 | return transCreateNodeBoolInfixOp(c, scope, stmt, .@"or", result_used); |
| 1157 | }, | 1135 | }, |
| 1158 | else => {}, | 1136 | else => {}, |
| 1159 | } | 1137 | } |
| 1160 | var op_id: Node.Tag = undefined; | 1138 | var op_id: Tag = undefined; |
| 1161 | switch (op) { | 1139 | switch (op) { |
| 1162 | .Add => { | 1140 | .Add => { |
| 1163 | if (cIsUnsignedInteger(qt)) { | 1141 | if (cIsUnsignedInteger(qt)) { |
| ... | @@ -1218,20 +1196,20 @@ fn transBinaryOperator( | ... | @@ -1218,20 +1196,20 @@ fn transBinaryOperator( |
| 1218 | else => unreachable, | 1196 | else => unreachable, |
| 1219 | } | 1197 | } |
| 1220 | | 1198 | |
| 1221 | const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value); | 1199 | const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used); |
| 1222 | const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value); | 1200 | const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used); |
| 1223 | | 1201 | |
| 1224 | const lhs = if (isBoolRes(lhs_uncasted)) | 1202 | const lhs = if (isBoolRes(lhs_uncasted)) |
| 1225 | try Node.bool_to_int.create(c.arena, lhs_uncasted) | 1203 | try Tag.bool_to_int.create(c.arena, lhs_uncasted) |
| 1226 | else | 1204 | else |
| 1227 | lhs_uncasted; | 1205 | lhs_uncasted; |
| 1228 | | 1206 | |
| 1229 | const rhs = if (isBoolRes(rhs_uncasted)) | 1207 | const rhs = if (isBoolRes(rhs_uncasted)) |
| 1230 | try Node.bool_to_int.create(c.arena, rhs_uncasted) | 1208 | try Tag.bool_to_int.create(c.arena, rhs_uncasted) |
| 1231 | else | 1209 | else |
| 1232 | rhs_uncasted; | 1210 | rhs_uncasted; |
| 1233 | | 1211 | |
| 1234 | return transCreateNodeInfixOp(c, scope, op_id, lhs, rhs, used); | 1212 | return transCreateNodeInfixOp(c, scope, op_id, lhs, rhs, result_used); |
| 1235 | } | 1213 | } |
| 1236 | | 1214 | |
| 1237 | fn transCompoundStmtInline( | 1215 | fn transCompoundStmtInline( |
| ... | @@ -1243,7 +1221,7 @@ fn transCompoundStmtInline( | ... | @@ -1243,7 +1221,7 @@ fn transCompoundStmtInline( |
| 1243 | var it = stmt.body_begin(); | 1221 | var it = stmt.body_begin(); |
| 1244 | const end_it = stmt.body_end(); | 1222 | const end_it = stmt.body_end(); |
| 1245 | while (it != end_it) : (it += 1) { | 1223 | while (it != end_it) : (it += 1) { |
| 1246 | const result = try transStmt(c, parent_scope, it[0], .unused, .r_value); | 1224 | const result = try transStmt(c, parent_scope, it[0], .unused); |
| 1247 | try block.statements.append(result); | 1225 | try block.statements.append(result); |
| 1248 | } | 1226 | } |
| 1249 | } | 1227 | } |
| ... | @@ -1260,7 +1238,6 @@ fn transCStyleCastExprClass( | ... | @@ -1260,7 +1238,6 @@ fn transCStyleCastExprClass( |
| 1260 | scope: *Scope, | 1238 | scope: *Scope, |
| 1261 | stmt: *const clang.CStyleCastExpr, | 1239 | stmt: *const clang.CStyleCastExpr, |
| 1262 | result_used: ResultUsed, | 1240 | result_used: ResultUsed, |
| 1263 | lrvalue: LRValue, | | |
| 1264 | ) TransError!Node { | 1241 | ) TransError!Node { |
| 1265 | const sub_expr = stmt.getSubExpr(); | 1242 | const sub_expr = stmt.getSubExpr(); |
| 1266 | const cast_node = (try transCCast( | 1243 | const cast_node = (try transCCast( |
| ... | @@ -1269,7 +1246,7 @@ fn transCStyleCastExprClass( | ... | @@ -1269,7 +1246,7 @@ fn transCStyleCastExprClass( |
| 1269 | stmt.getBeginLoc(), | 1246 | stmt.getBeginLoc(), |
| 1270 | stmt.getType(), | 1247 | stmt.getType(), |
| 1271 | sub_expr.getType(), | 1248 | sub_expr.getType(), |
| 1272 | try transExpr(c, scope, sub_expr, .used, lrvalue), | 1249 | try transExpr(c, scope, sub_expr, .used), |
| 1273 | )); | 1250 | )); |
| 1274 | return maybeSuppressResult(c, scope, result_used, cast_node); | 1251 | return maybeSuppressResult(c, scope, result_used, cast_node); |
| 1275 | } | 1252 | } |
| ... | @@ -1294,7 +1271,7 @@ fn transDeclStmtOne( | ... | @@ -1294,7 +1271,7 @@ fn transDeclStmtOne( |
| 1294 | // This is actually a global variable, put it in the global scope and reference it. | 1271 | // This is actually a global variable, put it in the global scope and reference it. |
| 1295 | // `_ = mangled_name;` | 1272 | // `_ = mangled_name;` |
| 1296 | try visitVarDecl(c, var_decl, mangled_name); | 1273 | try visitVarDecl(c, var_decl, mangled_name); |
| 1297 | return try maybeSuppressResult(c, scope, .unused, try Node.identifier.create(c.arena, mangled_name)); | 1274 | return try maybeSuppressResult(c, scope, .unused, try Tag.identifier.create(c.arena, mangled_name)); |
| 1298 | }, | 1275 | }, |
| 1299 | else => {}, | 1276 | else => {}, |
| 1300 | } | 1277 | } |
| ... | @@ -1308,13 +1285,13 @@ fn transDeclStmtOne( | ... | @@ -1308,13 +1285,13 @@ fn transDeclStmtOne( |
| 1308 | if (expr.getStmtClass() == .StringLiteralClass) | 1285 | if (expr.getStmtClass() == .StringLiteralClass) |
| 1309 | try transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), try zigArraySize(c, type_node)) | 1286 | try transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), try zigArraySize(c, type_node)) |
| 1310 | else | 1287 | else |
| 1311 | try transExprCoercing(c, scope, expr, .used, .r_value) | 1288 | try transExprCoercing(c, scope, expr, .used) |
| 1312 | else | 1289 | else |
| 1313 | try transCreateNodeUndefinedLiteral(c); | 1290 | Tag.undefined_literal.init(); |
| 1314 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { | 1291 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| 1315 | init_node = try Node.bool_to_int.create(c.arena, init_node); | 1292 | init_node = try Tag.bool_to_int.create(c.arena, init_node); |
| 1316 | } | 1293 | } |
| 1317 | return Node.var_decl.create(c.arena, .{ | 1294 | return Tag.var_decl.create(c.arena, .{ |
| 1318 | .is_pub = false, | 1295 | .is_pub = false, |
| 1319 | .is_const = is_const, | 1296 | .is_const = is_const, |
| 1320 | .is_extern = false, | 1297 | .is_extern = false, |
| ... | @@ -1339,7 +1316,7 @@ fn transDeclStmtOne( | ... | @@ -1339,7 +1316,7 @@ fn transDeclStmtOne( |
| 1339 | return node; | 1316 | return node; |
| 1340 | }, | 1317 | }, |
| 1341 | else => |kind| return fail( | 1318 | else => |kind| return fail( |
| 1342 | rp, | 1319 | c, |
| 1343 | error.UnsupportedTranslation, | 1320 | error.UnsupportedTranslation, |
| 1344 | decl.getLocation(), | 1321 | decl.getLocation(), |
| 1345 | "TODO implement translation of DeclStmt kind {s}", | 1322 | "TODO implement translation of DeclStmt kind {s}", |
| ... | @@ -1370,12 +1347,11 @@ fn transDeclRefExpr( | ... | @@ -1370,12 +1347,11 @@ fn transDeclRefExpr( |
| 1370 | c: *Context, | 1347 | c: *Context, |
| 1371 | scope: *Scope, | 1348 | scope: *Scope, |
| 1372 | expr: *const clang.DeclRefExpr, | 1349 | expr: *const clang.DeclRefExpr, |
| 1373 | lrvalue: LRValue, | | |
| 1374 | ) TransError!Node { | 1350 | ) TransError!Node { |
| 1375 | const value_decl = expr.getDecl(); | 1351 | const value_decl = expr.getDecl(); |
| 1376 | const name = try c.str(@ptrCast(*const clang.NamedDecl, value_decl).getName_bytes_begin()); | 1352 | const name = try c.str(@ptrCast(*const clang.NamedDecl, value_decl).getName_bytes_begin()); |
| 1377 | const mangled_name = scope.getAlias(name); | 1353 | const mangled_name = scope.getAlias(name); |
| 1378 | return Node.identifier.create(c.arena, mangled_name); | 1354 | return Tag.identifier.create(c.arena, mangled_name); |
| 1379 | } | 1355 | } |
| 1380 | | 1356 | |
| 1381 | fn transImplicitCastExpr( | 1357 | fn transImplicitCastExpr( |
| ... | @@ -1389,49 +1365,49 @@ fn transImplicitCastExpr( | ... | @@ -1389,49 +1365,49 @@ fn transImplicitCastExpr( |
| 1389 | const src_type = getExprQualType(c, sub_expr); | 1365 | const src_type = getExprQualType(c, sub_expr); |
| 1390 | switch (expr.getCastKind()) { | 1366 | switch (expr.getCastKind()) { |
| 1391 | .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => { | 1367 | .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => { |
| 1392 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value); | 1368 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); |
| 1393 | const casted = try transCCast(c, scope, expr.getBeginLoc(), dest_type, src_type, sub_expr_node); | 1369 | const casted = try transCCast(c, scope, expr.getBeginLoc(), dest_type, src_type, sub_expr_node); |
| 1394 | return maybeSuppressResult(c, scope, result_used, casted); | 1370 | return maybeSuppressResult(c, scope, result_used, casted); |
| 1395 | }, | 1371 | }, |
| 1396 | .LValueToRValue, .NoOp, .FunctionToPointerDecay => { | 1372 | .LValueToRValue, .NoOp, .FunctionToPointerDecay => { |
| 1397 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value); | 1373 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); |
| 1398 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); | 1374 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); |
| 1399 | }, | 1375 | }, |
| 1400 | .ArrayToPointerDecay => { | 1376 | .ArrayToPointerDecay => { |
| 1401 | if (exprIsNarrowStringLiteral(sub_expr)) { | 1377 | if (exprIsNarrowStringLiteral(sub_expr)) { |
| 1402 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value); | 1378 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); |
| 1403 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); | 1379 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); |
| 1404 | } | 1380 | } |
| 1405 | | 1381 | |
| 1406 | const addr = try Node.address_of.create(c.arena, try transExpr(c, scope, sub_expr, .used, .r_value)); | 1382 | const addr = try Tag.address_of.create(c.arena, try transExpr(c, scope, sub_expr, .used)); |
| 1407 | return maybeSuppressResult(c, scope, result_used, addr); | 1383 | return maybeSuppressResult(c, scope, result_used, addr); |
| 1408 | }, | 1384 | }, |
| 1409 | .NullToPointer => { | 1385 | .NullToPointer => { |
| 1410 | return Node.null_literal.init(); | 1386 | return Tag.null_literal.init(); |
| 1411 | }, | 1387 | }, |
| 1412 | .PointerToBoolean => { | 1388 | .PointerToBoolean => { |
| 1413 | // @ptrToInt(val) != 0 | 1389 | // @ptrToInt(val) != 0 |
| 1414 | const ptr_to_int = try Node.ptr_to_int.create(c.arena, try transExpr(c, scope, sub_expr, .used, .r_value)); | 1390 | const ptr_to_int = try Tag.ptr_to_int.create(c.arena, try transExpr(c, scope, sub_expr, .used)); |
| 1415 | | 1391 | |
| 1416 | const ne = try Node.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Node.zero_literal.init() }); | 1392 | const ne = try Tag.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Tag.zero_literal.init() }); |
| 1417 | return maybeSuppressResult(c, scope, result_used, ne); | 1393 | return maybeSuppressResult(c, scope, result_used, ne); |
| 1418 | }, | 1394 | }, |
| 1419 | .IntegralToBoolean => { | 1395 | .IntegralToBoolean => { |
| 1420 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value); | 1396 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); |
| 1421 | | 1397 | |
| 1422 | // The expression is already a boolean one, return it as-is | 1398 | // The expression is already a boolean one, return it as-is |
| 1423 | if (isBoolRes(sub_expr_node)) | 1399 | if (isBoolRes(sub_expr_node)) |
| 1424 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); | 1400 | return maybeSuppressResult(c, scope, result_used, sub_expr_node); |
| 1425 | | 1401 | |
| 1426 | // val != 0 | 1402 | // val != 0 |
| 1427 | const ne = try Node.not_equal.create(c.arena, .{ .lhs = sub_expr_node, .rhs = Node.zero_literal.init() }); | 1403 | const ne = try Tag.not_equal.create(c.arena, .{ .lhs = sub_expr_node, .rhs = Tag.zero_literal.init() }); |
| 1428 | return maybeSuppressResult(c, scope, result_used, ne); | 1404 | return maybeSuppressResult(c, scope, result_used, ne); |
| 1429 | }, | 1405 | }, |
| 1430 | .BuiltinFnToFnPtr => { | 1406 | .BuiltinFnToFnPtr => { |
| 1431 | return transExpr(rp, scope, sub_expr, result_used, .r_value); | 1407 | return transExpr(c, scope, sub_expr, result_used); |
| 1432 | }, | 1408 | }, |
| 1433 | else => |kind| return fail( | 1409 | else => |kind| return fail( |
| 1434 | rp, | 1410 | c, |
| 1435 | error.UnsupportedTranslation, | 1411 | error.UnsupportedTranslation, |
| 1436 | @ptrCast(*const clang.Stmt, expr).getBeginLoc(), | 1412 | @ptrCast(*const clang.Stmt, expr).getBeginLoc(), |
| 1437 | "TODO implement translation of CastKind {s}", | 1413 | "TODO implement translation of CastKind {s}", |
| ... | @@ -1445,17 +1421,16 @@ fn transBoolExpr( | ... | @@ -1445,17 +1421,16 @@ fn transBoolExpr( |
| 1445 | scope: *Scope, | 1421 | scope: *Scope, |
| 1446 | expr: *const clang.Expr, | 1422 | expr: *const clang.Expr, |
| 1447 | used: ResultUsed, | 1423 | used: ResultUsed, |
| 1448 | lrvalue: LRValue, | | |
| 1449 | ) TransError!Node { | 1424 | ) TransError!Node { |
| 1450 | if (@ptrCast(*const clang.Stmt, expr).getStmtClass() == .IntegerLiteralClass) { | 1425 | if (@ptrCast(*const clang.Stmt, expr).getStmtClass() == .IntegerLiteralClass) { |
| 1451 | var is_zero: bool = undefined; | 1426 | var is_zero: bool = undefined; |
| 1452 | if (!(@ptrCast(*const clang.IntegerLiteral, expr).isZero(&is_zero, c.clang_context))) { | 1427 | if (!(@ptrCast(*const clang.IntegerLiteral, expr).isZero(&is_zero, c.clang_context))) { |
| 1453 | return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid integer literal", .{}); | 1428 | return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid integer literal", .{}); |
| 1454 | } | 1429 | } |
| 1455 | return Node{ .tag = ([2]ast.Node.Tag{ .true_literal, .false_literal })[@boolToInt(is_zero)] }; | 1430 | return Node{ .tag_if_small_enough = @enumToInt(([2]Tag{ .true_literal, .false_literal })[@boolToInt(is_zero)]) }; |
| 1456 | } | 1431 | } |
| 1457 | | 1432 | |
| 1458 | var res = try transExpr(c, scope, expr, used, lrvalue); | 1433 | var res = try transExpr(c, scope, expr, used); |
| 1459 | if (isBoolRes(res)) { | 1434 | if (isBoolRes(res)) { |
| 1460 | return maybeSuppressResult(c, scope, used, res); | 1435 | return maybeSuppressResult(c, scope, used, res); |
| 1461 | } | 1436 | } |
| ... | @@ -1494,7 +1469,7 @@ fn isBoolRes(res: Node) bool { | ... | @@ -1494,7 +1469,7 @@ fn isBoolRes(res: Node) bool { |
| 1494 | .@"or", | 1469 | .@"or", |
| 1495 | .@"and", | 1470 | .@"and", |
| 1496 | .equal, | 1471 | .equal, |
| 1497 | .note_equal, | 1472 | .not_equal, |
| 1498 | .less_than, | 1473 | .less_than, |
| 1499 | .less_than_equal, | 1474 | .less_than_equal, |
| 1500 | .greater_than, | 1475 | .greater_than, |
| ... | @@ -1547,18 +1522,18 @@ fn finishBoolExpr( | ... | @@ -1547,18 +1522,18 @@ fn finishBoolExpr( |
| 1547 | .Float16, | 1522 | .Float16, |
| 1548 | => { | 1523 | => { |
| 1549 | // node != 0 | 1524 | // node != 0 |
| 1550 | return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() }); | 1525 | return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() }); |
| 1551 | }, | 1526 | }, |
| 1552 | .NullPtr => { | 1527 | .NullPtr => { |
| 1553 | // node == null | 1528 | // node == null |
| 1554 | return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init() }); | 1529 | return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() }); |
| 1555 | }, | 1530 | }, |
| 1556 | else => {}, | 1531 | else => {}, |
| 1557 | } | 1532 | } |
| 1558 | }, | 1533 | }, |
| 1559 | .Pointer => { | 1534 | .Pointer => { |
| 1560 | // node == null | 1535 | // node == null |
| 1561 | return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init() }); | 1536 | return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() }); |
| 1562 | }, | 1537 | }, |
| 1563 | .Typedef => { | 1538 | .Typedef => { |
| 1564 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); | 1539 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| ... | @@ -1568,8 +1543,7 @@ fn finishBoolExpr( | ... | @@ -1568,8 +1543,7 @@ fn finishBoolExpr( |
| 1568 | }, | 1543 | }, |
| 1569 | .Enum => { | 1544 | .Enum => { |
| 1570 | // node != 0 | 1545 | // node != 0 |
| 1571 | return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() }); | 1546 | return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() }); |
| 1572 | const op_token = try appendToken(c, .BangEqual, "!="); | | |
| 1573 | }, | 1547 | }, |
| 1574 | .Elaborated => { | 1548 | .Elaborated => { |
| 1575 | const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); | 1549 | const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); |
| ... | @@ -1614,9 +1588,10 @@ fn transIntegerLiteral( | ... | @@ -1614,9 +1588,10 @@ fn transIntegerLiteral( |
| 1614 | // But the first step is to be correct, and the next step is to make the output more elegant. | 1588 | // But the first step is to be correct, and the next step is to make the output more elegant. |
| 1615 | | 1589 | |
| 1616 | // @as(T, x) | 1590 | // @as(T, x) |
| | 1591 | const expr_base = @ptrCast(*const clang.Expr, expr); |
| 1617 | const ty_node = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()); | 1592 | const ty_node = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()); |
| 1618 | const rhs = try transCreateNodeAPInt(c, eval_result.Val.getInt()); | 1593 | const rhs = try transCreateNodeAPInt(c, eval_result.Val.getInt()); |
| 1619 | const as = try Node.as.create(c.arena, .{ .lhs = ty_node, .rhs = rhs }); | 1594 | const as = try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = rhs }); |
| 1620 | return maybeSuppressResult(c, scope, result_used, as); | 1595 | return maybeSuppressResult(c, scope, result_used, as); |
| 1621 | } | 1596 | } |
| 1622 | | 1597 | |
| ... | @@ -1624,16 +1599,16 @@ fn transReturnStmt( | ... | @@ -1624,16 +1599,16 @@ fn transReturnStmt( |
| 1624 | c: *Context, | 1599 | c: *Context, |
| 1625 | scope: *Scope, | 1600 | scope: *Scope, |
| 1626 | expr: *const clang.ReturnStmt, | 1601 | expr: *const clang.ReturnStmt, |
| 1627 | ) TransError!*ast.Node { | 1602 | ) TransError!Node { |
| 1628 | const val_expr = expr.getRetValue() orelse | 1603 | const val_expr = expr.getRetValue() orelse |
| 1629 | return Node.return_void.init(); | 1604 | return Tag.return_void.init(); |
| 1630 | | 1605 | |
| 1631 | var rhs = try transExprCoercing(c, scope, val_expr, .used, .r_value); | 1606 | var rhs = try transExprCoercing(c, scope, val_expr, .used); |
| 1632 | const return_qt = scope.findBlockReturnType(c); | 1607 | const return_qt = scope.findBlockReturnType(c); |
| 1633 | if (isBoolRes(rhs) and !qualTypeIsBoolean(return_qt)) { | 1608 | if (isBoolRes(rhs) and !qualTypeIsBoolean(return_qt)) { |
| 1634 | rhs = try Node.bool_to_int.create(c.arena, rhs); | 1609 | rhs = try Tag.bool_to_int.create(c.arena, rhs); |
| 1635 | } | 1610 | } |
| 1636 | return Node.@"return".create(c.arena, rhs); | 1611 | return Tag.@"return".create(c.arena, rhs); |
| 1637 | } | 1612 | } |
| 1638 | | 1613 | |
| 1639 | fn transStringLiteral( | 1614 | fn transStringLiteral( |
| ... | @@ -1647,10 +1622,9 @@ fn transStringLiteral( | ... | @@ -1647,10 +1622,9 @@ fn transStringLiteral( |
| 1647 | .Ascii, .UTF8 => { | 1622 | .Ascii, .UTF8 => { |
| 1648 | var len: usize = undefined; | 1623 | var len: usize = undefined; |
| 1649 | const bytes_ptr = stmt.getString_bytes_begin_size(&len); | 1624 | const bytes_ptr = stmt.getString_bytes_begin_size(&len); |
| 1650 | const str = bytes_ptr[0..len]; | | |
| 1651 | | 1625 | |
| 1652 | const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(str)}); | 1626 | const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])}); |
| 1653 | const node = try Node.string_literal.create(c.arena, str); | 1627 | const node = try Tag.string_literal.create(c.arena, str); |
| 1654 | return maybeSuppressResult(c, scope, result_used, node); | 1628 | return maybeSuppressResult(c, scope, result_used, node); |
| 1655 | }, | 1629 | }, |
| 1656 | .UTF16, .UTF32, .Wide => { | 1630 | .UTF16, .UTF32, .Wide => { |
| ... | @@ -1658,9 +1632,9 @@ fn transStringLiteral( | ... | @@ -1658,9 +1632,9 @@ fn transStringLiteral( |
| 1658 | const name = try std.fmt.allocPrint(c.arena, "zig.{s}_string_{d}", .{ str_type, c.getMangle() }); | 1632 | const name = try std.fmt.allocPrint(c.arena, "zig.{s}_string_{d}", .{ str_type, c.getMangle() }); |
| 1659 | const lit_array = try transStringLiteralAsArray(c, scope, stmt, stmt.getLength() + 1); | 1633 | const lit_array = try transStringLiteralAsArray(c, scope, stmt, stmt.getLength() + 1); |
| 1660 | | 1634 | |
| 1661 | const decl = try Node.var_simple.create(c.arena, .{ .name = name, .init = lit_array }); | 1635 | const decl = try Tag.var_simple.create(c.arena, .{ .name = name, .init = lit_array }); |
| 1662 | try scope.appendNode(name, decl); | 1636 | try scope.appendNode(decl); |
| 1663 | const node = try Node.identifier.create(c.arena, name); | 1637 | const node = try Tag.identifier.create(c.arena, name); |
| 1664 | return maybeSuppressResult(c, scope, result_used, node); | 1638 | return maybeSuppressResult(c, scope, result_used, node); |
| 1665 | }, | 1639 | }, |
| 1666 | } | 1640 | } |
| ... | @@ -1669,9 +1643,7 @@ fn transStringLiteral( | ... | @@ -1669,9 +1643,7 @@ fn transStringLiteral( |
| 1669 | /// Parse the size of an array back out from an ast Node. | 1643 | /// Parse the size of an array back out from an ast Node. |
| 1670 | fn zigArraySize(c: *Context, node: Node) TransError!usize { | 1644 | fn zigArraySize(c: *Context, node: Node) TransError!usize { |
| 1671 | if (node.castTag(.array_type)) |array| { | 1645 | if (node.castTag(.array_type)) |array| { |
| 1672 | if (array.data.len.castTag(.int_literal)) |int_lit| { | 1646 | return array.data.len; |
| 1673 | return std.fmt.parseUnsigned(usize, int_lit.data, 10) catch error.UnsupportedTranslation; | | |
| 1674 | } | | |
| 1675 | } | 1647 | } |
| 1676 | return error.UnsupportedTranslation; | 1648 | return error.UnsupportedTranslation; |
| 1677 | } | 1649 | } |
| ... | @@ -1709,7 +1681,7 @@ fn transStringLiteralAsArray( | ... | @@ -1709,7 +1681,7 @@ fn transStringLiteralAsArray( |
| 1709 | init_list[i] = try transCreateNodeNumber(c, 0); | 1681 | init_list[i] = try transCreateNodeNumber(c, 0); |
| 1710 | } | 1682 | } |
| 1711 | | 1683 | |
| 1712 | return Node.array_init.create(c.arena, init_list); | 1684 | return Tag.array_init.create(c.arena, init_list); |
| 1713 | } | 1685 | } |
| 1714 | | 1686 | |
| 1715 | fn cIsEnum(qt: clang.QualType) bool { | 1687 | fn cIsEnum(qt: clang.QualType) bool { |
| ... | @@ -1747,89 +1719,77 @@ fn transCCast( | ... | @@ -1747,89 +1719,77 @@ fn transCCast( |
| 1747 | // 3. Bit-cast to correct signed-ness | 1719 | // 3. Bit-cast to correct signed-ness |
| 1748 | const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type); | 1720 | const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type); |
| 1749 | const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type); | 1721 | const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type); |
| 1750 | var src_int_expr = if (cIsInteger(src_type)) expr else Node.enum_to_int.create(c.arena, expr); | 1722 | var src_int_expr = if (cIsInteger(src_type)) expr else try Tag.enum_to_int.create(c.arena, expr); |
| 1751 | | 1723 | |
| 1752 | if (isBoolRes(src_int_expr)) { | 1724 | if (isBoolRes(src_int_expr)) { |
| 1753 | src_int_expr = try Node.bool_to_int.create(c.arena, src_int_expr); | 1725 | src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr); |
| 1754 | } | 1726 | } |
| 1755 | | 1727 | |
| 1756 | switch (cIntTypeCmp(dst_type, src_int_type)) { | 1728 | switch (cIntTypeCmp(dst_type, src_int_type)) { |
| 1757 | .lt => { | 1729 | .lt => { |
| 1758 | // @truncate(SameSignSmallerInt, src_int_expr) | 1730 | // @truncate(SameSignSmallerInt, src_int_expr) |
| 1759 | const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed); | 1731 | const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed); |
| 1760 | src_int_expr = try Node.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr }); | 1732 | src_int_expr = try Tag.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr }); |
| 1761 | }, | 1733 | }, |
| 1762 | .gt => { | 1734 | .gt => { |
| 1763 | // @as(SameSignBiggerInt, src_int_expr) | 1735 | // @as(SameSignBiggerInt, src_int_expr) |
| 1764 | const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed); | 1736 | const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed); |
| 1765 | src_int_expr = try Node.as.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr }); | 1737 | src_int_expr = try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr }); |
| 1766 | }, | 1738 | }, |
| 1767 | .eq => { | 1739 | .eq => { |
| 1768 | // src_int_expr = src_int_expr | 1740 | // src_int_expr = src_int_expr |
| 1769 | }, | 1741 | }, |
| 1770 | } | 1742 | } |
| 1771 | // @bitCast(dest_type, intermediate_value) | 1743 | // @bitCast(dest_type, intermediate_value) |
| 1772 | return Node.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr }); | 1744 | return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr }); |
| 1773 | } | 1745 | } |
| 1774 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { | 1746 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 1775 | // @intCast(dest_type, @ptrToInt(val)) | 1747 | // @intCast(dest_type, @ptrToInt(val)) |
| 1776 | const ptr_to_int = try Node.ptr_to_int.create(c.arena, expr); | 1748 | const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr); |
| 1777 | return Node.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = ptr_to_int }); | 1749 | return Tag.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = ptr_to_int }); |
| 1778 | } | 1750 | } |
| 1779 | if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { | 1751 | if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| 1780 | // @intToPtr(dest_type, val) | 1752 | // @intToPtr(dest_type, val) |
| 1781 | return Node.int_to_ptr.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1753 | return Tag.int_to_ptr.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1782 | } | 1754 | } |
| 1783 | if (cIsFloating(src_type) and cIsFloating(dst_type)) { | 1755 | if (cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1784 | // @floatCast(dest_type, val) | 1756 | // @floatCast(dest_type, val) |
| 1785 | return Node.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1757 | return Tag.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1786 | } | 1758 | } |
| 1787 | if (cIsFloating(src_type) and !cIsFloating(dst_type)) { | 1759 | if (cIsFloating(src_type) and !cIsFloating(dst_type)) { |
| 1788 | // @floatToInt(dest_type, val) | 1760 | // @floatToInt(dest_type, val) |
| 1789 | return Node.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1761 | return Tag.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1790 | } | 1762 | } |
| 1791 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { | 1763 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1792 | // @intToFloat(dest_type, val) | 1764 | // @intToFloat(dest_type, val) |
| 1793 | return Node.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1765 | return Tag.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1794 | } | 1766 | } |
| 1795 | if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) { | 1767 | if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) { |
| 1796 | // @boolToInt returns either a comptime_int or a u1 | 1768 | // @boolToInt returns either a comptime_int or a u1 |
| 1797 | // TODO: if dst_type is 1 bit & signed (bitfield) we need @bitCast | 1769 | // TODO: if dst_type is 1 bit & signed (bitfield) we need @bitCast |
| 1798 | // instead of @as | 1770 | // instead of @as |
| 1799 | const bool_to_int = Node.bool_to_int.create(c.arena, expr); | 1771 | const bool_to_int = try Tag.bool_to_int.create(c.arena, expr); |
| 1800 | return Node.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int }); | 1772 | return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int }); |
| 1801 | } | 1773 | } |
| 1802 | if (cIsEnum(dst_type)) { | 1774 | if (cIsEnum(dst_type)) { |
| 1803 | // @intToEnum(dest_type, val) | 1775 | // @intToEnum(dest_type, val) |
| 1804 | return Node.int_to_enum.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1776 | return Tag.int_to_enum.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1805 | } | 1777 | } |
| 1806 | if (cIsEnum(src_type) and !cIsEnum(dst_type)) { | 1778 | if (cIsEnum(src_type) and !cIsEnum(dst_type)) { |
| 1807 | // @enumToInt(val) | 1779 | // @enumToInt(val) |
| 1808 | return Node.enum_to_int.create(c.arena, expr); | 1780 | return Tag.enum_to_int.create(c.arena, expr); |
| 1809 | } | 1781 | } |
| 1810 | // @as(dest_type, val) | 1782 | // @as(dest_type, val) |
| 1811 | return Node.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 1783 | return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 1812 | } | 1784 | } |
| 1813 | | 1785 | |
| 1814 | fn transExpr( | 1786 | fn transExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node { |
| 1815 | c: *Context, | 1787 | return transStmt(c, scope, @ptrCast(*const clang.Stmt, expr), used); |
| 1816 | scope: *Scope, | | |
| 1817 | expr: *const clang.Expr, | | |
| 1818 | used: ResultUsed, | | |
| 1819 | lrvalue: LRValue, | | |
| 1820 | ) TransError!Node { | | |
| 1821 | return transStmt(c, scope, @ptrCast(*const clang.Stmt, expr), used, lrvalue); | | |
| 1822 | } | 1788 | } |
| 1823 | | 1789 | |
| 1824 | /// Same as `transExpr` but with the knowledge that the operand will be type coerced, and therefore | 1790 | /// Same as `transExpr` but with the knowledge that the operand will be type coerced, and therefore |
| 1825 | /// an `@as` would be redundant. This is used to prevent redundant `@as` in integer literals. | 1791 | /// an `@as` would be redundant. This is used to prevent redundant `@as` in integer literals. |
| 1826 | fn transExprCoercing( | 1792 | fn transExprCoercing(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node { |
| 1827 | c: *Context, | | |
| 1828 | scope: *Scope, | | |
| 1829 | expr: *const clang.Expr, | | |
| 1830 | used: ResultUsed, | | |
| 1831 | lrvalue: LRValue, | | |
| 1832 | ) TransError!Node { | | |
| 1833 | switch (@ptrCast(*const clang.Stmt, expr).getStmtClass()) { | 1793 | switch (@ptrCast(*const clang.Stmt, expr).getStmtClass()) { |
| 1834 | .IntegerLiteralClass => { | 1794 | .IntegerLiteralClass => { |
| 1835 | return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, expr), .used, .no_as); | 1795 | return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, expr), .used, .no_as); |
| ... | @@ -1840,12 +1800,12 @@ fn transExprCoercing( | ... | @@ -1840,12 +1800,12 @@ fn transExprCoercing( |
| 1840 | .UnaryOperatorClass => { | 1800 | .UnaryOperatorClass => { |
| 1841 | const un_expr = @ptrCast(*const clang.UnaryOperator, expr); | 1801 | const un_expr = @ptrCast(*const clang.UnaryOperator, expr); |
| 1842 | if (un_expr.getOpcode() == .Extension) { | 1802 | if (un_expr.getOpcode() == .Extension) { |
| 1843 | return transExprCoercing(c, scope, un_expr.getSubExpr(), used, lrvalue); | 1803 | return transExprCoercing(c, scope, un_expr.getSubExpr(), used); |
| 1844 | } | 1804 | } |
| 1845 | }, | 1805 | }, |
| 1846 | else => {}, | 1806 | else => {}, |
| 1847 | } | 1807 | } |
| 1848 | return transExpr(c, scope, expr, .used, .r_value); | 1808 | return transExpr(c, scope, expr, .used); |
| 1849 | } | 1809 | } |
| 1850 | | 1810 | |
| 1851 | fn transInitListExprRecord( | 1811 | fn transInitListExprRecord( |
| ... | @@ -1896,11 +1856,11 @@ fn transInitListExprRecord( | ... | @@ -1896,11 +1856,11 @@ fn transInitListExprRecord( |
| 1896 | | 1856 | |
| 1897 | try field_inits.append(.{ | 1857 | try field_inits.append(.{ |
| 1898 | .name = raw_name, | 1858 | .name = raw_name, |
| 1899 | .value = try transExpr(c, scope, elem_expr, .used, .r_value), | 1859 | .value = try transExpr(c, scope, elem_expr, .used), |
| 1900 | }); | 1860 | }); |
| 1901 | } | 1861 | } |
| 1902 | | 1862 | |
| 1903 | return Node.container_init.create(c.arena, try c.arena.dupe(ast.Payload.ContainerInit.Initializer, field_inits.items)); | 1863 | return Tag.container_init.create(c.arena, try c.arena.dupe(ast.Payload.ContainerInit.Initializer, field_inits.items)); |
| 1904 | } | 1864 | } |
| 1905 | | 1865 | |
| 1906 | fn transInitListExprArray( | 1866 | fn transInitListExprArray( |
| ... | @@ -1920,18 +1880,18 @@ fn transInitListExprArray( | ... | @@ -1920,18 +1880,18 @@ fn transInitListExprArray( |
| 1920 | const leftover_count = all_count - init_count; | 1880 | const leftover_count = all_count - init_count; |
| 1921 | | 1881 | |
| 1922 | if (all_count == 0) { | 1882 | if (all_count == 0) { |
| 1923 | return Node.empty_array.create(c.arena, try transQualType(c, child_qt, source_loc)); | 1883 | return Tag.empty_array.create(c.arena, try transQualType(c, child_qt, loc)); |
| 1924 | } | 1884 | } |
| 1925 | | 1885 | |
| 1926 | const ty_node = try transType(ty); | 1886 | const ty_node = try transType(c, ty, loc); |
| 1927 | const init_node = if (init_count != 0) blk: { | 1887 | const init_node = if (init_count != 0) blk: { |
| 1928 | const init_list = try c.arena.alloc(Node, init_count); | 1888 | const init_list = try c.arena.alloc(Node, init_count); |
| 1929 | | 1889 | |
| 1930 | for (init_list) |*init, i| { | 1890 | for (init_list) |*init, i| { |
| 1931 | const elem_expr = expr.getInit(i); | 1891 | const elem_expr = expr.getInit(@intCast(c_uint, i)); |
| 1932 | init.* = try transExpr(c, scope, elem_expr, .used, .r_value); | 1892 | init.* = try transExpr(c, scope, elem_expr, .used); |
| 1933 | } | 1893 | } |
| 1934 | const init_node = try Node.array_init.create(c.arena, init_list); | 1894 | const init_node = try Tag.array_init.create(c.arena, init_list); |
| 1935 | if (leftover_count == 0) { | 1895 | if (leftover_count == 0) { |
| 1936 | return init_node; | 1896 | return init_node; |
| 1937 | } | 1897 | } |
| ... | @@ -1939,14 +1899,14 @@ fn transInitListExprArray( | ... | @@ -1939,14 +1899,14 @@ fn transInitListExprArray( |
| 1939 | } else null; | 1899 | } else null; |
| 1940 | | 1900 | |
| 1941 | const filler_val_expr = expr.getArrayFiller(); | 1901 | const filler_val_expr = expr.getArrayFiller(); |
| 1942 | const filler_node = try Node.array_filler.create(c.arena, .{ | 1902 | const filler_node = try Tag.array_filler.create(c.arena, .{ |
| 1943 | .type = ty_node, | 1903 | .type = ty_node, |
| 1944 | .filler = try transExpr(c, scope, filler_val_expr, .used, .r_value), | 1904 | .filler = try transExpr(c, scope, filler_val_expr, .used), |
| 1945 | .count = leftover_count, | 1905 | .count = leftover_count, |
| 1946 | }); | 1906 | }); |
| 1947 | | 1907 | |
| 1948 | if (init_node) |some| { | 1908 | if (init_node) |some| { |
| 1949 | return Node.array_cat.create(c.arena, some, filler_node); | 1909 | return Tag.array_cat.create(c.arena, .{ .lhs = some, .rhs = filler_node }); |
| 1950 | } else { | 1910 | } else { |
| 1951 | return filler_node; | 1911 | return filler_node; |
| 1952 | } | 1912 | } |
| ... | @@ -1964,7 +1924,7 @@ fn transInitListExpr( | ... | @@ -1964,7 +1924,7 @@ fn transInitListExpr( |
| 1964 | | 1924 | |
| 1965 | if (qual_type.isRecordType()) { | 1925 | if (qual_type.isRecordType()) { |
| 1966 | return maybeSuppressResult(c, scope, used, try transInitListExprRecord( | 1926 | return maybeSuppressResult(c, scope, used, try transInitListExprRecord( |
| 1967 | rp, | 1927 | c, |
| 1968 | scope, | 1928 | scope, |
| 1969 | source_loc, | 1929 | source_loc, |
| 1970 | expr, | 1930 | expr, |
| ... | @@ -1972,7 +1932,7 @@ fn transInitListExpr( | ... | @@ -1972,7 +1932,7 @@ fn transInitListExpr( |
| 1972 | )); | 1932 | )); |
| 1973 | } else if (qual_type.isArrayType()) { | 1933 | } else if (qual_type.isArrayType()) { |
| 1974 | return maybeSuppressResult(c, scope, used, try transInitListExprArray( | 1934 | return maybeSuppressResult(c, scope, used, try transInitListExprArray( |
| 1975 | rp, | 1935 | c, |
| 1976 | scope, | 1936 | scope, |
| 1977 | source_loc, | 1937 | source_loc, |
| 1978 | expr, | 1938 | expr, |
| ... | @@ -1994,7 +1954,7 @@ fn transZeroInitExpr( | ... | @@ -1994,7 +1954,7 @@ fn transZeroInitExpr( |
| 1994 | .Builtin => { | 1954 | .Builtin => { |
| 1995 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); | 1955 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| 1996 | switch (builtin_ty.getKind()) { | 1956 | switch (builtin_ty.getKind()) { |
| 1997 | .Bool => return Node.false_literal.init(), | 1957 | .Bool => return Tag.false_literal.init(), |
| 1998 | .Char_U, | 1958 | .Char_U, |
| 1999 | .UChar, | 1959 | .UChar, |
| 2000 | .Char_S, | 1960 | .Char_S, |
| ... | @@ -2015,11 +1975,11 @@ fn transZeroInitExpr( | ... | @@ -2015,11 +1975,11 @@ fn transZeroInitExpr( |
| 2015 | .Float128, | 1975 | .Float128, |
| 2016 | .Float16, | 1976 | .Float16, |
| 2017 | .LongDouble, | 1977 | .LongDouble, |
| 2018 | => return Node.zero_literal.init(), | 1978 | => return Tag.zero_literal.init(), |
| 2019 | else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), | 1979 | else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 2020 | } | 1980 | } |
| 2021 | }, | 1981 | }, |
| 2022 | .Pointer => return Node.null_literal.init(), | 1982 | .Pointer => return Tag.null_literal.init(), |
| 2023 | .Typedef => { | 1983 | .Typedef => { |
| 2024 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); | 1984 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| 2025 | const typedef_decl = typedef_ty.getDecl(); | 1985 | const typedef_decl = typedef_ty.getDecl(); |
| ... | @@ -2058,19 +2018,19 @@ fn transIfStmt( | ... | @@ -2058,19 +2018,19 @@ fn transIfStmt( |
| 2058 | var cond_scope = Scope.Condition{ | 2018 | var cond_scope = Scope.Condition{ |
| 2059 | .base = .{ | 2019 | .base = .{ |
| 2060 | .parent = scope, | 2020 | .parent = scope, |
| 2061 | .id = .Condition, | 2021 | .id = .condition, |
| 2062 | }, | 2022 | }, |
| 2063 | }; | 2023 | }; |
| 2064 | defer cond_scope.deinit(); | 2024 | defer cond_scope.deinit(); |
| 2065 | const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond()); | 2025 | const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond()); |
| 2066 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value); | 2026 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used); |
| 2067 | | 2027 | |
| 2068 | const then_body = try transStmt(c, scope, stmt.getThen(), .unused, .r_value); | 2028 | const then_body = try transStmt(c, scope, stmt.getThen(), .unused); |
| 2069 | const else_body = if (stmt.getElse()) |expr| | 2029 | const else_body = if (stmt.getElse()) |expr| |
| 2070 | try transStmt(c, scope, expr, .unused, .r_value) | 2030 | try transStmt(c, scope, expr, .unused) |
| 2071 | else | 2031 | else |
| 2072 | null; | 2032 | null; |
| 2073 | return Node.@"if".create(c.arena, .{ .cond = cond, .then = then_body, .@"else" = else_body }); | 2033 | return Tag.@"if".create(c.arena, .{ .cond = cond, .then = then_body, .@"else" = else_body }); |
| 2074 | } | 2034 | } |
| 2075 | | 2035 | |
| 2076 | fn transWhileLoop( | 2036 | fn transWhileLoop( |
| ... | @@ -2081,19 +2041,19 @@ fn transWhileLoop( | ... | @@ -2081,19 +2041,19 @@ fn transWhileLoop( |
| 2081 | var cond_scope = Scope.Condition{ | 2041 | var cond_scope = Scope.Condition{ |
| 2082 | .base = .{ | 2042 | .base = .{ |
| 2083 | .parent = scope, | 2043 | .parent = scope, |
| 2084 | .id = .Condition, | 2044 | .id = .condition, |
| 2085 | }, | 2045 | }, |
| 2086 | }; | 2046 | }; |
| 2087 | defer cond_scope.deinit(); | 2047 | defer cond_scope.deinit(); |
| 2088 | const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond()); | 2048 | const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond()); |
| 2089 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value); | 2049 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used); |
| 2090 | | 2050 | |
| 2091 | var loop_scope = Scope{ | 2051 | var loop_scope = Scope{ |
| 2092 | .parent = scope, | 2052 | .parent = scope, |
| 2093 | .id = .Loop, | 2053 | .id = .loop, |
| 2094 | }; | 2054 | }; |
| 2095 | const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value); | 2055 | const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused); |
| 2096 | return Node.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = null }); | 2056 | return Tag.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = null }); |
| 2097 | } | 2057 | } |
| 2098 | | 2058 | |
| 2099 | fn transDoWhileLoop( | 2059 | fn transDoWhileLoop( |
| ... | @@ -2103,20 +2063,19 @@ fn transDoWhileLoop( | ... | @@ -2103,20 +2063,19 @@ fn transDoWhileLoop( |
| 2103 | ) TransError!Node { | 2063 | ) TransError!Node { |
| 2104 | var loop_scope = Scope{ | 2064 | var loop_scope = Scope{ |
| 2105 | .parent = scope, | 2065 | .parent = scope, |
| 2106 | .id = .Loop, | 2066 | .id = .loop, |
| 2107 | }; | 2067 | }; |
| 2108 | | 2068 | |
| 2109 | // if (!cond) break; | 2069 | // if (!cond) break; |
| 2110 | const if_node = try transCreateNodeIf(c); | | |
| 2111 | var cond_scope = Scope.Condition{ | 2070 | var cond_scope = Scope.Condition{ |
| 2112 | .base = .{ | 2071 | .base = .{ |
| 2113 | .parent = scope, | 2072 | .parent = scope, |
| 2114 | .id = .Condition, | 2073 | .id = .condition, |
| 2115 | }, | 2074 | }, |
| 2116 | }; | 2075 | }; |
| 2117 | defer cond_scope.deinit(); | 2076 | defer cond_scope.deinit(); |
| 2118 | const cond = try transBoolExpr(c, &cond_scope.base, @ptrCast(*const clang.Expr, stmt.getCond()), .used, .r_value); | 2077 | const cond = try transBoolExpr(c, &cond_scope.base, @ptrCast(*const clang.Expr, stmt.getCond()), .used); |
| 2119 | const if_not_break = try Node.if_not_break.create(c.arena, cond); | 2078 | const if_not_break = try Tag.if_not_break.create(c.arena, cond); |
| 2120 | | 2079 | |
| 2121 | const body_node = if (stmt.getBody().getStmtClass() == .CompoundStmtClass) blk: { | 2080 | const body_node = if (stmt.getBody().getStmtClass() == .CompoundStmtClass) blk: { |
| 2122 | // there's already a block in C, so we'll append our condition to it. | 2081 | // there's already a block in C, so we'll append our condition to it. |
| ... | @@ -2129,8 +2088,8 @@ fn transDoWhileLoop( | ... | @@ -2129,8 +2088,8 @@ fn transDoWhileLoop( |
| 2129 | // zig: b; | 2088 | // zig: b; |
| 2130 | // zig: if (!cond) break; | 2089 | // zig: if (!cond) break; |
| 2131 | // zig: } | 2090 | // zig: } |
| 2132 | const node = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value); | 2091 | const node = try transStmt(c, &loop_scope, stmt.getBody(), .unused); |
| 2133 | const block = node.castTag(.block); | 2092 | const block = node.castTag(.block).?; |
| 2134 | block.data.stmts.len += 1; // This is safe since we reserve one extra space in Scope.Block.complete. | 2093 | block.data.stmts.len += 1; // This is safe since we reserve one extra space in Scope.Block.complete. |
| 2135 | block.data.stmts[block.data.stmts.len - 1] = if_not_break; | 2094 | block.data.stmts[block.data.stmts.len - 1] = if_not_break; |
| 2136 | break :blk node; | 2095 | break :blk node; |
| ... | @@ -2143,12 +2102,12 @@ fn transDoWhileLoop( | ... | @@ -2143,12 +2102,12 @@ fn transDoWhileLoop( |
| 2143 | // zig: a; | 2102 | // zig: a; |
| 2144 | // zig: if (!cond) break; | 2103 | // zig: if (!cond) break; |
| 2145 | // zig: } | 2104 | // zig: } |
| 2146 | const statements = try c.arena.create(Node, 2); | 2105 | const statements = try c.arena.alloc(Node, 2); |
| 2147 | statements[0] = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value); | 2106 | statements[0] = try transStmt(c, &loop_scope, stmt.getBody(), .unused); |
| 2148 | statements[1] = if_not_break; | 2107 | statements[1] = if_not_break; |
| 2149 | break :blk try Node.block.create(c.arena, .{ .label = null, .stmts = statements }); | 2108 | break :blk try Tag.block.create(c.arena, .{ .label = null, .stmts = statements }); |
| 2150 | }; | 2109 | }; |
| 2151 | return Node.while_true.create(c.arena, body_node); | 2110 | return Tag.while_true.create(c.arena, body_node); |
| 2152 | } | 2111 | } |
| 2153 | | 2112 | |
| 2154 | fn transForLoop( | 2113 | fn transForLoop( |
| ... | @@ -2158,7 +2117,7 @@ fn transForLoop( | ... | @@ -2158,7 +2117,7 @@ fn transForLoop( |
| 2158 | ) TransError!Node { | 2117 | ) TransError!Node { |
| 2159 | var loop_scope = Scope{ | 2118 | var loop_scope = Scope{ |
| 2160 | .parent = scope, | 2119 | .parent = scope, |
| 2161 | .id = .Loop, | 2120 | .id = .loop, |
| 2162 | }; | 2121 | }; |
| 2163 | | 2122 | |
| 2164 | var block_scope: ?Scope.Block = null; | 2123 | var block_scope: ?Scope.Block = null; |
| ... | @@ -2167,29 +2126,29 @@ fn transForLoop( | ... | @@ -2167,29 +2126,29 @@ fn transForLoop( |
| 2167 | if (stmt.getInit()) |init| { | 2126 | if (stmt.getInit()) |init| { |
| 2168 | block_scope = try Scope.Block.init(c, scope, false); | 2127 | block_scope = try Scope.Block.init(c, scope, false); |
| 2169 | loop_scope.parent = &block_scope.?.base; | 2128 | loop_scope.parent = &block_scope.?.base; |
| 2170 | const init_node = try transStmt(c, &block_scope.?.base, init, .unused, .r_value); | 2129 | const init_node = try transStmt(c, &block_scope.?.base, init, .unused); |
| 2171 | try block_scope.?.statements.append(init_node); | 2130 | try block_scope.?.statements.append(init_node); |
| 2172 | } | 2131 | } |
| 2173 | var cond_scope = Scope.Condition{ | 2132 | var cond_scope = Scope.Condition{ |
| 2174 | .base = .{ | 2133 | .base = .{ |
| 2175 | .parent = &loop_scope, | 2134 | .parent = &loop_scope, |
| 2176 | .id = .Condition, | 2135 | .id = .condition, |
| 2177 | }, | 2136 | }, |
| 2178 | }; | 2137 | }; |
| 2179 | defer cond_scope.deinit(); | 2138 | defer cond_scope.deinit(); |
| 2180 | | 2139 | |
| 2181 | const cond = if (stmt.getCond()) |cond| | 2140 | const cond = if (stmt.getCond()) |cond| |
| 2182 | try transBoolExpr(c, &cond_scope.base, cond, .used, .r_value) | 2141 | try transBoolExpr(c, &cond_scope.base, cond, .used) |
| 2183 | else | 2142 | else |
| 2184 | Node.true_literal.init(); | 2143 | Tag.true_literal.init(); |
| 2185 | | 2144 | |
| 2186 | const cont_expr = if (stmt.getInc()) |incr| | 2145 | const cont_expr = if (stmt.getInc()) |incr| |
| 2187 | try transExpr(c, &cond_scope.base, incr, .unused, .r_value) | 2146 | try transExpr(c, &cond_scope.base, incr, .unused) |
| 2188 | else | 2147 | else |
| 2189 | null; | 2148 | null; |
| 2190 | | 2149 | |
| 2191 | const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value); | 2150 | const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused); |
| 2192 | const while_node = try Node.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = cont_expr }); | 2151 | const while_node = try Tag.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = cont_expr }); |
| 2193 | if (block_scope) |*bs| { | 2152 | if (block_scope) |*bs| { |
| 2194 | try bs.statements.append(while_node); | 2153 | try bs.statements.append(while_node); |
| 2195 | return try bs.complete(c); | 2154 | return try bs.complete(c); |
| ... | @@ -2206,13 +2165,14 @@ fn transSwitch( | ... | @@ -2206,13 +2165,14 @@ fn transSwitch( |
| 2206 | var cond_scope = Scope.Condition{ | 2165 | var cond_scope = Scope.Condition{ |
| 2207 | .base = .{ | 2166 | .base = .{ |
| 2208 | .parent = scope, | 2167 | .parent = scope, |
| 2209 | .id = .Condition, | 2168 | .id = .condition, |
| 2210 | }, | 2169 | }, |
| 2211 | }; | 2170 | }; |
| 2212 | defer cond_scope.deinit(); | 2171 | defer cond_scope.deinit(); |
| 2213 | const switch_expr = try transExpr(c, &cond_scope.base, stmt.getCond(), .used, .r_value); | 2172 | const switch_expr = try transExpr(c, &cond_scope.base, stmt.getCond(), .used); |
| 2214 | const switch_node = try c.arena.create(ast.Payload.Switch); | 2173 | const switch_node = try c.arena.create(ast.Payload.Switch); |
| 2215 | switch_node.* = .{ | 2174 | switch_node.* = .{ |
| | 2175 | .base = .{ .tag = .@"switch" }, |
| 2216 | .data = .{ | 2176 | .data = .{ |
| 2217 | .cond = switch_expr, | 2177 | .cond = switch_expr, |
| 2218 | .cases = undefined, // set later | 2178 | .cases = undefined, // set later |
| ... | @@ -2221,7 +2181,7 @@ fn transSwitch( | ... | @@ -2221,7 +2181,7 @@ fn transSwitch( |
| 2221 | | 2181 | |
| 2222 | var switch_scope = Scope.Switch{ | 2182 | var switch_scope = Scope.Switch{ |
| 2223 | .base = .{ | 2183 | .base = .{ |
| 2224 | .id = .Switch, | 2184 | .id = .@"switch", |
| 2225 | .parent = scope, | 2185 | .parent = scope, |
| 2226 | }, | 2186 | }, |
| 2227 | .cases = std.ArrayList(Node).init(c.gpa), | 2187 | .cases = std.ArrayList(Node).init(c.gpa), |
| ... | @@ -2229,11 +2189,7 @@ fn transSwitch( | ... | @@ -2229,11 +2189,7 @@ fn transSwitch( |
| 2229 | .default_label = null, | 2189 | .default_label = null, |
| 2230 | .switch_label = null, | 2190 | .switch_label = null, |
| 2231 | }; | 2191 | }; |
| 2232 | defer { | 2192 | defer switch_scope.cases.deinit(); |
| 2233 | switch_node.data.cases = try c.arena.dupe(Node, switch_scope.cases.items); | | |
| 2234 | switch_node.data.default = switch_scope.switch_label; | | |
| 2235 | switch_scope.cases.deinit(); | | |
| 2236 | } | | |
| 2237 | | 2193 | |
| 2238 | // tmp block that all statements will go before being picked up by a case or default | 2194 | // tmp block that all statements will go before being picked up by a case or default |
| 2239 | var block_scope = try Scope.Block.init(c, &switch_scope.base, false); | 2195 | var block_scope = try Scope.Block.init(c, &switch_scope.base, false); |
| ... | @@ -2246,7 +2202,7 @@ fn transSwitch( | ... | @@ -2246,7 +2202,7 @@ fn transSwitch( |
| 2246 | switch_scope.pending_block = try Scope.Block.init(c, scope, false); | 2202 | switch_scope.pending_block = try Scope.Block.init(c, scope, false); |
| 2247 | try switch_scope.pending_block.statements.append(Node.initPayload(&switch_node.base)); | 2203 | try switch_scope.pending_block.statements.append(Node.initPayload(&switch_node.base)); |
| 2248 | | 2204 | |
| 2249 | const last = try transStmt(c, &block_scope.base, stmt.getBody(), .unused, .r_value); | 2205 | const last = try transStmt(c, &block_scope.base, stmt.getBody(), .unused); |
| 2250 | | 2206 | |
| 2251 | // take all pending statements | 2207 | // take all pending statements |
| 2252 | const last_block_stmts = last.castTag(.block).?.data.stmts; | 2208 | const last_block_stmts = last.castTag(.block).?.data.stmts; |
| ... | @@ -2264,13 +2220,14 @@ fn transSwitch( | ... | @@ -2264,13 +2220,14 @@ fn transSwitch( |
| 2264 | switch_scope.pending_block.label = l; | 2220 | switch_scope.pending_block.label = l; |
| 2265 | } | 2221 | } |
| 2266 | if (switch_scope.default_label == null) { | 2222 | if (switch_scope.default_label == null) { |
| 2267 | const else_prong = try Node.switch_else.create( | 2223 | const else_prong = try Tag.switch_else.create( |
| 2268 | c.arena, | 2224 | c.arena, |
| 2269 | try Node.@"break".create(c.arena, switch_scope.switch_label.?), | 2225 | try Tag.@"break".create(c.arena, switch_scope.switch_label.?), |
| 2270 | ); | 2226 | ); |
| 2271 | switch_scope.cases.append(else_prong); | 2227 | try switch_scope.cases.append(else_prong); |
| 2272 | } | 2228 | } |
| 2273 | | 2229 | |
| | 2230 | switch_node.data.cases = try c.arena.dupe(Node, switch_scope.cases.items); |
| 2274 | const result_node = try switch_scope.pending_block.complete(c); | 2231 | const result_node = try switch_scope.pending_block.complete(c); |
| 2275 | switch_scope.pending_block.deinit(); | 2232 | switch_scope.pending_block.deinit(); |
| 2276 | return result_node; | 2233 | return result_node; |
| ... | @@ -2286,18 +2243,18 @@ fn transCase( | ... | @@ -2286,18 +2243,18 @@ fn transCase( |
| 2286 | const label = try block_scope.makeMangledName(c, "case"); | 2243 | const label = try block_scope.makeMangledName(c, "case"); |
| 2287 | | 2244 | |
| 2288 | const expr = if (stmt.getRHS()) |rhs| blk: { | 2245 | const expr = if (stmt.getRHS()) |rhs| blk: { |
| 2289 | const lhs_node = try transExpr(c, scope, stmt.getLHS(), .used, .r_value); | 2246 | const lhs_node = try transExpr(c, scope, stmt.getLHS(), .used); |
| 2290 | const rhs_node = try transExpr(c, scope, rhs, .used, .r_value); | 2247 | const rhs_node = try transExpr(c, scope, rhs, .used); |
| 2291 | | 2248 | |
| 2292 | break :blk Node.ellipsis3.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); | 2249 | break :blk try Tag.ellipsis3.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); |
| 2293 | } else | 2250 | } else |
| 2294 | try transExpr(c, scope, stmt.getLHS(), .used, .r_value); | 2251 | try transExpr(c, scope, stmt.getLHS(), .used); |
| 2295 | | 2252 | |
| 2296 | const switch_prong = try Node.switch_prong.create( | 2253 | const switch_prong = try Tag.switch_prong.create(c.arena, .{ |
| 2297 | c.arena, | 2254 | .lhs = expr, |
| 2298 | try Node.@"break".create(c.arena, label), | 2255 | .rhs = try Tag.@"break".create(c.arena, label), |
| 2299 | ); | 2256 | }); |
| 2300 | switch_scope.cases.append(switch_prong); | 2257 | try switch_scope.cases.append(switch_prong); |
| 2301 | | 2258 | |
| 2302 | switch_scope.pending_block.label = label; | 2259 | switch_scope.pending_block.label = label; |
| 2303 | | 2260 | |
| ... | @@ -2311,7 +2268,7 @@ fn transCase( | ... | @@ -2311,7 +2268,7 @@ fn transCase( |
| 2311 | | 2268 | |
| 2312 | try switch_scope.pending_block.statements.append(pending_node); | 2269 | try switch_scope.pending_block.statements.append(pending_node); |
| 2313 | | 2270 | |
| 2314 | return transStmt(c, scope, stmt.getSubStmt(), .unused, .r_value); | 2271 | return transStmt(c, scope, stmt.getSubStmt(), .unused); |
| 2315 | } | 2272 | } |
| 2316 | | 2273 | |
| 2317 | fn transDefault( | 2274 | fn transDefault( |
| ... | @@ -2323,12 +2280,12 @@ fn transDefault( | ... | @@ -2323,12 +2280,12 @@ fn transDefault( |
| 2323 | const switch_scope = scope.getSwitch(); | 2280 | const switch_scope = scope.getSwitch(); |
| 2324 | switch_scope.default_label = try block_scope.makeMangledName(c, "default"); | 2281 | switch_scope.default_label = try block_scope.makeMangledName(c, "default"); |
| 2325 | | 2282 | |
| 2326 | const else_prong = try Node.switch_else.create( | 2283 | const else_prong = try Tag.switch_else.create( |
| 2327 | c.arena, | 2284 | c.arena, |
| 2328 | try Node.@"break".create(c.arena, switch_scope.default_label.?), | 2285 | try Tag.@"break".create(c.arena, switch_scope.default_label.?), |
| 2329 | ); | 2286 | ); |
| 2330 | switch_scope.cases.append(else_prong); | 2287 | try switch_scope.cases.append(else_prong); |
| 2331 | switch_scope.pending_block.label = try appendIdentifier(c, switch_scope.default_label.?); | 2288 | switch_scope.pending_block.label = switch_scope.default_label.?; |
| 2332 | | 2289 | |
| 2333 | // take all pending statements | 2290 | // take all pending statements |
| 2334 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); | 2291 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| ... | @@ -2339,7 +2296,7 @@ fn transDefault( | ... | @@ -2339,7 +2296,7 @@ fn transDefault( |
| 2339 | switch_scope.pending_block = try Scope.Block.init(c, scope, false); | 2296 | switch_scope.pending_block = try Scope.Block.init(c, scope, false); |
| 2340 | try switch_scope.pending_block.statements.append(pending_node); | 2297 | try switch_scope.pending_block.statements.append(pending_node); |
| 2341 | | 2298 | |
| 2342 | return transStmt(c, scope, stmt.getSubStmt(), .unused, .r_value); | 2299 | return transStmt(c, scope, stmt.getSubStmt(), .unused); |
| 2343 | } | 2300 | } |
| 2344 | | 2301 | |
| 2345 | fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node { | 2302 | fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node { |
| ... | @@ -2352,7 +2309,7 @@ fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: | ... | @@ -2352,7 +2309,7 @@ fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: |
| 2352 | // See comment in `transIntegerLiteral` for why this code is here. | 2309 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2353 | // @as(T, x) | 2310 | // @as(T, x) |
| 2354 | const expr_base = @ptrCast(*const clang.Expr, expr); | 2311 | const expr_base = @ptrCast(*const clang.Expr, expr); |
| 2355 | const as_node = try Node.as.create(c.arena, .{ | 2312 | const as_node = try Tag.as.create(c.arena, .{ |
| 2356 | .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()), | 2313 | .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()), |
| 2357 | .rhs = try transCreateNodeAPInt(c, result.Val.getInt()), | 2314 | .rhs = try transCreateNodeAPInt(c, result.Val.getInt()), |
| 2358 | }); | 2315 | }); |
| ... | @@ -2369,10 +2326,10 @@ fn transPredefinedExpr(c: *Context, scope: *Scope, expr: *const clang.Predefined | ... | @@ -2369,10 +2326,10 @@ fn transPredefinedExpr(c: *Context, scope: *Scope, expr: *const clang.Predefined |
| 2369 | } | 2326 | } |
| 2370 | | 2327 | |
| 2371 | fn transCreateCharLitNode(c: *Context, narrow: bool, val: u32) TransError!Node { | 2328 | fn transCreateCharLitNode(c: *Context, narrow: bool, val: u32) TransError!Node { |
| 2372 | return Node.char_literal.create(c.arena, if (narrow) | 2329 | return Tag.char_literal.create(c.arena, if (narrow) |
| 2373 | try std.fmt.bufPrint(c.arena, "'{}'", .{std.zig.fmtEscapes(&.{@intCast(u8, val)})}) | 2330 | try std.fmt.allocPrint(c.arena, "'{s}'", .{std.zig.fmtEscapes(&.{@intCast(u8, val)})}) |
| 2374 | else | 2331 | else |
| 2375 | try std.fmt.bufPrint(c.arena, "'\\u{{{x}}}'", .{val})); | 2332 | try std.fmt.allocPrint(c.arena, "'\\u{{{x}}}'", .{val})); |
| 2376 | } | 2333 | } |
| 2377 | | 2334 | |
| 2378 | fn transCharLiteral( | 2335 | fn transCharLiteral( |
| ... | @@ -2398,7 +2355,7 @@ fn transCharLiteral( | ... | @@ -2398,7 +2355,7 @@ fn transCharLiteral( |
| 2398 | // See comment in `transIntegerLiteral` for why this code is here. | 2355 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2399 | // @as(T, x) | 2356 | // @as(T, x) |
| 2400 | const expr_base = @ptrCast(*const clang.Expr, stmt); | 2357 | const expr_base = @ptrCast(*const clang.Expr, stmt); |
| 2401 | const as_node = Node.as.create(c.arena, .{ | 2358 | const as_node = try Tag.as.create(c.arena, .{ |
| 2402 | .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()), | 2359 | .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()), |
| 2403 | .rhs = int_lit_node, | 2360 | .rhs = int_lit_node, |
| 2404 | }); | 2361 | }); |
| ... | @@ -2416,12 +2373,12 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used: | ... | @@ -2416,12 +2373,12 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used: |
| 2416 | var it = comp.body_begin(); | 2373 | var it = comp.body_begin(); |
| 2417 | const end_it = comp.body_end(); | 2374 | const end_it = comp.body_end(); |
| 2418 | while (it != end_it - 1) : (it += 1) { | 2375 | while (it != end_it - 1) : (it += 1) { |
| 2419 | const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value); | 2376 | const result = try transStmt(c, &block_scope.base, it[0], .unused); |
| 2420 | try block_scope.statements.append(result); | 2377 | try block_scope.statements.append(result); |
| 2421 | } | 2378 | } |
| 2422 | const break_node = try Node.break_val.create(c.arena, .{ | 2379 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 2423 | .label = block_scope.label, | 2380 | .label = block_scope.label, |
| 2424 | .val = try transStmt(c, &block_scope.base, it[0], .used, .r_value), | 2381 | .val = try transStmt(c, &block_scope.base, it[0], .used), |
| 2425 | }); | 2382 | }); |
| 2426 | try block_scope.statements.append(break_node); | 2383 | try block_scope.statements.append(break_node); |
| 2427 | const res = try block_scope.complete(c); | 2384 | const res = try block_scope.complete(c); |
| ... | @@ -2429,10 +2386,10 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used: | ... | @@ -2429,10 +2386,10 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used: |
| 2429 | } | 2386 | } |
| 2430 | | 2387 | |
| 2431 | fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, result_used: ResultUsed) TransError!Node { | 2388 | fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, result_used: ResultUsed) TransError!Node { |
| 2432 | var container_node = try transExpr(c, scope, stmt.getBase(), .used, .r_value); | 2389 | var container_node = try transExpr(c, scope, stmt.getBase(), .used); |
| 2433 | | 2390 | |
| 2434 | if (stmt.isArrow()) { | 2391 | if (stmt.isArrow()) { |
| 2435 | container_node = try Node.deref.create(c.arena, container_node); | 2392 | container_node = try Tag.deref.create(c.arena, container_node); |
| 2436 | } | 2393 | } |
| 2437 | | 2394 | |
| 2438 | const member_decl = stmt.getMemberDecl(); | 2395 | const member_decl = stmt.getMemberDecl(); |
| ... | @@ -2450,9 +2407,9 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re | ... | @@ -2450,9 +2407,9 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re |
| 2450 | const decl = @ptrCast(*const clang.NamedDecl, member_decl); | 2407 | const decl = @ptrCast(*const clang.NamedDecl, member_decl); |
| 2451 | break :blk try c.str(decl.getName_bytes_begin()); | 2408 | break :blk try c.str(decl.getName_bytes_begin()); |
| 2452 | }; | 2409 | }; |
| 2453 | const ident = try Node.identifier.create(c.arena, name); | 2410 | const ident = try Tag.identifier.create(c.arena, name); |
| 2454 | | 2411 | |
| 2455 | const node = try Node.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident}); | 2412 | const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident }); |
| 2456 | return maybeSuppressResult(c, scope, result_used, node); | 2413 | return maybeSuppressResult(c, scope, result_used, node); |
| 2457 | } | 2414 | } |
| 2458 | | 2415 | |
| ... | @@ -2469,7 +2426,7 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip | ... | @@ -2469,7 +2426,7 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip |
| 2469 | } | 2426 | } |
| 2470 | } | 2427 | } |
| 2471 | | 2428 | |
| 2472 | const container_node = try transExpr(c, scope, base_stmt, .used, .r_value); | 2429 | const container_node = try transExpr(c, scope, base_stmt, .used); |
| 2473 | | 2430 | |
| 2474 | // cast if the index is long long or signed | 2431 | // cast if the index is long long or signed |
| 2475 | const subscr_expr = stmt.getIdx(); | 2432 | const subscr_expr = stmt.getIdx(); |
| ... | @@ -2477,14 +2434,17 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip | ... | @@ -2477,14 +2434,17 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip |
| 2477 | const is_longlong = cIsLongLongInteger(qt); | 2434 | const is_longlong = cIsLongLongInteger(qt); |
| 2478 | const is_signed = cIsSignedInteger(qt); | 2435 | const is_signed = cIsSignedInteger(qt); |
| 2479 | | 2436 | |
| 2480 | | 2437 | const rhs = if (is_longlong or is_signed) blk: { |
| 2481 | const node = try Node.array_access.create(c.arena, .{ .lhs = container_node, .rhs = if (is_longlong or is_signed) blk: { | | |
| 2482 | const cast_node = try c.createBuiltinCall("@intCast", 2); | | |
| 2483 | // check if long long first so that signed long long doesn't just become unsigned long long | 2438 | // check if long long first so that signed long long doesn't just become unsigned long long |
| 2484 | var typeid_node = if (is_longlong) try transCreateNodeIdentifier(c, "usize") else try transQualTypeIntWidthOf(c, qt, false); | 2439 | var typeid_node = if (is_longlong) try Tag.identifier.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, qt, false); |
| 2485 | break :blk try Node.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used, .r_value)}); | 2440 | break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) }); |
| 2486 | } else | 2441 | } else |
| 2487 | try transExpr(c, scope, subscr_expr, .used, .r_value)}); | 2442 | try transExpr(c, scope, subscr_expr, .used); |
| | 2443 | |
| | 2444 | const node = try Tag.array_access.create(c.arena, .{ |
| | 2445 | .lhs = container_node, |
| | 2446 | .rhs = rhs, |
| | 2447 | }); |
| 2488 | return maybeSuppressResult(c, scope, result_used, node); | 2448 | return maybeSuppressResult(c, scope, result_used, node); |
| 2489 | } | 2449 | } |
| 2490 | | 2450 | |
| ... | @@ -2522,23 +2482,23 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool { | ... | @@ -2522,23 +2482,23 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool { |
| 2522 | | 2482 | |
| 2523 | fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result_used: ResultUsed) TransError!Node { | 2483 | fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result_used: ResultUsed) TransError!Node { |
| 2524 | const callee = stmt.getCallee(); | 2484 | const callee = stmt.getCallee(); |
| 2525 | var raw_fn_expr = try transExpr(c, scope, callee, .used, .r_value); | 2485 | var raw_fn_expr = try transExpr(c, scope, callee, .used); |
| 2526 | | 2486 | |
| 2527 | var is_ptr = false; | 2487 | var is_ptr = false; |
| 2528 | const fn_ty = qualTypeGetFnProto(callee.getType(), &is_ptr); | 2488 | const fn_ty = qualTypeGetFnProto(callee.getType(), &is_ptr); |
| 2529 | | 2489 | |
| 2530 | const fn_expr = if (is_ptr and fn_ty != null and !cIsFunctionDeclRef(callee)) | 2490 | const fn_expr = if (is_ptr and fn_ty != null and !cIsFunctionDeclRef(callee)) |
| 2531 | try transCreateNodeUnwrapNull(rp.c, raw_fn_expr) | 2491 | try Tag.unwrap.create(c.arena, raw_fn_expr) |
| 2532 | else | 2492 | else |
| 2533 | raw_fn_expr; | 2493 | raw_fn_expr; |
| 2534 | | 2494 | |
| 2535 | const num_args = stmt.getNumArgs(); | 2495 | const num_args = stmt.getNumArgs(); |
| 2536 | const call_params = try c.arena.alloc(Node, num_args); | 2496 | const args = try c.arena.alloc(Node, num_args); |
| 2537 | | 2497 | |
| 2538 | const args = stmt.getArgs(); | 2498 | const c_args = stmt.getArgs(); |
| 2539 | var i: usize = 0; | 2499 | var i: usize = 0; |
| 2540 | while (i < num_args) : (i += 1) { | 2500 | while (i < num_args) : (i += 1) { |
| 2541 | var call_param = try transExpr(c, scope, args[i], .used, .r_value); | 2501 | var arg = try transExpr(c, scope, c_args[i], .used); |
| 2542 | | 2502 | |
| 2543 | // In C the result type of a boolean expression is int. If this result is passed as | 2503 | // In C the result type of a boolean expression is int. If this result is passed as |
| 2544 | // an argument to a function whose parameter is also int, there is no cast. Therefore | 2504 | // an argument to a function whose parameter is also int, there is no cast. Therefore |
| ... | @@ -2549,17 +2509,17 @@ fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result | ... | @@ -2549,17 +2509,17 @@ fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result |
| 2549 | const param_count = fn_proto.getNumParams(); | 2509 | const param_count = fn_proto.getNumParams(); |
| 2550 | if (i < param_count) { | 2510 | if (i < param_count) { |
| 2551 | const param_qt = fn_proto.getParamType(@intCast(c_uint, i)); | 2511 | const param_qt = fn_proto.getParamType(@intCast(c_uint, i)); |
| 2552 | if (isBoolRes(call_param) and cIsNativeInt(param_qt)) { | 2512 | if (isBoolRes(arg) and cIsNativeInt(param_qt)) { |
| 2553 | call_param = try Node.bool_to_int.create(c.arena, call_param); | 2513 | arg = try Tag.bool_to_int.create(c.arena, arg); |
| 2554 | } | 2514 | } |
| 2555 | } | 2515 | } |
| 2556 | }, | 2516 | }, |
| 2557 | else => {}, | 2517 | else => {}, |
| 2558 | } | 2518 | } |
| 2559 | } | 2519 | } |
| 2560 | call_params[i] = call_param; | 2520 | args[i] = arg; |
| 2561 | } | 2521 | } |
| 2562 | const node = try Node.call.create(c.arena, .{ .lhs = fn_expr, .args = call_params }); | 2522 | const node = try Tag.call.create(c.arena, .{ .lhs = fn_expr, .args = args }); |
| 2563 | if (fn_ty) |ty| { | 2523 | if (fn_ty) |ty| { |
| 2564 | const canon = ty.getReturnType().getCanonicalType(); | 2524 | const canon = ty.getReturnType().getCanonicalType(); |
| 2565 | const ret_ty = canon.getTypePtr(); | 2525 | const ret_ty = canon.getTypePtr(); |
| ... | @@ -2609,17 +2569,17 @@ fn transUnaryExprOrTypeTraitExpr( | ... | @@ -2609,17 +2569,17 @@ fn transUnaryExprOrTypeTraitExpr( |
| 2609 | result_used: ResultUsed, | 2569 | result_used: ResultUsed, |
| 2610 | ) TransError!Node { | 2570 | ) TransError!Node { |
| 2611 | const loc = stmt.getBeginLoc(); | 2571 | const loc = stmt.getBeginLoc(); |
| 2612 | const type_node = try transQualType(rp, stmt.getTypeOfArgument(), loc); | 2572 | const type_node = try transQualType(c, stmt.getTypeOfArgument(), loc); |
| 2613 | | 2573 | |
| 2614 | const kind = stmt.getKind(); | 2574 | const kind = stmt.getKind(); |
| 2615 | switch (kind) { | 2575 | switch (kind) { |
| 2616 | .SizeOf => return Node.sizeof.create(c.arena, type_node), | 2576 | .SizeOf => return Tag.sizeof.create(c.arena, type_node), |
| 2617 | .AlignOf => return Node.alignof.create(c.arena, type_node), | 2577 | .AlignOf => return Tag.alignof.create(c.arena, type_node), |
| 2618 | .PreferredAlignOf, | 2578 | .PreferredAlignOf, |
| 2619 | .VecStep, | 2579 | .VecStep, |
| 2620 | .OpenMPRequiredSimdAlign, | 2580 | .OpenMPRequiredSimdAlign, |
| 2621 | => return revertAndWarn( | 2581 | => return fail( |
| 2622 | rp, | 2582 | c, |
| 2623 | error.UnsupportedTranslation, | 2583 | error.UnsupportedTranslation, |
| 2624 | loc, | 2584 | loc, |
| 2625 | "Unsupported type trait kind {}", | 2585 | "Unsupported type trait kind {}", |
| ... | @@ -2642,53 +2602,54 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat | ... | @@ -2642,53 +2602,54 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat |
| 2642 | const op_expr = stmt.getSubExpr(); | 2602 | const op_expr = stmt.getSubExpr(); |
| 2643 | switch (stmt.getOpcode()) { | 2603 | switch (stmt.getOpcode()) { |
| 2644 | .PostInc => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2604 | .PostInc => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2645 | return transCreatePostCrement(c, scope, stmt, .assign_add_wrap, used) | 2605 | return transCreatePostCrement(c, scope, stmt, .add_wrap_assign, used) |
| 2646 | else | 2606 | else |
| 2647 | return transCreatePostCrement(c, scope, stmt, .assign_add, used), | 2607 | return transCreatePostCrement(c, scope, stmt, .add_assign, used), |
| 2648 | .PostDec => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2608 | .PostDec => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2649 | return transCreatePostCrement(c, scope, stmt, .assign_sub_wrap, used) | 2609 | return transCreatePostCrement(c, scope, stmt, .sub_wrap_assign, used) |
| 2650 | else | 2610 | else |
| 2651 | return transCreatePostCrement(c, scope, stmt, .assign_sub, used), | 2611 | return transCreatePostCrement(c, scope, stmt, .sub_assign, used), |
| 2652 | .PreInc => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2612 | .PreInc => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2653 | return transCreatePreCrement(c, scope, stmt, .assign_add_wrap, used) | 2613 | return transCreatePreCrement(c, scope, stmt, .add_wrap_assign, used) |
| 2654 | else | 2614 | else |
| 2655 | return transCreatePreCrement(c, scope, stmt, .assign_add, used), | 2615 | return transCreatePreCrement(c, scope, stmt, .add_assign, used), |
| 2656 | .PreDec => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2616 | .PreDec => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2657 | return transCreatePreCrement(c, scope, stmt, .assign_sub_wrap, used) | 2617 | return transCreatePreCrement(c, scope, stmt, .sub_wrap_assign, used) |
| 2658 | else | 2618 | else |
| 2659 | return transCreatePreCrement(c, scope, stmt, .assign_sub, used), | 2619 | return transCreatePreCrement(c, scope, stmt, .sub_assign, used), |
| 2660 | .AddrOf => { | 2620 | .AddrOf => { |
| 2661 | if (cIsFunctionDeclRef(op_expr)) { | 2621 | if (cIsFunctionDeclRef(op_expr)) { |
| 2662 | return transExpr(rp, scope, op_expr, used, .r_value); | 2622 | return transExpr(c, scope, op_expr, used); |
| 2663 | } | 2623 | } |
| 2664 | return Node.address_of.create(c.arena, try transExpr(c, scope, op_expr, used, .r_value)); | 2624 | return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used)); |
| 2665 | }, | 2625 | }, |
| 2666 | .Deref => { | 2626 | .Deref => { |
| 2667 | const node = try transExpr(c, scope, op_expr, used, .r_value); | 2627 | const node = try transExpr(c, scope, op_expr, used); |
| 2668 | var is_ptr = false; | 2628 | var is_ptr = false; |
| 2669 | const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr); | 2629 | const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr); |
| 2670 | if (fn_ty != null and is_ptr) | 2630 | if (fn_ty != null and is_ptr) |
| 2671 | return node; | 2631 | return node; |
| 2672 | return Node.unwrap_deref.create(c.arena, node); | 2632 | const unwrapped = try Tag.unwrap.create(c.arena, node); |
| | 2633 | return Tag.deref.create(c.arena, unwrapped); |
| 2673 | }, | 2634 | }, |
| 2674 | .Plus => return transExpr(c, scope, op_expr, used, .r_value), | 2635 | .Plus => return transExpr(c, scope, op_expr, used), |
| 2675 | .Minus => { | 2636 | .Minus => { |
| 2676 | if (!qualTypeHasWrappingOverflow(op_expr.getType())) { | 2637 | if (!qualTypeHasWrappingOverflow(op_expr.getType())) { |
| 2677 | return Node.negate.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value)); | 2638 | return Tag.negate.create(c.arena, try transExpr(c, scope, op_expr, .used)); |
| 2678 | } else if (cIsUnsignedInteger(op_expr.getType())) { | 2639 | } else if (cIsUnsignedInteger(op_expr.getType())) { |
| 2679 | // use -% x for unsigned integers | 2640 | // use -% x for unsigned integers |
| 2680 | return Node.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value)); | 2641 | return Tag.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used)); |
| 2681 | } else | 2642 | } else |
| 2682 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "C negation with non float non integer", .{}); | 2643 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "C negation with non float non integer", .{}); |
| 2683 | }, | 2644 | }, |
| 2684 | .Not => { | 2645 | .Not => { |
| 2685 | return Node.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value)); | 2646 | return Tag.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used)); |
| 2686 | }, | 2647 | }, |
| 2687 | .LNot => { | 2648 | .LNot => { |
| 2688 | return Node.not.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value)); | 2649 | return Tag.not.create(c.arena, try transExpr(c, scope, op_expr, .used)); |
| 2689 | }, | 2650 | }, |
| 2690 | .Extension => { | 2651 | .Extension => { |
| 2691 | return transExpr(c, scope, stmt.getSubExpr(), used, .l_value); | 2652 | return transExpr(c, scope, stmt.getSubExpr(), used); |
| 2692 | }, | 2653 | }, |
| 2693 | else => return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "unsupported C translation {}", .{stmt.getOpcode()}), | 2654 | else => return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "unsupported C translation {}", .{stmt.getOpcode()}), |
| 2694 | } | 2655 | } |
| ... | @@ -2698,7 +2659,7 @@ fn transCreatePreCrement( | ... | @@ -2698,7 +2659,7 @@ fn transCreatePreCrement( |
| 2698 | c: *Context, | 2659 | c: *Context, |
| 2699 | scope: *Scope, | 2660 | scope: *Scope, |
| 2700 | stmt: *const clang.UnaryOperator, | 2661 | stmt: *const clang.UnaryOperator, |
| 2701 | op: Node.Tag, | 2662 | op: Tag, |
| 2702 | used: ResultUsed, | 2663 | used: ResultUsed, |
| 2703 | ) TransError!Node { | 2664 | ) TransError!Node { |
| 2704 | const op_expr = stmt.getSubExpr(); | 2665 | const op_expr = stmt.getSubExpr(); |
| ... | @@ -2707,8 +2668,8 @@ fn transCreatePreCrement( | ... | @@ -2707,8 +2668,8 @@ fn transCreatePreCrement( |
| 2707 | // common case | 2668 | // common case |
| 2708 | // c: ++expr | 2669 | // c: ++expr |
| 2709 | // zig: expr += 1 | 2670 | // zig: expr += 1 |
| 2710 | const lhs = try transExpr(c, scope, op_expr, .used, .r_value); | 2671 | const lhs = try transExpr(c, scope, op_expr, .used); |
| 2711 | const rhs = Node.one_literal.init(); | 2672 | const rhs = Tag.one_literal.init(); |
| 2712 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used); | 2673 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used); |
| 2713 | } | 2674 | } |
| 2714 | // worst case | 2675 | // worst case |
| ... | @@ -2722,17 +2683,17 @@ fn transCreatePreCrement( | ... | @@ -2722,17 +2683,17 @@ fn transCreatePreCrement( |
| 2722 | defer block_scope.deinit(); | 2683 | defer block_scope.deinit(); |
| 2723 | const ref = try block_scope.makeMangledName(c, "ref"); | 2684 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2724 | | 2685 | |
| 2725 | const expr = try transExpr(c, scope, op_expr, .used, .r_value); | 2686 | const expr = try transExpr(c, scope, op_expr, .used); |
| 2726 | const addr_of = try Node.address_of.create(c.arena, expr); | 2687 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2727 | const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of}); | 2688 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2728 | try block_scope.statements.append(ref_decl); | 2689 | try block_scope.statements.append(ref_decl); |
| 2729 | | 2690 | |
| 2730 | const lhs_node = try Node.identifier.create(c.arena, ref); | 2691 | const lhs_node = try Tag.identifier.create(c.arena, ref); |
| 2731 | const ref_node = try Node.deref.create(c.arena, lhs_node); | 2692 | const ref_node = try Tag.deref.create(c.arena, lhs_node); |
| 2732 | const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Node.one_literal.init(), .used); | 2693 | const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used); |
| 2733 | try block_scope.statements.append(node); | 2694 | try block_scope.statements.append(node); |
| 2734 | | 2695 | |
| 2735 | const break_node = try Node.break_val.create(c.arena, .{ | 2696 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 2736 | .label = block_scope.label, | 2697 | .label = block_scope.label, |
| 2737 | .val = ref_node, | 2698 | .val = ref_node, |
| 2738 | }); | 2699 | }); |
| ... | @@ -2744,7 +2705,7 @@ fn transCreatePostCrement( | ... | @@ -2744,7 +2705,7 @@ fn transCreatePostCrement( |
| 2744 | c: *Context, | 2705 | c: *Context, |
| 2745 | scope: *Scope, | 2706 | scope: *Scope, |
| 2746 | stmt: *const clang.UnaryOperator, | 2707 | stmt: *const clang.UnaryOperator, |
| 2747 | op: Node.Tag, | 2708 | op: Tag, |
| 2748 | used: ResultUsed, | 2709 | used: ResultUsed, |
| 2749 | ) TransError!Node { | 2710 | ) TransError!Node { |
| 2750 | const op_expr = stmt.getSubExpr(); | 2711 | const op_expr = stmt.getSubExpr(); |
| ... | @@ -2753,8 +2714,8 @@ fn transCreatePostCrement( | ... | @@ -2753,8 +2714,8 @@ fn transCreatePostCrement( |
| 2753 | // common case | 2714 | // common case |
| 2754 | // c: expr++ | 2715 | // c: expr++ |
| 2755 | // zig: expr += 1 | 2716 | // zig: expr += 1 |
| 2756 | const lhs = try transExpr(c, scope, op_expr, .used, .r_value); | 2717 | const lhs = try transExpr(c, scope, op_expr, .used); |
| 2757 | const rhs = Node.one_literal.init(); | 2718 | const rhs = Tag.one_literal.init(); |
| 2758 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used); | 2719 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used); |
| 2759 | } | 2720 | } |
| 2760 | // worst case | 2721 | // worst case |
| ... | @@ -2769,24 +2730,24 @@ fn transCreatePostCrement( | ... | @@ -2769,24 +2730,24 @@ fn transCreatePostCrement( |
| 2769 | defer block_scope.deinit(); | 2730 | defer block_scope.deinit(); |
| 2770 | const ref = try block_scope.makeMangledName(c, "ref"); | 2731 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2771 | | 2732 | |
| 2772 | const expr = try transExpr(c, scope, op_expr, .used, .r_value); | 2733 | const expr = try transExpr(c, scope, op_expr, .used); |
| 2773 | const addr_of = try Node.address_of.create(c.arena, expr); | 2734 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2774 | const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of}); | 2735 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2775 | try block_scope.statements.append(ref_decl); | 2736 | try block_scope.statements.append(ref_decl); |
| 2776 | | 2737 | |
| 2777 | const lhs_node = try Node.identifier.create(c.arena, ref); | 2738 | const lhs_node = try Tag.identifier.create(c.arena, ref); |
| 2778 | const ref_node = try Node.deref.create(c.arena, lhs_node); | 2739 | const ref_node = try Tag.deref.create(c.arena, lhs_node); |
| 2779 | | 2740 | |
| 2780 | const tmp = try block_scope.makeMangledName(c, "tmp"); | 2741 | const tmp = try block_scope.makeMangledName(c, "tmp"); |
| 2781 | const tmp_decl = try Node.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node}); | 2742 | const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node }); |
| 2782 | try block_scope.statements.append(tmp_decl); | 2743 | try block_scope.statements.append(tmp_decl); |
| 2783 | | 2744 | |
| 2784 | const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Node.one_literal.init(), .used); | 2745 | const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used); |
| 2785 | try block_scope.statements.append(node); | 2746 | try block_scope.statements.append(node); |
| 2786 | | 2747 | |
| 2787 | const break_node = try Node.break_val.create(c.arena, .{ | 2748 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 2788 | .label = block_scope.label, | 2749 | .label = block_scope.label, |
| 2789 | .val = try Node.identifier.create(c.arena, tmp), | 2750 | .val = try Tag.identifier.create(c.arena, tmp), |
| 2790 | }); | 2751 | }); |
| 2791 | try block_scope.statements.append(break_node); | 2752 | try block_scope.statements.append(break_node); |
| 2792 | return block_scope.complete(c); | 2753 | return block_scope.complete(c); |
| ... | @@ -2795,26 +2756,26 @@ fn transCreatePostCrement( | ... | @@ -2795,26 +2756,26 @@ fn transCreatePostCrement( |
| 2795 | fn transCompoundAssignOperator(c: *Context, scope: *Scope, stmt: *const clang.CompoundAssignOperator, used: ResultUsed) TransError!Node { | 2756 | fn transCompoundAssignOperator(c: *Context, scope: *Scope, stmt: *const clang.CompoundAssignOperator, used: ResultUsed) TransError!Node { |
| 2796 | switch (stmt.getOpcode()) { | 2757 | switch (stmt.getOpcode()) { |
| 2797 | .MulAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2758 | .MulAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2798 | return transCreateCompoundAssign(c, scope, stmt, .assign_mul_wrap, used) | 2759 | return transCreateCompoundAssign(c, scope, stmt, .mul_wrap_assign, used) |
| 2799 | else | 2760 | else |
| 2800 | return transCreateCompoundAssign(c, scope, stmt, .assign_mul, used), | 2761 | return transCreateCompoundAssign(c, scope, stmt, .mul_assign, used), |
| 2801 | .AddAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2762 | .AddAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2802 | return transCreateCompoundAssign(c, scope, stmt, .assign_add_wrap, used) | 2763 | return transCreateCompoundAssign(c, scope, stmt, .add_wrap_assign, used) |
| 2803 | else | 2764 | else |
| 2804 | return transCreateCompoundAssign(c, scope, stmt, .assign_add, used), | 2765 | return transCreateCompoundAssign(c, scope, stmt, .add_assign, used), |
| 2805 | .SubAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) | 2766 | .SubAssign => if (qualTypeHasWrappingOverflow(stmt.getType())) |
| 2806 | return transCreateCompoundAssign(c, scope, stmt, .assign_sub_wrap, used) | 2767 | return transCreateCompoundAssign(c, scope, stmt, .sub_wrap_assign, used) |
| 2807 | else | 2768 | else |
| 2808 | return transCreateCompoundAssign(c, scope, stmt, .assign_sub, used), | 2769 | return transCreateCompoundAssign(c, scope, stmt, .sub_assign, used), |
| 2809 | .DivAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_div, used), | 2770 | .DivAssign => return transCreateCompoundAssign(c, scope, stmt, .div_assign, used), |
| 2810 | .RemAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_mod, used), | 2771 | .RemAssign => return transCreateCompoundAssign(c, scope, stmt, .mod_assign, used), |
| 2811 | .ShlAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_shl, used), | 2772 | .ShlAssign => return transCreateCompoundAssign(c, scope, stmt, .shl_assign, used), |
| 2812 | .ShrAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_shr, used), | 2773 | .ShrAssign => return transCreateCompoundAssign(c, scope, stmt, .shr_assign, used), |
| 2813 | .AndAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_and, used), | 2774 | .AndAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_and_assign, used), |
| 2814 | .XorAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_xor, used), | 2775 | .XorAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_xor_assign, used), |
| 2815 | .OrAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_or, used), | 2776 | .OrAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_or_assign, used), |
| 2816 | else => return fail( | 2777 | else => return fail( |
| 2817 | rp, | 2778 | c, |
| 2818 | error.UnsupportedTranslation, | 2779 | error.UnsupportedTranslation, |
| 2819 | stmt.getBeginLoc(), | 2780 | stmt.getBeginLoc(), |
| 2820 | "unsupported C translation {}", | 2781 | "unsupported C translation {}", |
| ... | @@ -2827,12 +2788,12 @@ fn transCreateCompoundAssign( | ... | @@ -2827,12 +2788,12 @@ fn transCreateCompoundAssign( |
| 2827 | c: *Context, | 2788 | c: *Context, |
| 2828 | scope: *Scope, | 2789 | scope: *Scope, |
| 2829 | stmt: *const clang.CompoundAssignOperator, | 2790 | stmt: *const clang.CompoundAssignOperator, |
| 2830 | op: Node.Tag, | 2791 | op: Tag, |
| 2831 | used: ResultUsed, | 2792 | used: ResultUsed, |
| 2832 | ) TransError!Node { | 2793 | ) TransError!Node { |
| 2833 | const is_shift = op == .assign_shl or op == .assign_shr; | 2794 | const is_shift = op == .shl_assign or op == .shr_assign; |
| 2834 | const is_div = op == .assign_div; | 2795 | const is_div = op == .div_assign; |
| 2835 | const is_mod = op == .assign_mod; | 2796 | const is_mod = op == .mod_assign; |
| 2836 | const lhs = stmt.getLHS(); | 2797 | const lhs = stmt.getLHS(); |
| 2837 | const rhs = stmt.getRHS(); | 2798 | const rhs = stmt.getRHS(); |
| 2838 | const loc = stmt.getBeginLoc(); | 2799 | const loc = stmt.getBeginLoc(); |
| ... | @@ -2849,21 +2810,21 @@ fn transCreateCompoundAssign( | ... | @@ -2849,21 +2810,21 @@ fn transCreateCompoundAssign( |
| 2849 | // c: lhs += rhs | 2810 | // c: lhs += rhs |
| 2850 | // zig: lhs += rhs | 2811 | // zig: lhs += rhs |
| 2851 | if ((is_mod or is_div) and is_signed) { | 2812 | if ((is_mod or is_div) and is_signed) { |
| 2852 | const lhs_node = try transExpr(c, scope, lhs, .used, .l_value); | 2813 | const lhs_node = try transExpr(c, scope, lhs, .used); |
| 2853 | const rhs_node = try transExpr(c, scope, rhs, .used, .r_value); | 2814 | const rhs_node = try transExpr(c, scope, rhs, .used); |
| 2854 | const builtin = if (is_mod) | 2815 | const builtin = if (is_mod) |
| 2855 | try Node.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) | 2816 | try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) |
| 2856 | else | 2817 | else |
| 2857 | try Node.divTrunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); | 2818 | try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); |
| 2858 | | 2819 | |
| 2859 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); | 2820 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); |
| 2860 | } | 2821 | } |
| 2861 | | 2822 | |
| 2862 | const lhs_node = try transExpr(c, scope, lhs, .used, .l_value); | 2823 | const lhs_node = try transExpr(c, scope, lhs, .used); |
| 2863 | var rhs_node = if (is_shift or requires_int_cast) | 2824 | var rhs_node = if (is_shift or requires_int_cast) |
| 2864 | try transExprCoercing(c, scope, rhs, .used, .r_value) | 2825 | try transExprCoercing(c, scope, rhs, .used) |
| 2865 | else | 2826 | else |
| 2866 | try transExpr(c, scope, rhs, .used, .r_value); | 2827 | try transExpr(c, scope, rhs, .used); |
| 2867 | | 2828 | |
| 2868 | if (is_shift or requires_int_cast) { | 2829 | if (is_shift or requires_int_cast) { |
| 2869 | // @intCast(rhs) | 2830 | // @intCast(rhs) |
| ... | @@ -2871,11 +2832,11 @@ fn transCreateCompoundAssign( | ... | @@ -2871,11 +2832,11 @@ fn transCreateCompoundAssign( |
| 2871 | try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc) | 2832 | try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc) |
| 2872 | else | 2833 | else |
| 2873 | try transQualType(c, getExprQualType(c, lhs), loc); | 2834 | try transQualType(c, getExprQualType(c, lhs), loc); |
| 2874 | | 2835 | |
| 2875 | rhs_node = try Node.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); | 2836 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); |
| 2876 | } | 2837 | } |
| 2877 | | 2838 | |
| 2878 | return transCreateNodeInfixOp(c, scope, assign_op, lhs_node, rhs_node, .used); | 2839 | return transCreateNodeInfixOp(c, scope, op, lhs_node, rhs_node, .used); |
| 2879 | } | 2840 | } |
| 2880 | // worst case | 2841 | // worst case |
| 2881 | // c: lhs += rhs | 2842 | // c: lhs += rhs |
| ... | @@ -2888,25 +2849,25 @@ fn transCreateCompoundAssign( | ... | @@ -2888,25 +2849,25 @@ fn transCreateCompoundAssign( |
| 2888 | defer block_scope.deinit(); | 2849 | defer block_scope.deinit(); |
| 2889 | const ref = try block_scope.makeMangledName(c, "ref"); | 2850 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2890 | | 2851 | |
| 2891 | const expr = try transExpr(c, scope, op_expr, .used, .r_value); | 2852 | const expr = try transExpr(c, scope, lhs, .used); |
| 2892 | const addr_of = try Node.address_of.create(c.arena, expr); | 2853 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2893 | const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of}); | 2854 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2894 | try block_scope.statements.append(ref_decl); | 2855 | try block_scope.statements.append(ref_decl); |
| 2895 | | 2856 | |
| 2896 | const lhs_node = try Node.identifier.create(c.arena, ref); | 2857 | const lhs_node = try Tag.identifier.create(c.arena, ref); |
| 2897 | const ref_node = try Node.deref.create(c.arena, lhs_node); | 2858 | const ref_node = try Tag.deref.create(c.arena, lhs_node); |
| 2898 | | 2859 | |
| 2899 | if ((is_mod or is_div) and is_signed) { | 2860 | if ((is_mod or is_div) and is_signed) { |
| 2900 | const rhs_node = try transExpr(c, scope, rhs, .used, .r_value); | 2861 | const rhs_node = try transExpr(c, scope, rhs, .used); |
| 2901 | const builtin = if (is_mod) | 2862 | const builtin = if (is_mod) |
| 2902 | try Node.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) | 2863 | try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) |
| 2903 | else | 2864 | else |
| 2904 | try Node.divTrunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); | 2865 | try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); |
| 2905 | | 2866 | |
| 2906 | const assign = try transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); | 2867 | const assign = try transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); |
| 2907 | try block_scope.statements.append(assign); | 2868 | try block_scope.statements.append(assign); |
| 2908 | } else { | 2869 | } else { |
| 2909 | var rhs_node = try transExpr(c, scope, rhs, .used, .r_value); | 2870 | var rhs_node = try transExpr(c, scope, rhs, .used); |
| 2910 | | 2871 | |
| 2911 | if (is_shift or requires_int_cast) { | 2872 | if (is_shift or requires_int_cast) { |
| 2912 | // @intCast(rhs) | 2873 | // @intCast(rhs) |
| ... | @@ -2914,15 +2875,15 @@ fn transCreateCompoundAssign( | ... | @@ -2914,15 +2875,15 @@ fn transCreateCompoundAssign( |
| 2914 | try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc) | 2875 | try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc) |
| 2915 | else | 2876 | else |
| 2916 | try transQualType(c, getExprQualType(c, lhs), loc); | 2877 | try transQualType(c, getExprQualType(c, lhs), loc); |
| 2917 | | 2878 | |
| 2918 | rhs_node = try Node.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); | 2879 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); |
| 2919 | } | 2880 | } |
| 2920 | | 2881 | |
| 2921 | const assign = try transCreateNodeInfixOp(c, scope, op, ref_node, rhs_node, .used); | 2882 | const assign = try transCreateNodeInfixOp(c, scope, op, ref_node, rhs_node, .used); |
| 2922 | try block_scope.statements.append(assign); | 2883 | try block_scope.statements.append(assign); |
| 2923 | } | 2884 | } |
| 2924 | | 2885 | |
| 2925 | const break_node = try Node.break_val.create(c.arena, .{ | 2886 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 2926 | .label = block_scope.label, | 2887 | .label = block_scope.label, |
| 2927 | .val = ref_node, | 2888 | .val = ref_node, |
| 2928 | }); | 2889 | }); |
| ... | @@ -2941,7 +2902,7 @@ fn transCPtrCast( | ... | @@ -2941,7 +2902,7 @@ fn transCPtrCast( |
| 2941 | const child_type = ty.getPointeeType(); | 2902 | const child_type = ty.getPointeeType(); |
| 2942 | const src_ty = src_type.getTypePtr(); | 2903 | const src_ty = src_type.getTypePtr(); |
| 2943 | const src_child_type = src_ty.getPointeeType(); | 2904 | const src_child_type = src_ty.getPointeeType(); |
| 2944 | const dst_type = try transType(c, ty, loc); | 2905 | const dst_type_node = try transType(c, ty, loc); |
| 2945 | | 2906 | |
| 2946 | if ((src_child_type.isConstQualified() and | 2907 | if ((src_child_type.isConstQualified() and |
| 2947 | !child_type.isConstQualified()) or | 2908 | !child_type.isConstQualified()) or |
| ... | @@ -2949,8 +2910,8 @@ fn transCPtrCast( | ... | @@ -2949,8 +2910,8 @@ fn transCPtrCast( |
| 2949 | !child_type.isVolatileQualified())) | 2910 | !child_type.isVolatileQualified())) |
| 2950 | { | 2911 | { |
| 2951 | // Casting away const or volatile requires us to use @intToPtr | 2912 | // Casting away const or volatile requires us to use @intToPtr |
| 2952 | const ptr_to_int = try Node.ptr_to_int.create(c.arena, expr); | 2913 | const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr); |
| 2953 | const int_to_ptr = try Node.int_to_ptr.create(c.arena, .{ .lhs = dst_type, .rhs = ptr_to_int }); | 2914 | const int_to_ptr = try Tag.int_to_ptr.create(c.arena, .{ .lhs = dst_type_node, .rhs = ptr_to_int }); |
| 2954 | return int_to_ptr; | 2915 | return int_to_ptr; |
| 2955 | } else { | 2916 | } else { |
| 2956 | // Implicit downcasting from higher to lower alignment values is forbidden, | 2917 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| ... | @@ -2963,17 +2924,17 @@ fn transCPtrCast( | ... | @@ -2963,17 +2924,17 @@ fn transCPtrCast( |
| 2963 | expr | 2924 | expr |
| 2964 | else blk: { | 2925 | else blk: { |
| 2965 | const child_type_node = try transQualType(c, child_type, loc); | 2926 | const child_type_node = try transQualType(c, child_type, loc); |
| 2966 | const alignof = try Node.alignof.create(c.arena, child_type_node); | 2927 | const alignof = try Tag.alignof.create(c.arena, child_type_node); |
| 2967 | const align_cast = try Node.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr }); | 2928 | const align_cast = try Tag.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr }); |
| 2968 | break :blk align_cast; | 2929 | break :blk align_cast; |
| 2969 | }; | 2930 | }; |
| 2970 | return Node.ptr_cast.create(c.arena, .{ .lhs = dst_type, .rhs = rhs }); | 2931 | return Tag.ptr_cast.create(c.arena, .{ .lhs = dst_type_node, .rhs = rhs }); |
| 2971 | } | 2932 | } |
| 2972 | } | 2933 | } |
| 2973 | | 2934 | |
| 2974 | fn transBreak(c: *Context, scope: *Scope) TransError!Node { | 2935 | fn transBreak(c: *Context, scope: *Scope) TransError!Node { |
| 2975 | const break_scope = scope.getBreakableScope(); | 2936 | const break_scope = scope.getBreakableScope(); |
| 2976 | const label_text: ?[]const u8 = if (break_scope.id == .Switch) blk: { | 2937 | const label_text: ?[]const u8 = if (break_scope.id == .@"switch") blk: { |
| 2977 | const swtch = @fieldParentPtr(Scope.Switch, "base", break_scope); | 2938 | const swtch = @fieldParentPtr(Scope.Switch, "base", break_scope); |
| 2978 | const block_scope = try scope.findBlockScope(c); | 2939 | const block_scope = try scope.findBlockScope(c); |
| 2979 | swtch.switch_label = try block_scope.makeMangledName(c, "switch"); | 2940 | swtch.switch_label = try block_scope.makeMangledName(c, "switch"); |
| ... | @@ -2981,20 +2942,20 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node { | ... | @@ -2981,20 +2942,20 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node { |
| 2981 | } else | 2942 | } else |
| 2982 | null; | 2943 | null; |
| 2983 | | 2944 | |
| 2984 | return Node.@"break".create(c.arena, label_text); | 2945 | return Tag.@"break".create(c.arena, label_text); |
| 2985 | } | 2946 | } |
| 2986 | | 2947 | |
| 2987 | fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node { | 2948 | fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node { |
| 2988 | // TODO use something more accurate | 2949 | // TODO use something more accurate |
| 2989 | const dbl = stmt.getValueAsApproximateDouble(); | 2950 | const dbl = stmt.getValueAsApproximateDouble(); |
| 2990 | const node = try transCreateNodeNumber(c, dbl); | 2951 | const node = try transCreateNodeNumber(c, dbl); |
| 2991 | return maybeSuppressResult(c, scope, used, &node.base); | 2952 | return maybeSuppressResult(c, scope, used, node); |
| 2992 | } | 2953 | } |
| 2993 | | 2954 | |
| 2994 | fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.BinaryConditionalOperator, used: ResultUsed) TransError!Node { | 2955 | fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.BinaryConditionalOperator, used: ResultUsed) TransError!Node { |
| 2995 | // GNU extension of the ternary operator where the middle expression is | 2956 | // GNU extension of the ternary operator where the middle expression is |
| 2996 | // omitted, the conditition itself is returned if it evaluates to true | 2957 | // omitted, the conditition itself is returned if it evaluates to true |
| 2997 | const qt = @ptrCast(*const clang.Stmt, stmt).getType(); | 2958 | const qt = @ptrCast(*const clang.Expr, stmt).getType(); |
| 2998 | const res_is_bool = qualTypeIsBoolean(qt); | 2959 | const res_is_bool = qualTypeIsBoolean(qt); |
| 2999 | const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt); | 2960 | const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt); |
| 3000 | const cond_expr = casted_stmt.getCond(); | 2961 | const cond_expr = casted_stmt.getCond(); |
| ... | @@ -3010,26 +2971,33 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang | ... | @@ -3010,26 +2971,33 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang |
| 3010 | defer block_scope.deinit(); | 2971 | defer block_scope.deinit(); |
| 3011 | | 2972 | |
| 3012 | const mangled_name = try block_scope.makeMangledName(c, "cond_temp"); | 2973 | const mangled_name = try block_scope.makeMangledName(c, "cond_temp"); |
| 3013 | const init_node = try transExpr(c, &block_scope.base, cond_expr, .used, .r_value); | 2974 | const init_node = try transExpr(c, &block_scope.base, cond_expr, .used); |
| 3014 | const ref_decl = try Node.var_simple.create(c.arena, .{ .name = mangled_name, .init = init_node}); | 2975 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = mangled_name, .init = init_node }); |
| 3015 | try block_scope.statements.append(ref_decl); | 2976 | try block_scope.statements.append(ref_decl); |
| 3016 | | 2977 | |
| | 2978 | var cond_scope = Scope.Condition{ |
| | 2979 | .base = .{ |
| | 2980 | .parent = &block_scope.base, |
| | 2981 | .id = .condition, |
| | 2982 | }, |
| | 2983 | }; |
| | 2984 | defer cond_scope.deinit(); |
| 3017 | const cond_node = try transBoolExpr(c, &cond_scope.base, cond_expr, .used); | 2985 | const cond_node = try transBoolExpr(c, &cond_scope.base, cond_expr, .used); |
| 3018 | var then_body = try Node.identifier.create(c.arena, mangled_name); | 2986 | var then_body = try Tag.identifier.create(c.arena, mangled_name); |
| 3019 | if (!res_is_bool and isBoolRes(init_node)) { | 2987 | if (!res_is_bool and isBoolRes(init_node)) { |
| 3020 | then_body = try Node.bool_to_int.create(c.arena, then_body); | 2988 | then_body = try Tag.bool_to_int.create(c.arena, then_body); |
| 3021 | } | 2989 | } |
| 3022 | | 2990 | |
| 3023 | var else_body = try transExpr(c, &block_scope.base, false_expr, .used, .r_value); | 2991 | var else_body = try transExpr(c, &block_scope.base, false_expr, .used); |
| 3024 | if (!res_is_bool and isBoolRes(else_body)) { | 2992 | if (!res_is_bool and isBoolRes(else_body)) { |
| 3025 | else_body = try Node.bool_to_int.create(c.arena, else_body); | 2993 | else_body = try Tag.bool_to_int.create(c.arena, else_body); |
| 3026 | } | 2994 | } |
| 3027 | const if_node = try Node.@"if".create(c.arena, .{ | 2995 | const if_node = try Tag.@"if".create(c.arena, .{ |
| 3028 | .cond = cond, | 2996 | .cond = cond_node, |
| 3029 | .then = then_body, | 2997 | .then = then_body, |
| 3030 | .@"else" = else_body, | 2998 | .@"else" = else_body, |
| 3031 | }); | 2999 | }); |
| 3032 | const break_node = try Node.break_val.create(c.arena, .{ | 3000 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 3033 | .label = block_scope.label, | 3001 | .label = block_scope.label, |
| 3034 | .val = if_node, | 3002 | .val = if_node, |
| 3035 | }); | 3003 | }); |
| ... | @@ -3042,31 +3010,31 @@ fn transConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.Condi | ... | @@ -3042,31 +3010,31 @@ fn transConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.Condi |
| 3042 | var cond_scope = Scope.Condition{ | 3010 | var cond_scope = Scope.Condition{ |
| 3043 | .base = .{ | 3011 | .base = .{ |
| 3044 | .parent = scope, | 3012 | .parent = scope, |
| 3045 | .id = .Condition, | 3013 | .id = .condition, |
| 3046 | }, | 3014 | }, |
| 3047 | }; | 3015 | }; |
| 3048 | defer cond_scope.deinit(); | 3016 | defer cond_scope.deinit(); |
| 3049 | | 3017 | |
| 3050 | const qt = @ptrCast(*const clang.Stmt, stmt).getType(); | 3018 | const qt = @ptrCast(*const clang.Expr, stmt).getType(); |
| 3051 | const res_is_bool = qualTypeIsBoolean(qt); | 3019 | const res_is_bool = qualTypeIsBoolean(qt); |
| 3052 | const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt); | 3020 | const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt); |
| 3053 | const cond_expr = casted_stmt.getCond(); | 3021 | const cond_expr = casted_stmt.getCond(); |
| 3054 | const true_expr = casted_stmt.getTrueExpr(); | 3022 | const true_expr = casted_stmt.getTrueExpr(); |
| 3055 | const false_expr = casted_stmt.getFalseExpr(); | 3023 | const false_expr = casted_stmt.getFalseExpr(); |
| 3056 | | 3024 | |
| 3057 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value); | 3025 | const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used); |
| 3058 | | 3026 | |
| 3059 | var then_body = try transExpr(c, scope, true_expr, .used, .r_value); | 3027 | var then_body = try transExpr(c, scope, true_expr, .used); |
| 3060 | if (!res_is_bool and isBoolRes(then_body)) { | 3028 | if (!res_is_bool and isBoolRes(then_body)) { |
| 3061 | then_body = try Node.bool_to_int.create(c.arena, then_body); | 3029 | then_body = try Tag.bool_to_int.create(c.arena, then_body); |
| 3062 | } | 3030 | } |
| 3063 | | 3031 | |
| 3064 | var else_body = try transExpr(c, scope, false_expr, .used, .r_value); | 3032 | var else_body = try transExpr(c, scope, false_expr, .used); |
| 3065 | if (!res_is_bool and isBoolRes(else_body)) { | 3033 | if (!res_is_bool and isBoolRes(else_body)) { |
| 3066 | else_body = try Node.bool_to_int.create(c.arena, else_body); | 3034 | else_body = try Tag.bool_to_int.create(c.arena, else_body); |
| 3067 | } | 3035 | } |
| 3068 | | 3036 | |
| 3069 | const if_node = try Node.@"if".create(c.arena, .{ | 3037 | const if_node = try Tag.@"if".create(c.arena, .{ |
| 3070 | .cond = cond, | 3038 | .cond = cond, |
| 3071 | .then = then_body, | 3039 | .then = then_body, |
| 3072 | .@"else" = else_body, | 3040 | .@"else" = else_body, |
| ... | @@ -3081,7 +3049,7 @@ fn maybeSuppressResult( | ... | @@ -3081,7 +3049,7 @@ fn maybeSuppressResult( |
| 3081 | result: Node, | 3049 | result: Node, |
| 3082 | ) TransError!Node { | 3050 | ) TransError!Node { |
| 3083 | if (used == .used) return result; | 3051 | if (used == .used) return result; |
| 3084 | return Node.ignore.create(c.arena, result); | 3052 | return Tag.ignore.create(c.arena, result); |
| 3085 | } | 3053 | } |
| 3086 | | 3054 | |
| 3087 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void { | 3055 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void { |
| ... | @@ -3100,19 +3068,19 @@ fn transQualTypeInitialized( | ... | @@ -3100,19 +3068,19 @@ fn transQualTypeInitialized( |
| 3100 | const ty = qt.getTypePtr(); | 3068 | const ty = qt.getTypePtr(); |
| 3101 | if (ty.getTypeClass() == .IncompleteArray) { | 3069 | if (ty.getTypeClass() == .IncompleteArray) { |
| 3102 | const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); | 3070 | const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); |
| 3103 | const elem_ty = incomplete_array_ty.getElementType().getTypePtr(); | 3071 | const elem_ty = try transType(c, incomplete_array_ty.getElementType().getTypePtr(), source_loc); |
| 3104 | | 3072 | |
| 3105 | switch (decl_init.getStmtClass()) { | 3073 | switch (decl_init.getStmtClass()) { |
| 3106 | .StringLiteralClass => { | 3074 | .StringLiteralClass => { |
| 3107 | const string_lit = @ptrCast(*const clang.StringLiteral, decl_init); | 3075 | const string_lit = @ptrCast(*const clang.StringLiteral, decl_init); |
| 3108 | const string_lit_size = string_lit.getLength() + 1; // +1 for null terminator | 3076 | const string_lit_size = string_lit.getLength() + 1; // +1 for null terminator |
| 3109 | const array_size = @intCast(usize, string_lit_size); | 3077 | const array_size = @intCast(usize, string_lit_size); |
| 3110 | return Node.array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty }); | 3078 | return Tag.array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty }); |
| 3111 | }, | 3079 | }, |
| 3112 | .InitListExprClass => { | 3080 | .InitListExprClass => { |
| 3113 | const init_expr = @ptrCast(*const clang.InitListExpr, decl_init); | 3081 | const init_expr = @ptrCast(*const clang.InitListExpr, decl_init); |
| 3114 | const size = init_expr.getNumInits(); | 3082 | const size = init_expr.getNumInits(); |
| 3115 | return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty }); | 3083 | return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty }); |
| 3116 | }, | 3084 | }, |
| 3117 | else => {}, | 3085 | else => {}, |
| 3118 | } | 3086 | } |
| ... | @@ -3135,7 +3103,7 @@ fn transQualTypeIntWidthOf(c: *Context, ty: clang.QualType, is_signed: bool) Typ | ... | @@ -3135,7 +3103,7 @@ fn transQualTypeIntWidthOf(c: *Context, ty: clang.QualType, is_signed: bool) Typ |
| 3135 | fn transTypeIntWidthOf(c: *Context, ty: *const clang.Type, is_signed: bool) TypeError!Node { | 3103 | fn transTypeIntWidthOf(c: *Context, ty: *const clang.Type, is_signed: bool) TypeError!Node { |
| 3136 | assert(ty.getTypeClass() == .Builtin); | 3104 | assert(ty.getTypeClass() == .Builtin); |
| 3137 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); | 3105 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| 3138 | return Node.type.create(c.arena, switch (builtin_ty.getKind()) { | 3106 | return Tag.type.create(c.arena, switch (builtin_ty.getKind()) { |
| 3139 | .Char_U, .Char_S, .UChar, .SChar, .Char8 => if (is_signed) "i8" else "u8", | 3107 | .Char_U, .Char_S, .UChar, .SChar, .Char8 => if (is_signed) "i8" else "u8", |
| 3140 | .UShort, .Short => if (is_signed) "c_short" else "c_ushort", | 3108 | .UShort, .Short => if (is_signed) "c_short" else "c_ushort", |
| 3141 | .UInt, .Int => if (is_signed) "c_int" else "c_uint", | 3109 | .UInt, .Int => if (is_signed) "c_int" else "c_uint", |
| ... | @@ -3214,11 +3182,11 @@ fn qualTypeToLog2IntRef(c: *Context, qt: clang.QualType, source_loc: clang.Sourc | ... | @@ -3214,11 +3182,11 @@ fn qualTypeToLog2IntRef(c: *Context, qt: clang.QualType, source_loc: clang.Sourc |
| 3214 | if (int_bit_width != 0) { | 3182 | if (int_bit_width != 0) { |
| 3215 | // we can perform the log2 now. | 3183 | // we can perform the log2 now. |
| 3216 | const cast_bit_width = math.log2_int(u64, int_bit_width); | 3184 | const cast_bit_width = math.log2_int(u64, int_bit_width); |
| 3217 | return Node.log2_int_type.create(c.arena, cast_bit_width); | 3185 | return Tag.log2_int_type.create(c.arena, cast_bit_width); |
| 3218 | } | 3186 | } |
| 3219 | | 3187 | |
| 3220 | const zig_type = try transQualType(c, qt, source_loc); | 3188 | const zig_type = try transQualType(c, qt, source_loc); |
| 3221 | return Node.std_math_Log2Int.create(c.arena, zig_type); | 3189 | return Tag.std_math_Log2Int.create(c.arena, zig_type); |
| 3222 | } | 3190 | } |
| 3223 | | 3191 | |
| 3224 | fn qualTypeChildIsFnProto(qt: clang.QualType) bool { | 3192 | fn qualTypeChildIsFnProto(qt: clang.QualType) bool { |
| ... | @@ -3392,10 +3360,10 @@ fn transCreateNodeAssign( | ... | @@ -3392,10 +3360,10 @@ fn transCreateNodeAssign( |
| 3392 | // c: lhs = rhs | 3360 | // c: lhs = rhs |
| 3393 | // zig: lhs = rhs | 3361 | // zig: lhs = rhs |
| 3394 | if (result_used == .unused) { | 3362 | if (result_used == .unused) { |
| 3395 | const lhs_node = try transExpr(c, scope, lhs, .used, .l_value); | 3363 | const lhs_node = try transExpr(c, scope, lhs, .used); |
| 3396 | var rhs_node = try transExprCoercing(c, scope, rhs, .used, .r_value); | 3364 | var rhs_node = try transExprCoercing(c, scope, rhs, .used); |
| 3397 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { | 3365 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3398 | rhs_node = try Node.bool_to_int.create(c.arena, rhs_node); | 3366 | rhs_node = try Tag.bool_to_int.create(c.arena, rhs_node); |
| 3399 | } | 3367 | } |
| 3400 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, rhs_node, .used); | 3368 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, rhs_node, .used); |
| 3401 | } | 3369 | } |
| ... | @@ -3411,17 +3379,16 @@ fn transCreateNodeAssign( | ... | @@ -3411,17 +3379,16 @@ fn transCreateNodeAssign( |
| 3411 | defer block_scope.deinit(); | 3379 | defer block_scope.deinit(); |
| 3412 | | 3380 | |
| 3413 | const tmp = try block_scope.makeMangledName(c, "tmp"); | 3381 | const tmp = try block_scope.makeMangledName(c, "tmp"); |
| 3414 | const rhs = try transExpr(c, scope, op_expr, .used, .r_value); | 3382 | const rhs_node = try transExpr(c, scope, rhs, .used); |
| 3415 | const tmp_decl = try Node.var_simple.create(c.arena, .{ .name = tmp, .init = rhs}); | 3383 | const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = rhs_node }); |
| 3416 | try block_scope.statements.append(tmp_decl); | 3384 | try block_scope.statements.append(tmp_decl); |
| 3417 | | 3385 | |
| 3418 | | 3386 | const lhs_node = try transExpr(c, &block_scope.base, lhs, .used); |
| 3419 | const lhs = try transExpr(c, &block_scope.base, lhs, .used, .l_value); | 3387 | const tmp_ident = try Tag.identifier.create(c.arena, tmp); |
| 3420 | const tmp_ident = try Node.identifier.create(c.arena, tmp); | 3388 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs_node, tmp_ident, .used); |
| 3421 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs, tmp_iden, .used); | | |
| 3422 | try block_scope.statements.append(assign); | 3389 | try block_scope.statements.append(assign); |
| 3423 | | 3390 | |
| 3424 | const break_node = try Node.break_val.create(c.arena, .{ | 3391 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 3425 | .label = block_scope.label, | 3392 | .label = block_scope.label, |
| 3426 | .val = tmp_ident, | 3393 | .val = tmp_ident, |
| 3427 | }); | 3394 | }); |
| ... | @@ -3432,7 +3399,7 @@ fn transCreateNodeAssign( | ... | @@ -3432,7 +3399,7 @@ fn transCreateNodeAssign( |
| 3432 | fn transCreateNodeInfixOp( | 3399 | fn transCreateNodeInfixOp( |
| 3433 | c: *Context, | 3400 | c: *Context, |
| 3434 | scope: *Scope, | 3401 | scope: *Scope, |
| 3435 | op: ast.Node.Tag, | 3402 | op: Tag, |
| 3436 | lhs: Node, | 3403 | lhs: Node, |
| 3437 | rhs: Node, | 3404 | rhs: Node, |
| 3438 | used: ResultUsed, | 3405 | used: ResultUsed, |
| ... | @@ -3452,13 +3419,13 @@ fn transCreateNodeBoolInfixOp( | ... | @@ -3452,13 +3419,13 @@ fn transCreateNodeBoolInfixOp( |
| 3452 | c: *Context, | 3419 | c: *Context, |
| 3453 | scope: *Scope, | 3420 | scope: *Scope, |
| 3454 | stmt: *const clang.BinaryOperator, | 3421 | stmt: *const clang.BinaryOperator, |
| 3455 | op: ast.Node.Tag, | 3422 | op: Tag, |
| 3456 | used: ResultUsed, | 3423 | used: ResultUsed, |
| 3457 | ) !Node { | 3424 | ) !Node { |
| 3458 | std.debug.assert(op == .bool_and or op == .bool_or); | 3425 | std.debug.assert(op == .@"and" or op == .@"or"); |
| 3459 | | 3426 | |
| 3460 | const lhs = try transBoolExpr(rp, scope, stmt.getLHS(), .used, .l_value); | 3427 | const lhs = try transBoolExpr(c, scope, stmt.getLHS(), .used); |
| 3461 | const rhs = try transBoolExpr(rp, scope, stmt.getRHS(), .used, .r_value); | 3428 | const rhs = try transBoolExpr(c, scope, stmt.getRHS(), .used); |
| 3462 | | 3429 | |
| 3463 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, used); | 3430 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs, used); |
| 3464 | } | 3431 | } |
| ... | @@ -3503,22 +3470,22 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node { | ... | @@ -3503,22 +3470,22 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node { |
| 3503 | const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) { | 3470 | const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) { |
| 3504 | error.OutOfMemory => return error.OutOfMemory, | 3471 | error.OutOfMemory => return error.OutOfMemory, |
| 3505 | }; | 3472 | }; |
| 3506 | return Node.int_literal.create(c.arena, str); | 3473 | return Tag.number_literal.create(c.arena, str); |
| 3507 | } | 3474 | } |
| 3508 | | 3475 | |
| 3509 | fn transCreateNodeNumber(c: *Context, int: anytype) !Node { | 3476 | fn transCreateNodeNumber(c: *Context, int: anytype) !Node { |
| 3510 | const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}"; | 3477 | const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}"; |
| 3511 | const str = try std.fmt.allocPrint(c.arena, fmt_s, .{int}); | 3478 | const str = try std.fmt.allocPrint(c.arena, fmt_s, .{int}); |
| 3512 | return Node.int_literal.create(c.arena, str); | 3479 | return Tag.number_literal.create(c.arena, str); |
| 3513 | } | 3480 | } |
| 3514 | | 3481 | |
| 3515 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node { | 3482 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node { |
| 3516 | const scope = &c.global_scope.base; | 3483 | const scope = &c.global_scope.base; |
| 3517 | | 3484 | |
| 3518 | var fn_params = std.ArrayList(Node).init(c.gpa); | 3485 | var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa); |
| 3519 | defer fn_params.deinit(); | 3486 | defer fn_params.deinit(); |
| 3520 | | 3487 | |
| 3521 | for (proto_alias.params()) |param, i| { | 3488 | for (proto_alias.data.params) |param, i| { |
| 3522 | const param_name = param.name orelse | 3489 | const param_name = param.name orelse |
| 3523 | try std.fmt.allocPrint(c.arena, "arg_{d}", .{c.getMangle()}); | 3490 | try std.fmt.allocPrint(c.arena, "arg_{d}", .{c.getMangle()}); |
| 3524 | | 3491 | |
| ... | @@ -3529,29 +3496,29 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: | ... | @@ -3529,29 +3496,29 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: |
| 3529 | }); | 3496 | }); |
| 3530 | } | 3497 | } |
| 3531 | | 3498 | |
| 3532 | const init = if (value.castTag(.var_decl)) |v| | 3499 | const init = if (ref.castTag(.var_decl)) |v| |
| 3533 | v.data.init | 3500 | v.data.init.? |
| 3534 | else if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |v| | 3501 | else if (ref.castTag(.var_simple) orelse ref.castTag(.pub_var_simple)) |v| |
| 3535 | v.data.init | 3502 | v.data.init |
| 3536 | else | 3503 | else |
| 3537 | unreachable; | 3504 | unreachable; |
| 3538 | | 3505 | |
| 3539 | const unwrap_expr = try Node.unwrap.create(c.arena, init); | 3506 | const unwrap_expr = try Tag.unwrap.create(c.arena, init); |
| 3540 | const call_params = try c.arena.alloc(Node, fn_params.items.len); | 3507 | const args = try c.arena.alloc(Node, fn_params.items.len); |
| 3541 | for (fn_params.items) |param, i| { | 3508 | for (fn_params.items) |param, i| { |
| 3542 | call_params[i] = try Node.identifier.create(c.arena, param.name); | 3509 | args[i] = try Tag.identifier.create(c.arena, param.name.?); |
| 3543 | } | 3510 | } |
| 3544 | const call_expr = try Node.call.create(c.arean, .{ | 3511 | const call_expr = try Tag.call.create(c.arena, .{ |
| 3545 | .lhs = unwrap_expr, | 3512 | .lhs = unwrap_expr, |
| 3546 | .args = call_params, | 3513 | .args = args, |
| 3547 | }); | 3514 | }); |
| 3548 | const return_expr = try Node.@"return".create(c.arean, call_expr); | 3515 | const return_expr = try Tag.@"return".create(c.arena, call_expr); |
| 3549 | const block = try Node.block_single.create(c.arean, return_expr); | 3516 | const block = try Tag.block_single.create(c.arena, return_expr); |
| 3550 | | 3517 | |
| 3551 | return Node.pub_inline_fn.create(c.arena, .{ | 3518 | return Tag.pub_inline_fn.create(c.arena, .{ |
| 3552 | .name = name, | 3519 | .name = name, |
| 3553 | .params = try c.arena.dupe(ast.Node.Param, fn_params.items), | 3520 | .params = try c.arena.dupe(ast.Payload.Param, fn_params.items), |
| 3554 | .return_type = proto_alias.return_type, | 3521 | .return_type = proto_alias.data.return_type, |
| 3555 | .body = block, | 3522 | .body = block, |
| 3556 | }); | 3523 | }); |
| 3557 | } | 3524 | } |
| ... | @@ -3560,7 +3527,7 @@ fn transCreateNodeShiftOp( | ... | @@ -3560,7 +3527,7 @@ fn transCreateNodeShiftOp( |
| 3560 | c: *Context, | 3527 | c: *Context, |
| 3561 | scope: *Scope, | 3528 | scope: *Scope, |
| 3562 | stmt: *const clang.BinaryOperator, | 3529 | stmt: *const clang.BinaryOperator, |
| 3563 | op: Node.Tag, | 3530 | op: Tag, |
| 3564 | used: ResultUsed, | 3531 | used: ResultUsed, |
| 3565 | ) !Node { | 3532 | ) !Node { |
| 3566 | std.debug.assert(op == .shl or op == .shr); | 3533 | std.debug.assert(op == .shl or op == .shr); |
| ... | @@ -3570,11 +3537,11 @@ fn transCreateNodeShiftOp( | ... | @@ -3570,11 +3537,11 @@ fn transCreateNodeShiftOp( |
| 3570 | const rhs_location = rhs_expr.getBeginLoc(); | 3537 | const rhs_location = rhs_expr.getBeginLoc(); |
| 3571 | // lhs >> @as(u5, rh) | 3538 | // lhs >> @as(u5, rh) |
| 3572 | | 3539 | |
| 3573 | const lhs = try transExpr(c, scope, lhs_expr, .used, .l_value); | 3540 | const lhs = try transExpr(c, scope, lhs_expr, .used); |
| 3574 | | 3541 | |
| 3575 | const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location); | 3542 | const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location); |
| 3576 | const rhs = try transExprCoercing(c, scope, rhs_expr, .used, .r_value); | 3543 | const rhs = try transExprCoercing(c, scope, rhs_expr, .used); |
| 3577 | const rhs_casted = try Node.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type }); | 3544 | const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type }); |
| 3578 | | 3545 | |
| 3579 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used); | 3546 | return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used); |
| 3580 | } | 3547 | } |
| ... | @@ -3583,7 +3550,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3583,7 +3550,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3583 | switch (ty.getTypeClass()) { | 3550 | switch (ty.getTypeClass()) { |
| 3584 | .Builtin => { | 3551 | .Builtin => { |
| 3585 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); | 3552 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| 3586 | return Node.type.create(c.arena, switch (builtin_ty.getKind()) { | 3553 | return Tag.type.create(c.arena, switch (builtin_ty.getKind()) { |
| 3587 | .Void => "c_void", | 3554 | .Void => "c_void", |
| 3588 | .Bool => "bool", | 3555 | .Bool => "bool", |
| 3589 | .Char_U, .UChar, .Char_S, .Char8 => "u8", | 3556 | .Char_U, .UChar, .Char_S, .Char8 => "u8", |
| ... | @@ -3608,11 +3575,13 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3608,11 +3575,13 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3608 | }, | 3575 | }, |
| 3609 | .FunctionProto => { | 3576 | .FunctionProto => { |
| 3610 | const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty); | 3577 | const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty); |
| 3611 | return transFnProto(c, null, fn_proto_ty, source_loc, null, false); | 3578 | const fn_proto = try transFnProto(c, null, fn_proto_ty, source_loc, null, false); |
| | 3579 | return Node.initPayload(&fn_proto.base); |
| 3612 | }, | 3580 | }, |
| 3613 | .FunctionNoProto => { | 3581 | .FunctionNoProto => { |
| 3614 | const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty); | 3582 | const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty); |
| 3615 | return transFnNoProto(c, fn_no_proto_ty, source_loc, null, false); | 3583 | const fn_proto = try transFnNoProto(c, fn_no_proto_ty, source_loc, null, false); |
| | 3584 | return Node.initPayload(&fn_proto.base); |
| 3616 | }, | 3585 | }, |
| 3617 | .Paren => { | 3586 | .Paren => { |
| 3618 | const paren_ty = @ptrCast(*const clang.ParenType, ty); | 3587 | const paren_ty = @ptrCast(*const clang.ParenType, ty); |
| ... | @@ -3621,16 +3590,16 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3621,16 +3590,16 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3621 | .Pointer => { | 3590 | .Pointer => { |
| 3622 | const child_qt = ty.getPointeeType(); | 3591 | const child_qt = ty.getPointeeType(); |
| 3623 | if (qualTypeChildIsFnProto(child_qt)) { | 3592 | if (qualTypeChildIsFnProto(child_qt)) { |
| 3624 | return Node.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc)); | 3593 | return Tag.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc)); |
| 3625 | } | 3594 | } |
| 3626 | const is_const = child_qt.isConstQualified(); | 3595 | const is_const = child_qt.isConstQualified(); |
| 3627 | const is_volatile = child_qt.isVolatileQualified(); | 3596 | const is_volatile = child_qt.isVolatileQualified(); |
| 3628 | const elem_type = try transQualType(c, child_qt, source_loc); | 3597 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 3629 | if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) { | 3598 | if (typeIsOpaque(c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(c, child_qt)) { |
| 3630 | return Node.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); | 3599 | return Tag.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 3631 | } | 3600 | } |
| 3632 | | 3601 | |
| 3633 | return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); | 3602 | return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 3634 | }, | 3603 | }, |
| 3635 | .ConstantArray => { | 3604 | .ConstantArray => { |
| 3636 | const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty); | 3605 | const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty); |
| ... | @@ -3639,7 +3608,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3639,7 +3608,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3639 | const size = size_ap_int.getLimitedValue(math.maxInt(usize)); | 3608 | const size = size_ap_int.getLimitedValue(math.maxInt(usize)); |
| 3640 | const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc); | 3609 | const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc); |
| 3641 | | 3610 | |
| 3642 | return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type }); | 3611 | return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type }); |
| 3643 | }, | 3612 | }, |
| 3644 | .IncompleteArray => { | 3613 | .IncompleteArray => { |
| 3645 | const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); | 3614 | const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); |
| ... | @@ -3649,7 +3618,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3649,7 +3618,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3649 | const is_volatile = child_qt.isVolatileQualified(); | 3618 | const is_volatile = child_qt.isVolatileQualified(); |
| 3650 | const elem_type = try transQualType(c, child_qt, source_loc); | 3619 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 3651 | | 3620 | |
| 3652 | return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); | 3621 | return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); |
| 3653 | }, | 3622 | }, |
| 3654 | .Typedef => { | 3623 | .Typedef => { |
| 3655 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); | 3624 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| ... | @@ -3690,7 +3659,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio | ... | @@ -3690,7 +3659,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio |
| 3690 | }, | 3659 | }, |
| 3691 | else => { | 3660 | else => { |
| 3692 | const type_name = c.str(ty.getTypeClassName()); | 3661 | const type_name = c.str(ty.getTypeClassName()); |
| 3693 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); | 3662 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); |
| 3694 | }, | 3663 | }, |
| 3695 | } | 3664 | } |
| 3696 | } | 3665 | } |
| ... | @@ -3770,7 +3739,7 @@ fn transCC( | ... | @@ -3770,7 +3739,7 @@ fn transCC( |
| 3770 | .AAPCS => return CallingConvention.AAPCS, | 3739 | .AAPCS => return CallingConvention.AAPCS, |
| 3771 | .AAPCS_VFP => return CallingConvention.AAPCSVFP, | 3740 | .AAPCS_VFP => return CallingConvention.AAPCSVFP, |
| 3772 | else => return fail( | 3741 | else => return fail( |
| 3773 | rp, | 3742 | c, |
| 3774 | error.UnsupportedType, | 3743 | error.UnsupportedType, |
| 3775 | source_loc, | 3744 | source_loc, |
| 3776 | "unsupported calling convention: {s}", | 3745 | "unsupported calling convention: {s}", |
| ... | @@ -3786,7 +3755,7 @@ fn transFnProto( | ... | @@ -3786,7 +3755,7 @@ fn transFnProto( |
| 3786 | source_loc: clang.SourceLocation, | 3755 | source_loc: clang.SourceLocation, |
| 3787 | fn_decl_context: ?FnDeclContext, | 3756 | fn_decl_context: ?FnDeclContext, |
| 3788 | is_pub: bool, | 3757 | is_pub: bool, |
| 3789 | ) !Node.FnProto { | 3758 | ) !*ast.Payload.Func { |
| 3790 | const fn_ty = @ptrCast(*const clang.FunctionType, fn_proto_ty); | 3759 | const fn_ty = @ptrCast(*const clang.FunctionType, fn_proto_ty); |
| 3791 | const cc = try transCC(c, fn_ty, source_loc); | 3760 | const cc = try transCC(c, fn_ty, source_loc); |
| 3792 | const is_var_args = fn_proto_ty.isVariadic(); | 3761 | const is_var_args = fn_proto_ty.isVariadic(); |
| ... | @@ -3799,7 +3768,7 @@ fn transFnNoProto( | ... | @@ -3799,7 +3768,7 @@ fn transFnNoProto( |
| 3799 | source_loc: clang.SourceLocation, | 3768 | source_loc: clang.SourceLocation, |
| 3800 | fn_decl_context: ?FnDeclContext, | 3769 | fn_decl_context: ?FnDeclContext, |
| 3801 | is_pub: bool, | 3770 | is_pub: bool, |
| 3802 | ) !Node.FnProto { | 3771 | ) !*ast.Payload.Func { |
| 3803 | const cc = try transCC(c, fn_ty, source_loc); | 3772 | const cc = try transCC(c, fn_ty, source_loc); |
| 3804 | const is_var_args = if (fn_decl_context) |ctx| (!ctx.is_export and ctx.storage_class != .Static) else true; | 3773 | const is_var_args = if (fn_decl_context) |ctx| (!ctx.is_export and ctx.storage_class != .Static) else true; |
| 3805 | return finishTransFnProto(c, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); | 3774 | return finishTransFnProto(c, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); |
| ... | @@ -3822,7 +3791,7 @@ fn finishTransFnProto( | ... | @@ -3822,7 +3791,7 @@ fn finishTransFnProto( |
| 3822 | // TODO check for always_inline attribute | 3791 | // TODO check for always_inline attribute |
| 3823 | // TODO check for align attribute | 3792 | // TODO check for align attribute |
| 3824 | | 3793 | |
| 3825 | var fn_params = std.ArrayList(ast.Payload.Func.Param).init(c.gpa); | 3794 | var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa); |
| 3826 | defer fn_params.deinit(); | 3795 | defer fn_params.deinit(); |
| 3827 | const param_count: usize = if (fn_proto_ty != null) fn_proto_ty.?.getNumParams() else 0; | 3796 | const param_count: usize = if (fn_proto_ty != null) fn_proto_ty.?.getNumParams() else 0; |
| 3828 | try fn_params.ensureCapacity(param_count); | 3797 | try fn_params.ensureCapacity(param_count); |
| ... | @@ -3861,7 +3830,7 @@ fn finishTransFnProto( | ... | @@ -3861,7 +3830,7 @@ fn finishTransFnProto( |
| 3861 | break :blk null; | 3830 | break :blk null; |
| 3862 | }; | 3831 | }; |
| 3863 | | 3832 | |
| 3864 | const alignment: c_uint = blk: { | 3833 | const alignment = blk: { |
| 3865 | if (fn_decl) |decl| { | 3834 | if (fn_decl) |decl| { |
| 3866 | const alignment = decl.getAlignedAttribute(c.clang_context); | 3835 | const alignment = decl.getAlignedAttribute(c.clang_context); |
| 3867 | if (alignment != 0) { | 3836 | if (alignment != 0) { |
| ... | @@ -3876,16 +3845,16 @@ fn finishTransFnProto( | ... | @@ -3876,16 +3845,16 @@ fn finishTransFnProto( |
| 3876 | | 3845 | |
| 3877 | const return_type_node = blk: { | 3846 | const return_type_node = blk: { |
| 3878 | if (fn_ty.getNoReturnAttr()) { | 3847 | if (fn_ty.getNoReturnAttr()) { |
| 3879 | break :blk Node.noreturn_type.init(); | 3848 | break :blk Tag.noreturn_type.init(); |
| 3880 | } else { | 3849 | } else { |
| 3881 | const return_qt = fn_ty.getReturnType(); | 3850 | const return_qt = fn_ty.getReturnType(); |
| 3882 | if (isCVoid(return_qt)) { | 3851 | if (isCVoid(return_qt)) { |
| 3883 | // convert primitive c_void to actual void (only for return type) | 3852 | // convert primitive c_void to actual void (only for return type) |
| 3884 | break :blk Node.void_type.init(); | 3853 | break :blk Tag.void_type.init(); |
| 3885 | } else { | 3854 | } else { |
| 3886 | break :blk transQualType(c, return_qt, source_loc) catch |err| switch (err) { | 3855 | break :blk transQualType(c, return_qt, source_loc) catch |err| switch (err) { |
| 3887 | error.UnsupportedType => { | 3856 | error.UnsupportedType => { |
| 3888 | try warn(c, source_loc, "unsupported function proto return type", .{}); | 3857 | try warn(c, &c.global_scope.base, source_loc, "unsupported function proto return type", .{}); |
| 3889 | return err; | 3858 | return err; |
| 3890 | }, | 3859 | }, |
| 3891 | error.OutOfMemory => |e| return e, | 3860 | error.OutOfMemory => |e| return e, |
| ... | @@ -3893,26 +3862,31 @@ fn finishTransFnProto( | ... | @@ -3893,26 +3862,31 @@ fn finishTransFnProto( |
| 3893 | } | 3862 | } |
| 3894 | } | 3863 | } |
| 3895 | }; | 3864 | }; |
| 3896 | | 3865 | const name: ?[]const u8 = if (fn_decl_context) |ctx| ctx.fn_name else null; |
| 3897 | return Node.func.create(c.arena, .{ | 3866 | const payload = try c.arena.create(ast.Payload.Func); |
| 3898 | .is_pub = is_pub, | 3867 | payload.* = .{ |
| 3899 | .is_extern = is_extern, | 3868 | .base = .{ .tag = .func }, |
| 3900 | .is_export = is_export, | 3869 | .data = .{ |
| 3901 | .is_var_args = is_var_args, | 3870 | .is_pub = is_pub, |
| 3902 | .name = name, | 3871 | .is_extern = is_extern, |
| 3903 | .linksection_string = linksection_string, | 3872 | .is_export = is_export, |
| 3904 | .explicit_callconv = explicit_callconv, | 3873 | .is_var_args = is_var_args, |
| 3905 | .params = try c.arena.dupe(ast.Payload.Func.Param, fn_params.items), | 3874 | .name = name, |
| 3906 | .return_type = return_node, | 3875 | .linksection_string = linksection_string, |
| 3907 | .body = null, | 3876 | .explicit_callconv = explicit_callconv, |
| 3908 | .alignment = alignment, | 3877 | .params = try c.arena.dupe(ast.Payload.Param, fn_params.items), |
| 3909 | }); | 3878 | .return_type = return_type_node, |
| | 3879 | .body = null, |
| | 3880 | .alignment = alignment, |
| | 3881 | }, |
| | 3882 | }; |
| | 3883 | return payload; |
| 3910 | } | 3884 | } |
| 3911 | | 3885 | |
| 3912 | fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { | 3886 | fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void { |
| 3913 | const args_prefix = .{c.locStr(loc)}; | 3887 | const args_prefix = .{c.locStr(loc)}; |
| 3914 | const value = std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args); | 3888 | const value = try std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args); |
| 3915 | try scope.appendNode(c.gpa, try Node.warning.create(c.arena, value)); | 3889 | try scope.appendNode(try Tag.warning.create(c.arena, value)); |
| 3916 | } | 3890 | } |
| 3917 | | 3891 | |
| 3918 | fn fail( | 3892 | fn fail( |
| ... | @@ -3922,17 +3896,17 @@ fn fail( | ... | @@ -3922,17 +3896,17 @@ fn fail( |
| 3922 | comptime format: []const u8, | 3896 | comptime format: []const u8, |
| 3923 | args: anytype, | 3897 | args: anytype, |
| 3924 | ) (@TypeOf(err) || error{OutOfMemory}) { | 3898 | ) (@TypeOf(err) || error{OutOfMemory}) { |
| 3925 | try warn(c, source_loc, format, args); | 3899 | try warn(c, &c.global_scope.base, source_loc, format, args); |
| 3926 | return err; | 3900 | return err; |
| 3927 | } | 3901 | } |
| 3928 | | 3902 | |
| 3929 | pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void { | 3903 | pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) Error!void { |
| 3930 | // location | 3904 | // location |
| 3931 | // pub const name = @compileError(msg); | 3905 | // pub const name = @compileError(msg); |
| 3932 | const location_comment = std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)}); | 3906 | const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)}); |
| 3933 | try c.global_scope.nodes.append(try Node.warning.create(c.arena, location_comment)); | 3907 | try c.global_scope.nodes.append(try Tag.warning.create(c.arena, location_comment)); |
| 3934 | const fail_msg = std.fmt.allocPrint(c.arena, format, args); | 3908 | const fail_msg = try std.fmt.allocPrint(c.arena, format, args); |
| 3935 | try c.global_scope.nodes.append(try Node.fail_decl.create(c.arena, fail_msg)); | 3909 | try c.global_scope.nodes.append(try Tag.fail_decl.create(c.arena, fail_msg)); |
| 3936 | } | 3910 | } |
| 3937 | | 3911 | |
| 3938 | pub fn freeErrors(errors: []ClangErrMsg) void { | 3912 | pub fn freeErrors(errors: []ClangErrMsg) void { |
| ... | @@ -4075,7 +4049,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4075,7 +4049,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4075 | if (last != .Eof and last != .Nl) | 4049 | if (last != .Eof and last != .Nl) |
| 4076 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); | 4050 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); |
| 4077 | | 4051 | |
| 4078 | const var_decl = try Node.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node }); | 4052 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node }); |
| 4079 | _ = try c.global_scope.macro_table.put(m.name, var_decl); | 4053 | _ = try c.global_scope.macro_table.put(m.name, var_decl); |
| 4080 | } | 4054 | } |
| 4081 | | 4055 | |
| ... | @@ -4099,7 +4073,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4099,7 +4073,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4099 | try fn_params.append(.{ | 4073 | try fn_params.append(.{ |
| 4100 | .is_noalias = false, | 4074 | .is_noalias = false, |
| 4101 | .name = mangled_name, | 4075 | .name = mangled_name, |
| 4102 | .type = Node.@"anytype".init(), | 4076 | .type = Tag.@"anytype".init(), |
| 4103 | }); | 4077 | }); |
| 4104 | | 4078 | |
| 4105 | if (m.peek().? != .Comma) break; | 4079 | if (m.peek().? != .Comma) break; |
| ... | @@ -4119,19 +4093,19 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4119,19 +4093,19 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4119 | const stmts = some.data.stmts; | 4093 | const stmts = some.data.stmts; |
| 4120 | const blk_last = stmts[stmts.len - 1]; | 4094 | const blk_last = stmts[stmts.len - 1]; |
| 4121 | const br = blk_last.castTag(.break_val).?; | 4095 | const br = blk_last.castTag(.break_val).?; |
| 4122 | break :blk br.data; | 4096 | break :blk br.data.val; |
| 4123 | } else expr; | 4097 | } else expr; |
| 4124 | const typeof = try Node.typeof.create(c.arean, typeof_arg); | 4098 | const typeof = try Tag.typeof.create(c.arena, typeof_arg); |
| 4125 | const return_expr = try Node.@"return".create(c.arena, expr); | 4099 | const return_expr = try Tag.@"return".create(c.arena, expr); |
| 4126 | try block_scope.statements.append(&return_expr.base); | 4100 | try block_scope.statements.append(return_expr); |
| 4127 | | 4101 | |
| 4128 | const fn_decl = try Node.pub_inline_fn.create(c.arena, .{ | 4102 | const fn_decl = try Tag.pub_inline_fn.create(c.arena, .{ |
| 4129 | .name = m.name, | 4103 | .name = m.name, |
| 4130 | .params = try c.arena.dupe(ast.Payload.Param, fn_params.items), | 4104 | .params = try c.arena.dupe(ast.Payload.Param, fn_params.items), |
| 4131 | .return_type = typeof, | 4105 | .return_type = typeof, |
| 4132 | .body = try block_scope.complete(c), | 4106 | .body = try block_scope.complete(c), |
| 4133 | }); | 4107 | }); |
| 4134 | _ = try c.global_scope.macro_table.put(m.name, &fn_proto.base); | 4108 | _ = try c.global_scope.macro_table.put(m.name, fn_decl); |
| 4135 | } | 4109 | } |
| 4136 | | 4110 | |
| 4137 | const ParseError = Error || error{ParseError}; | 4111 | const ParseError = Error || error{ParseError}; |
| ... | @@ -4149,7 +4123,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4149,7 +4123,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4149 | var last = node; | 4123 | var last = node; |
| 4150 | while (true) { | 4124 | while (true) { |
| 4151 | // suppress result | 4125 | // suppress result |
| 4152 | const ignore = try Node.ignore.create(c.arena, last); | 4126 | const ignore = try Tag.ignore.create(c.arena, last); |
| 4153 | try block_scope.statements.append(ignore); | 4127 | try block_scope.statements.append(ignore); |
| 4154 | | 4128 | |
| 4155 | last = try parseCCondExpr(c, m, scope); | 4129 | last = try parseCCondExpr(c, m, scope); |
| ... | @@ -4159,7 +4133,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4159,7 +4133,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4159 | } | 4133 | } |
| 4160 | } | 4134 | } |
| 4161 | | 4135 | |
| 4162 | const break_node = try Node.break_val.create(c.arena, .{ | 4136 | const break_node = try Tag.break_val.create(c.arena, .{ |
| 4163 | .label = block_scope.label, | 4137 | .label = block_scope.label, |
| 4164 | .val = last, | 4138 | .val = last, |
| 4165 | }); | 4139 | }); |
| ... | @@ -4190,7 +4164,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -4190,7 +4164,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 4190 | return transCreateNodeNumber(c, lit_bytes); | 4164 | return transCreateNodeNumber(c, lit_bytes); |
| 4191 | } | 4165 | } |
| 4192 | | 4166 | |
| 4193 | const type_node = try Node.type.create(c.arena, switch (suffix) { | 4167 | const type_node = try Tag.type.create(c.arena, switch (suffix) { |
| 4194 | .u => "c_uint", | 4168 | .u => "c_uint", |
| 4195 | .l => "c_long", | 4169 | .l => "c_long", |
| 4196 | .lu => "c_ulong", | 4170 | .lu => "c_ulong", |
| ... | @@ -4205,7 +4179,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -4205,7 +4179,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 4205 | else => unreachable, | 4179 | else => unreachable, |
| 4206 | }]; | 4180 | }]; |
| 4207 | const rhs = try transCreateNodeNumber(c, lit_bytes); | 4181 | const rhs = try transCreateNodeNumber(c, lit_bytes); |
| 4208 | return Node.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); | 4182 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); |
| 4209 | }, | 4183 | }, |
| 4210 | .FloatLiteral => |suffix| { | 4184 | .FloatLiteral => |suffix| { |
| 4211 | if (lit_bytes[0] == '.') | 4185 | if (lit_bytes[0] == '.') |
| ... | @@ -4213,13 +4187,13 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -4213,13 +4187,13 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 4213 | if (suffix == .none) { | 4187 | if (suffix == .none) { |
| 4214 | return transCreateNodeNumber(c, lit_bytes); | 4188 | return transCreateNodeNumber(c, lit_bytes); |
| 4215 | } | 4189 | } |
| 4216 | const type_node = try Node.type.create(c.arena, switch (suffix) { | 4190 | const type_node = try Tag.type.create(c.arena, switch (suffix) { |
| 4217 | .f => "f32", | 4191 | .f => "f32", |
| 4218 | .l => "c_longdouble", | 4192 | .l => "c_longdouble", |
| 4219 | else => unreachable, | 4193 | else => unreachable, |
| 4220 | }); | 4194 | }); |
| 4221 | const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1]); | 4195 | const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1]); |
| 4222 | return Node.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); | 4196 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs }); |
| 4223 | }, | 4197 | }, |
| 4224 | else => unreachable, | 4198 | else => unreachable, |
| 4225 | } | 4199 | } |
| ... | @@ -4391,56 +4365,56 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -4391,56 +4365,56 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 4391 | switch (tok) { | 4365 | switch (tok) { |
| 4392 | .CharLiteral => { | 4366 | .CharLiteral => { |
| 4393 | if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) { | 4367 | if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) { |
| 4394 | return Node.char_literal.create(c.arena, try zigifyEscapeSequences(c, m)); | 4368 | return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m)); |
| 4395 | } else { | 4369 | } else { |
| 4396 | const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]}); | 4370 | const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]}); |
| 4397 | return Node.int_literal.create(c.arena, str); | 4371 | return Tag.number_literal.create(c.arena, str); |
| 4398 | } | 4372 | } |
| 4399 | }, | 4373 | }, |
| 4400 | .StringLiteral => { | 4374 | .StringLiteral => { |
| 4401 | return Node.string_literal.create(c.arena, try zigifyEscapeSequences(c, m)); | 4375 | return Tag.string_literal.create(c.arena, try zigifyEscapeSequences(c, m)); |
| 4402 | }, | 4376 | }, |
| 4403 | .IntegerLiteral, .FloatLiteral => { | 4377 | .IntegerLiteral, .FloatLiteral => { |
| 4404 | return parseCNumLit(c, m); | 4378 | return parseCNumLit(c, m); |
| 4405 | }, | 4379 | }, |
| 4406 | // eventually this will be replaced by std.c.parse which will handle these correctly | 4380 | // eventually this will be replaced by std.c.parse which will handle these correctly |
| 4407 | .Keyword_void => return Node.type.create(c.arena, "c_void"), | 4381 | .Keyword_void => return Tag.type.create(c.arena, "c_void"), |
| 4408 | .Keyword_bool => return Node.type.create(c.arena, "bool"), | 4382 | .Keyword_bool => return Tag.type.create(c.arena, "bool"), |
| 4409 | .Keyword_double => return Node.type.create(c.arena, "f64"), | 4383 | .Keyword_double => return Tag.type.create(c.arena, "f64"), |
| 4410 | .Keyword_long => return Node.type.create(c.arena, "c_long"), | 4384 | .Keyword_long => return Tag.type.create(c.arena, "c_long"), |
| 4411 | .Keyword_int => return Node.type.create(c.arena, "c_int"), | 4385 | .Keyword_int => return Tag.type.create(c.arena, "c_int"), |
| 4412 | .Keyword_float => return Node.type.create(c.arena, "f32"), | 4386 | .Keyword_float => return Tag.type.create(c.arena, "f32"), |
| 4413 | .Keyword_short => return Node.type.create(c.arena, "c_short"), | 4387 | .Keyword_short => return Tag.type.create(c.arena, "c_short"), |
| 4414 | .Keyword_char => return Node.type.create(c.arena, "u8"), | 4388 | .Keyword_char => return Tag.type.create(c.arena, "u8"), |
| 4415 | .Keyword_unsigned => if (m.next()) |t| switch (t) { | 4389 | .Keyword_unsigned => if (m.next()) |t| switch (t) { |
| 4416 | .Keyword_char => return Node.type.create(c.arena, "u8"), | 4390 | .Keyword_char => return Tag.type.create(c.arena, "u8"), |
| 4417 | .Keyword_short => return Node.type.create(c.arena, "c_ushort"), | 4391 | .Keyword_short => return Tag.type.create(c.arena, "c_ushort"), |
| 4418 | .Keyword_int => return Node.type.create(c.arena, "c_uint"), | 4392 | .Keyword_int => return Tag.type.create(c.arena, "c_uint"), |
| 4419 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { | 4393 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 4420 | _ = m.next(); | 4394 | _ = m.next(); |
| 4421 | return Node.type.create(c.arena, "c_ulonglong"); | 4395 | return Tag.type.create(c.arena, "c_ulonglong"); |
| 4422 | } else return Node.type.create(c.arena, "c_ulong"), | 4396 | } else return Tag.type.create(c.arena, "c_ulong"), |
| 4423 | else => { | 4397 | else => { |
| 4424 | m.i -= 1; | 4398 | m.i -= 1; |
| 4425 | return Node.type.create(c.arena, "c_uint"); | 4399 | return Tag.type.create(c.arena, "c_uint"); |
| 4426 | }, | 4400 | }, |
| 4427 | } else { | 4401 | } else { |
| 4428 | return Node.type.create(c.arena, "c_uint"); | 4402 | return Tag.type.create(c.arena, "c_uint"); |
| 4429 | }, | 4403 | }, |
| 4430 | .Keyword_signed => if (m.next()) |t| switch (t) { | 4404 | .Keyword_signed => if (m.next()) |t| switch (t) { |
| 4431 | .Keyword_char => return Node.type.create(c.arena, "i8"), | 4405 | .Keyword_char => return Tag.type.create(c.arena, "i8"), |
| 4432 | .Keyword_short => return Node.type.create(c.arena, "c_short"), | 4406 | .Keyword_short => return Tag.type.create(c.arena, "c_short"), |
| 4433 | .Keyword_int => return Node.type.create(c.arena, "c_int"), | 4407 | .Keyword_int => return Tag.type.create(c.arena, "c_int"), |
| 4434 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { | 4408 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 4435 | _ = m.next(); | 4409 | _ = m.next(); |
| 4436 | return Node.type.create(c.arena, "c_longlong"); | 4410 | return Tag.type.create(c.arena, "c_longlong"); |
| 4437 | } else return Node.type.create(c.arena, "c_long"), | 4411 | } else return Tag.type.create(c.arena, "c_long"), |
| 4438 | else => { | 4412 | else => { |
| 4439 | m.i -= 1; | 4413 | m.i -= 1; |
| 4440 | return Node.type.create(c.arena, "c_int"); | 4414 | return Tag.type.create(c.arena, "c_int"); |
| 4441 | }, | 4415 | }, |
| 4442 | } else { | 4416 | } else { |
| 4443 | return Node.type.create(c.arena, "c_int"); | 4417 | return Tag.type.create(c.arena, "c_int"); |
| 4444 | }, | 4418 | }, |
| 4445 | .Keyword_enum, .Keyword_struct, .Keyword_union => { | 4419 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| 4446 | // struct Foo will be declared as struct_Foo by transRecordDecl | 4420 | // struct Foo will be declared as struct_Foo by transRecordDecl |
| ... | @@ -4451,11 +4425,11 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -4451,11 +4425,11 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 4451 | } | 4425 | } |
| 4452 | | 4426 | |
| 4453 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); | 4427 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| 4454 | return Node.identifier.create(c.arena, name); | 4428 | return Tag.identifier.create(c.arena, name); |
| 4455 | }, | 4429 | }, |
| 4456 | .Identifier => { | 4430 | .Identifier => { |
| 4457 | const mangled_name = scope.getAlias(slice); | 4431 | const mangled_name = scope.getAlias(slice); |
| 4458 | return Node.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); | 4432 | return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); |
| 4459 | }, | 4433 | }, |
| 4460 | .LParen => { | 4434 | .LParen => { |
| 4461 | const inner_node = try parseCExpr(c, m, scope); | 4435 | const inner_node = try parseCExpr(c, m, scope); |
| ... | @@ -4492,7 +4466,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -4492,7 +4466,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 4492 | return error.ParseError; | 4466 | return error.ParseError; |
| 4493 | } | 4467 | } |
| 4494 | | 4468 | |
| 4495 | return Node.std_meta_cast.create(c.arena, .{ .lhs = inner_node, .rhs = node_to_cast }); | 4469 | return Tag.std_meta_cast.create(c.arena, .{ .lhs = inner_node, .rhs = node_to_cast }); |
| 4496 | }, | 4470 | }, |
| 4497 | else => { | 4471 | else => { |
| 4498 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); | 4472 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); |
| ... | @@ -4511,7 +4485,7 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4511,7 +4485,7 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4511 | .StringLiteral, .Identifier => {}, | 4485 | .StringLiteral, .Identifier => {}, |
| 4512 | else => break, | 4486 | else => break, |
| 4513 | } | 4487 | } |
| 4514 | node = try Node.array_cat.create(c.arena, .{ .lhs = node, .rhs = try parseCPrimaryExprInner(c, m, scope) }); | 4488 | node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = try parseCPrimaryExprInner(c, m, scope) }); |
| 4515 | } | 4489 | } |
| 4516 | return node; | 4490 | return node; |
| 4517 | } | 4491 | } |
| ... | @@ -4521,7 +4495,7 @@ fn macroBoolToInt(c: *Context, node: Node) !Node { | ... | @@ -4521,7 +4495,7 @@ fn macroBoolToInt(c: *Context, node: Node) !Node { |
| 4521 | return node; | 4495 | return node; |
| 4522 | } | 4496 | } |
| 4523 | | 4497 | |
| 4524 | return Node.bool_to_int.create(c.arena, node); | 4498 | return Tag.bool_to_int.create(c.arena, node); |
| 4525 | } | 4499 | } |
| 4526 | | 4500 | |
| 4527 | fn macroIntToBool(c: *Context, node: Node) !Node { | 4501 | fn macroIntToBool(c: *Context, node: Node) !Node { |
| ... | @@ -4529,7 +4503,7 @@ fn macroIntToBool(c: *Context, node: Node) !Node { | ... | @@ -4529,7 +4503,7 @@ fn macroIntToBool(c: *Context, node: Node) !Node { |
| 4529 | return node; | 4503 | return node; |
| 4530 | } | 4504 | } |
| 4531 | | 4505 | |
| 4532 | return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() }); | 4506 | return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() }); |
| 4533 | } | 4507 | } |
| 4534 | | 4508 | |
| 4535 | fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 4509 | fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| ... | @@ -4545,7 +4519,7 @@ fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4545,7 +4519,7 @@ fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4545 | return error.ParseError; | 4519 | return error.ParseError; |
| 4546 | } | 4520 | } |
| 4547 | const else_body = try parseCCondExpr(c, m, scope); | 4521 | const else_body = try parseCCondExpr(c, m, scope); |
| 4548 | return Node.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body }); | 4522 | return Tag.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body }); |
| 4549 | } | 4523 | } |
| 4550 | | 4524 | |
| 4551 | fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | 4525 | fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| ... | @@ -4553,7 +4527,7 @@ fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4553,7 +4527,7 @@ fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4553 | while (m.next().? == .PipePipe) { | 4527 | while (m.next().? == .PipePipe) { |
| 4554 | const lhs = try macroIntToBool(c, node); | 4528 | const lhs = try macroIntToBool(c, node); |
| 4555 | const rhs = try macroIntToBool(c, try parseCAndExpr(c, m, scope)); | 4529 | const rhs = try macroIntToBool(c, try parseCAndExpr(c, m, scope)); |
| 4556 | node = try Node.@"or".create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4530 | node = try Tag.@"or".create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4557 | } | 4531 | } |
| 4558 | m.i -= 1; | 4532 | m.i -= 1; |
| 4559 | return node; | 4533 | return node; |
| ... | @@ -4564,7 +4538,7 @@ fn parseCAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4564,7 +4538,7 @@ fn parseCAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4564 | while (m.next().? == .AmpersandAmpersand) { | 4538 | while (m.next().? == .AmpersandAmpersand) { |
| 4565 | const lhs = try macroIntToBool(c, node); | 4539 | const lhs = try macroIntToBool(c, node); |
| 4566 | const rhs = try macroIntToBool(c, try parseCBitOrExpr(c, m, scope)); | 4540 | const rhs = try macroIntToBool(c, try parseCBitOrExpr(c, m, scope)); |
| 4567 | node = try Node.@"and".create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4541 | node = try Tag.@"and".create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4568 | } | 4542 | } |
| 4569 | m.i -= 1; | 4543 | m.i -= 1; |
| 4570 | return node; | 4544 | return node; |
| ... | @@ -4575,7 +4549,7 @@ fn parseCBitOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4575,7 +4549,7 @@ fn parseCBitOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4575 | while (m.next().? == .Pipe) { | 4549 | while (m.next().? == .Pipe) { |
| 4576 | const lhs = try macroBoolToInt(c, node); | 4550 | const lhs = try macroBoolToInt(c, node); |
| 4577 | const rhs = try macroBoolToInt(c, try parseCBitXorExpr(c, m, scope)); | 4551 | const rhs = try macroBoolToInt(c, try parseCBitXorExpr(c, m, scope)); |
| 4578 | node = try Node.bit_or.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4552 | node = try Tag.bit_or.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4579 | } | 4553 | } |
| 4580 | m.i -= 1; | 4554 | m.i -= 1; |
| 4581 | return node; | 4555 | return node; |
| ... | @@ -4586,7 +4560,7 @@ fn parseCBitXorExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4586,7 +4560,7 @@ fn parseCBitXorExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4586 | while (m.next().? == .Caret) { | 4560 | while (m.next().? == .Caret) { |
| 4587 | const lhs = try macroBoolToInt(c, node); | 4561 | const lhs = try macroBoolToInt(c, node); |
| 4588 | const rhs = try macroBoolToInt(c, try parseCBitAndExpr(c, m, scope)); | 4562 | const rhs = try macroBoolToInt(c, try parseCBitAndExpr(c, m, scope)); |
| 4589 | node = try Node.bit_xor.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4563 | node = try Tag.bit_xor.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4590 | } | 4564 | } |
| 4591 | m.i -= 1; | 4565 | m.i -= 1; |
| 4592 | return node; | 4566 | return node; |
| ... | @@ -4597,7 +4571,7 @@ fn parseCBitAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4597,7 +4571,7 @@ fn parseCBitAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4597 | while (m.next().? == .Ampersand) { | 4571 | while (m.next().? == .Ampersand) { |
| 4598 | const lhs = try macroBoolToInt(c, node); | 4572 | const lhs = try macroBoolToInt(c, node); |
| 4599 | const rhs = try macroBoolToInt(c, try parseCEqExpr(c, m, scope)); | 4573 | const rhs = try macroBoolToInt(c, try parseCEqExpr(c, m, scope)); |
| 4600 | node = try Node.bit_and.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4574 | node = try Tag.bit_and.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4601 | } | 4575 | } |
| 4602 | m.i -= 1; | 4576 | m.i -= 1; |
| 4603 | return node; | 4577 | return node; |
| ... | @@ -4611,13 +4585,13 @@ fn parseCEqExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4611,13 +4585,13 @@ fn parseCEqExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4611 | _ = m.next(); | 4585 | _ = m.next(); |
| 4612 | const lhs = try macroBoolToInt(c, node); | 4586 | const lhs = try macroBoolToInt(c, node); |
| 4613 | const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope)); | 4587 | const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope)); |
| 4614 | node = try Node.not_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4588 | node = try Tag.not_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4615 | }, | 4589 | }, |
| 4616 | .EqualEqual => { | 4590 | .EqualEqual => { |
| 4617 | _ = m.next(); | 4591 | _ = m.next(); |
| 4618 | const lhs = try macroBoolToInt(c, node); | 4592 | const lhs = try macroBoolToInt(c, node); |
| 4619 | const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope)); | 4593 | const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope)); |
| 4620 | node = try Node.equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4594 | node = try Tag.equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4621 | }, | 4595 | }, |
| 4622 | else => return node, | 4596 | else => return node, |
| 4623 | } | 4597 | } |
| ... | @@ -4632,25 +4606,25 @@ fn parseCRelExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4632,25 +4606,25 @@ fn parseCRelExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4632 | _ = m.next(); | 4606 | _ = m.next(); |
| 4633 | const lhs = try macroBoolToInt(c, node); | 4607 | const lhs = try macroBoolToInt(c, node); |
| 4634 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); | 4608 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); |
| 4635 | node = try Node.greater_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4609 | node = try Tag.greater_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4636 | }, | 4610 | }, |
| 4637 | .AngleBracketRightEqual => { | 4611 | .AngleBracketRightEqual => { |
| 4638 | _ = m.next(); | 4612 | _ = m.next(); |
| 4639 | const lhs = try macroBoolToInt(c, node); | 4613 | const lhs = try macroBoolToInt(c, node); |
| 4640 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); | 4614 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); |
| 4641 | node = try Node.greater_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4615 | node = try Tag.greater_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4642 | }, | 4616 | }, |
| 4643 | .AngleBracketLeft => { | 4617 | .AngleBracketLeft => { |
| 4644 | _ = m.next(); | 4618 | _ = m.next(); |
| 4645 | const lhs = try macroBoolToInt(c, node); | 4619 | const lhs = try macroBoolToInt(c, node); |
| 4646 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); | 4620 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); |
| 4647 | node = try Node.less_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4621 | node = try Tag.less_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4648 | }, | 4622 | }, |
| 4649 | .AngleBracketLeftEqual => { | 4623 | .AngleBracketLeftEqual => { |
| 4650 | _ = m.next(); | 4624 | _ = m.next(); |
| 4651 | const lhs = try macroBoolToInt(c, node); | 4625 | const lhs = try macroBoolToInt(c, node); |
| 4652 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); | 4626 | const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope)); |
| 4653 | node = try Node.less_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4627 | node = try Tag.less_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4654 | }, | 4628 | }, |
| 4655 | else => return node, | 4629 | else => return node, |
| 4656 | } | 4630 | } |
| ... | @@ -4665,13 +4639,13 @@ fn parseCShiftExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4665,13 +4639,13 @@ fn parseCShiftExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4665 | _ = m.next(); | 4639 | _ = m.next(); |
| 4666 | const lhs = try macroBoolToInt(c, node); | 4640 | const lhs = try macroBoolToInt(c, node); |
| 4667 | const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope)); | 4641 | const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope)); |
| 4668 | node = try Node.shl.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4642 | node = try Tag.shl.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4669 | }, | 4643 | }, |
| 4670 | .AngleBracketAngleBracketRight => { | 4644 | .AngleBracketAngleBracketRight => { |
| 4671 | _ = m.next(); | 4645 | _ = m.next(); |
| 4672 | const lhs = try macroBoolToInt(c, node); | 4646 | const lhs = try macroBoolToInt(c, node); |
| 4673 | const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope)); | 4647 | const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope)); |
| 4674 | node = try Node.shr.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4648 | node = try Tag.shr.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4675 | }, | 4649 | }, |
| 4676 | else => return node, | 4650 | else => return node, |
| 4677 | } | 4651 | } |
| ... | @@ -4686,13 +4660,13 @@ fn parseCAddSubExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4686,13 +4660,13 @@ fn parseCAddSubExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4686 | _ = m.next(); | 4660 | _ = m.next(); |
| 4687 | const lhs = try macroBoolToInt(c, node); | 4661 | const lhs = try macroBoolToInt(c, node); |
| 4688 | const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope)); | 4662 | const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope)); |
| 4689 | node = try Node.add.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4663 | node = try Tag.add.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4690 | }, | 4664 | }, |
| 4691 | .Minus => { | 4665 | .Minus => { |
| 4692 | _ = m.next(); | 4666 | _ = m.next(); |
| 4693 | const lhs = try macroBoolToInt(c, node); | 4667 | const lhs = try macroBoolToInt(c, node); |
| 4694 | const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope)); | 4668 | const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope)); |
| 4695 | node = try Node.sub.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4669 | node = try Tag.sub.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4696 | }, | 4670 | }, |
| 4697 | else => return node, | 4671 | else => return node, |
| 4698 | } | 4672 | } |
| ... | @@ -4711,14 +4685,14 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4711,14 +4685,14 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4711 | const prev_id = m.list[m.i - 1].id; | 4685 | const prev_id = m.list[m.i - 1].id; |
| 4712 | | 4686 | |
| 4713 | if (prev_id == .Keyword_void) { | 4687 | if (prev_id == .Keyword_void) { |
| 4714 | const ptr = try Node.single_pointer.create(c.arena, .{ | 4688 | const ptr = try Tag.single_pointer.create(c.arena, .{ |
| 4715 | .is_const = false, | 4689 | .is_const = false, |
| 4716 | .is_volatile = false, | 4690 | .is_volatile = false, |
| 4717 | .elem_type = node, | 4691 | .elem_type = node, |
| 4718 | }); | 4692 | }); |
| 4719 | return Node.optional_type.create(c.arena, ptr); | 4693 | return Tag.optional_type.create(c.arena, ptr); |
| 4720 | } else { | 4694 | } else { |
| 4721 | return Node.c_pointer.create(c.arena, .{ | 4695 | return Tag.c_pointer.create(c.arena, .{ |
| 4722 | .is_const = false, | 4696 | .is_const = false, |
| 4723 | .is_volatile = false, | 4697 | .is_volatile = false, |
| 4724 | .elem_type = node, | 4698 | .elem_type = node, |
| ... | @@ -4728,18 +4702,18 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4728,18 +4702,18 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4728 | // expr * expr | 4702 | // expr * expr |
| 4729 | const lhs = try macroBoolToInt(c, node); | 4703 | const lhs = try macroBoolToInt(c, node); |
| 4730 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 4704 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); |
| 4731 | node = try Node.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4705 | node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4732 | } | 4706 | } |
| 4733 | }, | 4707 | }, |
| 4734 | .Slash => { | 4708 | .Slash => { |
| 4735 | const lhs = try macroBoolToInt(c, node); | 4709 | const lhs = try macroBoolToInt(c, node); |
| 4736 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 4710 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); |
| 4737 | node = try Node.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4711 | node = try Tag.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4738 | }, | 4712 | }, |
| 4739 | .Percent => { | 4713 | .Percent => { |
| 4740 | const lhs = try macroBoolToInt(c, node); | 4714 | const lhs = try macroBoolToInt(c, node); |
| 4741 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 4715 | const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); |
| 4742 | node = try Node.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 4716 | node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); |
| 4743 | }, | 4717 | }, |
| 4744 | else => { | 4718 | else => { |
| 4745 | m.i -= 1; | 4719 | m.i -= 1; |
| ... | @@ -4759,8 +4733,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4759,8 +4733,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4759 | return error.ParseError; | 4733 | return error.ParseError; |
| 4760 | } | 4734 | } |
| 4761 | | 4735 | |
| 4762 | const ident = try Node.identifier.create(c.arena, m.slice()); | 4736 | const ident = try Tag.identifier.create(c.arena, m.slice()); |
| 4763 | node = try Node.field_access.create(c.arena, .{ .lhs = node, .rhs = ident }); | 4737 | node = try Tag.field_access.create(c.arena, .{ .lhs = node, .rhs = ident }); |
| 4764 | }, | 4738 | }, |
| 4765 | .Arrow => { | 4739 | .Arrow => { |
| 4766 | if (m.next().? != .Identifier) { | 4740 | if (m.next().? != .Identifier) { |
| ... | @@ -4768,20 +4742,20 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4768,20 +4742,20 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4768 | return error.ParseError; | 4742 | return error.ParseError; |
| 4769 | } | 4743 | } |
| 4770 | | 4744 | |
| 4771 | const deref = try Node.deref.create(c.arena, node); | 4745 | const deref = try Tag.deref.create(c.arena, node); |
| 4772 | const ident = try Node.identifier.create(c.arena, m.slice()); | 4746 | const ident = try Tag.identifier.create(c.arena, m.slice()); |
| 4773 | node = try Node.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident }); | 4747 | node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident }); |
| 4774 | }, | 4748 | }, |
| 4775 | .LBracket => { | 4749 | .LBracket => { |
| 4776 | const index = try macroBoolToInt(c, try parseCExpr(c, m, scope)); | 4750 | const index = try macroBoolToInt(c, try parseCExpr(c, m, scope)); |
| 4777 | node = try Node.array_access.create(c.arena, .{ .lhs = node, .rhs = index }); | 4751 | node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index }); |
| 4778 | }, | 4752 | }, |
| 4779 | .LParen => { | 4753 | .LParen => { |
| 4780 | var call_params = std.ArrayList(Node).init(c.gpa); | 4754 | var args = std.ArrayList(Node).init(c.gpa); |
| 4781 | defer call_params.deinit(); | 4755 | defer args.deinit(); |
| 4782 | while (true) { | 4756 | while (true) { |
| 4783 | const arg = try parseCCondExpr(c, m, scope); | 4757 | const arg = try parseCCondExpr(c, m, scope); |
| 4784 | try call_params.append(arg); | 4758 | try args.append(arg); |
| 4785 | switch (m.next().?) { | 4759 | switch (m.next().?) { |
| 4786 | .Comma => {}, | 4760 | .Comma => {}, |
| 4787 | .RParen => break, | 4761 | .RParen => break, |
| ... | @@ -4791,7 +4765,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4791,7 +4765,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4791 | }, | 4765 | }, |
| 4792 | } | 4766 | } |
| 4793 | } | 4767 | } |
| 4794 | node = try Node.call.create(c.arena, .{ .lhs = node, .rhs = try c.arena.dupe(Node, call_params.items) }); | 4768 | node = try Tag.call.create(c.arena, .{ .lhs = node, .args = try c.arena.dupe(Node, args.items) }); |
| 4795 | }, | 4769 | }, |
| 4796 | .LBrace => { | 4770 | .LBrace => { |
| 4797 | var init_vals = std.ArrayList(Node).init(c.gpa); | 4771 | var init_vals = std.ArrayList(Node).init(c.gpa); |
| ... | @@ -4809,8 +4783,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4809,8 +4783,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4809 | }, | 4783 | }, |
| 4810 | } | 4784 | } |
| 4811 | } | 4785 | } |
| 4812 | const tuple_node = try Node.tuple.create(c.arena, try c.arena.dupe(Node, init_vals.items)); | 4786 | const tuple_node = try Tag.tuple.create(c.arena, try c.arena.dupe(Node, init_vals.items)); |
| 4813 | node = try Node.std_mem_zeroinit.create(c.arena, .{ .lhs = node, .rhs = tuple_node }); | 4787 | node = try Tag.std_mem_zeroinit.create(c.arena, .{ .lhs = node, .rhs = tuple_node }); |
| 4814 | }, | 4788 | }, |
| 4815 | .PlusPlus, .MinusMinus => { | 4789 | .PlusPlus, .MinusMinus => { |
| 4816 | try m.fail(c, "TODO postfix inc/dec expr", .{}); | 4790 | try m.fail(c, "TODO postfix inc/dec expr", .{}); |
| ... | @@ -4828,24 +4802,24 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4828,24 +4802,24 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4828 | switch (m.next().?) { | 4802 | switch (m.next().?) { |
| 4829 | .Bang => { | 4803 | .Bang => { |
| 4830 | const operand = try macroIntToBool(c, try parseCUnaryExpr(c, m, scope)); | 4804 | const operand = try macroIntToBool(c, try parseCUnaryExpr(c, m, scope)); |
| 4831 | return Node.not.create(c.arena, operand); | 4805 | return Tag.not.create(c.arena, operand); |
| 4832 | }, | 4806 | }, |
| 4833 | .Minus => { | 4807 | .Minus => { |
| 4834 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 4808 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); |
| 4835 | return Node.negate.create(c.arena, operand); | 4809 | return Tag.negate.create(c.arena, operand); |
| 4836 | }, | 4810 | }, |
| 4837 | .Plus => return try parseCUnaryExpr(c, m, scope), | 4811 | .Plus => return try parseCUnaryExpr(c, m, scope), |
| 4838 | .Tilde => { | 4812 | .Tilde => { |
| 4839 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); | 4813 | const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope)); |
| 4840 | return Node.bit_not.create(c.arena, operand); | 4814 | return Tag.bit_not.create(c.arena, operand); |
| 4841 | }, | 4815 | }, |
| 4842 | .Asterisk => { | 4816 | .Asterisk => { |
| 4843 | const operand = try parseCUnaryExpr(c, m, scope); | 4817 | const operand = try parseCUnaryExpr(c, m, scope); |
| 4844 | return Node.deref.create(c.arena, operand); | 4818 | return Tag.deref.create(c.arena, operand); |
| 4845 | }, | 4819 | }, |
| 4846 | .Ampersand => { | 4820 | .Ampersand => { |
| 4847 | const operand = try parseCUnaryExpr(c, m, scope); | 4821 | const operand = try parseCUnaryExpr(c, m, scope); |
| 4848 | return Node.address_of.create(c.arena, operand); | 4822 | return Tag.address_of.create(c.arena, operand); |
| 4849 | }, | 4823 | }, |
| 4850 | .Keyword_sizeof => { | 4824 | .Keyword_sizeof => { |
| 4851 | const operand = if (m.peek().? == .LParen) blk: { | 4825 | const operand = if (m.peek().? == .LParen) blk: { |
| ... | @@ -4860,7 +4834,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4860,7 +4834,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4860 | break :blk inner; | 4834 | break :blk inner; |
| 4861 | } else try parseCUnaryExpr(c, m, scope); | 4835 | } else try parseCUnaryExpr(c, m, scope); |
| 4862 | | 4836 | |
| 4863 | return Node.std_meta_sizeof.create(c.arena, operand); | 4837 | return Tag.std_meta_sizeof.create(c.arena, operand); |
| 4864 | }, | 4838 | }, |
| 4865 | .Keyword_alignof => { | 4839 | .Keyword_alignof => { |
| 4866 | // TODO this won't work if using <stdalign.h>'s | 4840 | // TODO this won't work if using <stdalign.h>'s |
| ... | @@ -4877,7 +4851,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -4877,7 +4851,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4877 | return error.ParseError; | 4851 | return error.ParseError; |
| 4878 | } | 4852 | } |
| 4879 | | 4853 | |
| 4880 | return Node.alignof.create(c.arena, operand); | 4854 | return Tag.alignof.create(c.arena, operand); |
| 4881 | }, | 4855 | }, |
| 4882 | .PlusPlus, .MinusMinus => { | 4856 | .PlusPlus, .MinusMinus => { |
| 4883 | try m.fail(c, "TODO unary inc/dec expr", .{}); | 4857 | try m.fail(c, "TODO unary inc/dec expr", .{}); |
| ... | @@ -4902,7 +4876,7 @@ fn getContainer(c: *Context, node: Node) ?Node { | ... | @@ -4902,7 +4876,7 @@ fn getContainer(c: *Context, node: Node) ?Node { |
| 4902 | .negate, | 4876 | .negate, |
| 4903 | .negate_wrap, | 4877 | .negate_wrap, |
| 4904 | .array_type, | 4878 | .array_type, |
| 4905 | .c_pointer, | 4879 | .c_pointer, |
| 4906 | .single_pointer, | 4880 | .single_pointer, |
| 4907 | => return node, | 4881 | => return node, |
| 4908 | | 4882 | |
| ... | @@ -4910,7 +4884,7 @@ fn getContainer(c: *Context, node: Node) ?Node { | ... | @@ -4910,7 +4884,7 @@ fn getContainer(c: *Context, node: Node) ?Node { |
| 4910 | const ident = node.castTag(.identifier).?; | 4884 | const ident = node.castTag(.identifier).?; |
| 4911 | if (c.global_scope.sym_table.get(ident.data)) |value| { | 4885 | if (c.global_scope.sym_table.get(ident.data)) |value| { |
| 4912 | if (value.castTag(.var_decl)) |var_decl| | 4886 | if (value.castTag(.var_decl)) |var_decl| |
| 4913 | return getContainer(c, var_decl.data.init); | 4887 | return getContainer(c, var_decl.data.init.?); |
| 4914 | if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |var_decl| | 4888 | if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |var_decl| |
| 4915 | return getContainer(c, var_decl.data.init); | 4889 | return getContainer(c, var_decl.data.init); |
| 4916 | } | 4890 | } |
| ... | @@ -4923,8 +4897,8 @@ fn getContainer(c: *Context, node: Node) ?Node { | ... | @@ -4923,8 +4897,8 @@ fn getContainer(c: *Context, node: Node) ?Node { |
| 4923 | if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| { | 4897 | if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| { |
| 4924 | for (container.data.fields) |field| { | 4898 | for (container.data.fields) |field| { |
| 4925 | const ident = infix.data.rhs.castTag(.identifier).?; | 4899 | const ident = infix.data.rhs.castTag(.identifier).?; |
| 4926 | if (mem.eql(u8, field.data.name, field.data)) { | 4900 | if (mem.eql(u8, field.name, ident.data)) { |
| 4927 | return getContainer(c, field.type_expr.?); | 4901 | return getContainer(c, field.type); |
| 4928 | } | 4902 | } |
| 4929 | } | 4903 | } |
| 4930 | } | 4904 | } |
| ... | @@ -4960,9 +4934,9 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node { | ... | @@ -4960,9 +4934,9 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node { |
| 4960 | } | 4934 | } |
| 4961 | | 4935 | |
| 4962 | fn getFnProto(c: *Context, ref: Node) ?*ast.Payload.Func { | 4936 | fn getFnProto(c: *Context, ref: Node) ?*ast.Payload.Func { |
| 4963 | const init = if (value.castTag(.var_decl)) |v| | 4937 | const init = if (ref.castTag(.var_decl)) |v| |
| 4964 | v.data.init | 4938 | v.data.init orelse return null |
| 4965 | else if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |v| | 4939 | else if (ref.castTag(.var_simple) orelse ref.castTag(.pub_var_simple)) |v| |
| 4966 | v.data.init | 4940 | v.data.init |
| 4967 | else | 4941 | else |
| 4968 | return null; | 4942 | return null; |