| ... | @@ -54,44 +54,79 @@ const Scope = struct { | ... | @@ -54,44 +54,79 @@ const Scope = struct { |
| 54 | Loop, | 54 | Loop, |
| 55 | }; | 55 | }; |
| 56 | | 56 | |
| | 57 | /// Represents an in-progress ast.Node.Switch. This struct is stack-allocated. |
| | 58 | /// When it is deinitialized, it produces an ast.Node.Switch which is allocated |
| | 59 | /// into the main arena. |
| 57 | const Switch = struct { | 60 | const Switch = struct { |
| 58 | base: Scope, | 61 | base: Scope, |
| 59 | pending_block: *ast.Node.Block, | 62 | pending_block: *Block, |
| 60 | cases: *ast.Node.Switch.CaseList, | 63 | cases: []*ast.Node, |
| | 64 | case_index: usize, |
| 61 | has_default: bool = false, | 65 | has_default: bool = false, |
| 62 | }; | 66 | }; |
| 63 | | 67 | |
| | 68 | /// Used for the scope of condition expressions, for example `if (cond)`. |
| | 69 | /// The block is lazily initialised because it is only needed for rare |
| | 70 | /// cases of comma operators being used. |
| | 71 | const Condition = struct { |
| | 72 | base: Scope, |
| | 73 | block: ?Block = null, |
| | 74 | |
| | 75 | fn getBlockScope(self: *Condition, c: *Context) !*Block { |
| | 76 | if (self.block) |*b| return b; |
| | 77 | self.block = try Block.init(c, &self.base, "blk"); |
| | 78 | return &self.block.?; |
| | 79 | } |
| | 80 | |
| | 81 | fn deinit(self: *Condition) void { |
| | 82 | if (self.block) |*b| b.deinit(); |
| | 83 | } |
| | 84 | }; |
| | 85 | |
| | 86 | /// Represents an in-progress ast.Node.Block. This struct is stack-allocated. |
| | 87 | /// When it is deinitialized, it produces an ast.Node.Block which is allocated |
| | 88 | /// into the main arena. |
| 64 | const Block = struct { | 89 | const Block = struct { |
| 65 | base: Scope, | 90 | base: Scope, |
| 66 | block_node: *ast.Node.Block, | 91 | statements: std.ArrayList(*ast.Node), |
| 67 | statements_it: *?*std.SinglyLinkedList(*ast.Node), | | |
| 68 | variables: AliasList, | 92 | variables: AliasList, |
| 69 | label: ?[]const u8, | 93 | label: ?ast.TokenIndex, |
| 70 | mangle_count: u32 = 0, | 94 | mangle_count: u32 = 0, |
| | 95 | lbrace: ast.TokenIndex, |
| 71 | | 96 | |
| 72 | /// Don't forget to set rbrace token and block_node later | 97 | fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block { |
| 73 | fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block { | 98 | return Block{ |
| 74 | const block = try c.arena.create(Block); | | |
| 75 | block.* = .{ | | |
| 76 | .base = .{ | 99 | .base = .{ |
| 77 | .id = .Block, | 100 | .id = .Block, |
| 78 | .parent = parent, | 101 | .parent = parent, |
| 79 | }, | 102 | }, |
| 80 | .block_node = undefined, | 103 | .statements = std.ArrayList(*ast.Node).init(c.gpa), |
| 81 | .statements_it = undefined, | 104 | .variables = AliasList.init(c.gpa), |
| 82 | .variables = AliasList.init(c.arena), | 105 | .label = if (self.label) |l| blk: { |
| 83 | .label = label, | 106 | const ll = try appendIdentifier(c, l); |
| | 107 | _ = try appendToken(c, .Colon, ":"); |
| | 108 | break :blk ll; |
| | 109 | } else null, |
| | 110 | .lbrace = try appendToken(c, .LBrace, "{"), |
| 84 | }; | 111 | }; |
| 85 | return block; | | |
| 86 | } | 112 | } |
| 87 | | 113 | |
| 88 | fn pushStatement(self: *Block, c: *Context, stmt: *ast.Node) !void { | 114 | fn deinit(self: *Block) void { |
| 89 | self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt); | 115 | self.statements.deinit(); |
| | 116 | self.variables.deinit(); |
| | 117 | self.* = undefined; |
| 90 | } | 118 | } |
| 91 | | 119 | |
| 92 | fn setBlockNode(self: *Block, block: *ast.Node.Block) void { | 120 | fn complete(self: *Block, c: *Context) !*ast.Node.Block { |
| 93 | self.block_node = block; | 121 | const node = try ast.Node.Block.alloc(c.arena, self.statements.items.len); |
| 94 | self.statements_it = &block.statements.first; | 122 | node.* = .{ |
| | 123 | .statements_len = self.statements.items.len, |
| | 124 | .lbrace = self.lbrace, |
| | 125 | .rbrace = try appendToken(c, .RBrace, "}"), |
| | 126 | .label = self.label, |
| | 127 | }; |
| | 128 | mem.copy(*ast.Node, node.statements(), self.statements.items); |
| | 129 | return node; |
| 95 | } | 130 | } |
| 96 | | 131 | |
| 97 | /// Given the desired name, return a name that does not shadow anything from outer scopes. | 132 | /// Given the desired name, return a name that does not shadow anything from outer scopes. |
| ... | @@ -102,12 +137,13 @@ const Scope = struct { | ... | @@ -102,12 +137,13 @@ const Scope = struct { |
| 102 | scope.mangle_count += 1; | 137 | scope.mangle_count += 1; |
| 103 | proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count }); | 138 | proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count }); |
| 104 | } | 139 | } |
| 105 | try scope.variables.append(.{ .name = name, .alias = proposed_name }); | 140 | try scope.variables.push(.{ .name = name, .alias = proposed_name }); |
| 106 | return proposed_name; | 141 | return proposed_name; |
| 107 | } | 142 | } |
| 108 | | 143 | |
| 109 | fn getAlias(scope: *Block, name: []const u8) []const u8 { | 144 | fn getAlias(scope: *Block, name: []const u8) []const u8 { |
| 110 | for (scope.variables.items) |p| { | 145 | var it = scope.variables.iterator(0); |
| | 146 | while (it.next()) |p| { |
| 111 | if (mem.eql(u8, p.name, name)) | 147 | if (mem.eql(u8, p.name, name)) |
| 112 | return p.alias; | 148 | return p.alias; |
| 113 | } | 149 | } |
| ... | @@ -115,7 +151,8 @@ const Scope = struct { | ... | @@ -115,7 +151,8 @@ const Scope = struct { |
| 115 | } | 151 | } |
| 116 | | 152 | |
| 117 | fn localContains(scope: *Block, name: []const u8) bool { | 153 | fn localContains(scope: *Block, name: []const u8) bool { |
| 118 | for (scope.variables.items) |p| { | 154 | var it = scope.variables.iterator(0); |
| | 155 | while (it.next()) |p| { |
| 119 | if (mem.eql(u8, p.name, name)) | 156 | if (mem.eql(u8, p.name, name)) |
| 120 | return true; | 157 | return true; |
| 121 | } | 158 | } |
| ... | @@ -167,10 +204,7 @@ const Scope = struct { | ... | @@ -167,10 +204,7 @@ const Scope = struct { |
| 167 | switch (scope.id) { | 204 | switch (scope.id) { |
| 168 | .Root => unreachable, | 205 | .Root => unreachable, |
| 169 | .Block => return @fieldParentPtr(Block, "base", scope), | 206 | .Block => return @fieldParentPtr(Block, "base", scope), |
| 170 | .Condition => { | 207 | .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c), |
| 171 | // comma operator used | | |
| 172 | return try Block.init(c, scope, "blk"); | | |
| 173 | }, | | |
| 174 | else => scope = scope.parent.?, | 208 | else => scope = scope.parent.?, |
| 175 | } | 209 | } |
| 176 | } | 210 | } |
| ... | @@ -219,7 +253,8 @@ const Scope = struct { | ... | @@ -219,7 +253,8 @@ const Scope = struct { |
| 219 | pub const Context = struct { | 253 | pub const Context = struct { |
| 220 | gpa: *mem.Allocator, | 254 | gpa: *mem.Allocator, |
| 221 | arena: *mem.Allocator, | 255 | arena: *mem.Allocator, |
| 222 | tokens: std.ArrayListUnmanaged(Token), | 256 | token_ids: std.ArrayListUnmanaged(Token.Id), |
| | 257 | token_locs: std.ArrayListUnmanaged(Token.Loc), |
| 223 | errors: std.ArrayListUnmanaged(ast.Error), | 258 | errors: std.ArrayListUnmanaged(ast.Error), |
| 224 | source_buffer: *std.ArrayList(u8), | 259 | source_buffer: *std.ArrayList(u8), |
| 225 | err: Error, | 260 | err: Error, |
| ... | @@ -237,16 +272,6 @@ pub const Context = struct { | ... | @@ -237,16 +272,6 @@ pub const Context = struct { |
| 237 | /// up front in a pre-processing step. | 272 | /// up front in a pre-processing step. |
| 238 | global_names: std.StringHashMap(void), | 273 | global_names: std.StringHashMap(void), |
| 239 | | 274 | |
| 240 | /// Helper type to append elements to a singly linked list. | | |
| 241 | const LinkedListPusher = struct { | | |
| 242 | c: *Context, | | |
| 243 | it: *?*std.SinglyLinkedList(*ast.Node).Node, | | |
| 244 | | | |
| 245 | fn push(self: *LinkedListPusher, element: *ast.Node) !void { | | |
| 246 | self.it = try self.c.llpush(*ast.Node, self.it, element); | | |
| 247 | } | | |
| 248 | }; | | |
| 249 | | | |
| 250 | fn getMangle(c: *Context) u32 { | 275 | fn getMangle(c: *Context) u32 { |
| 251 | c.mangle_count += 1; | 276 | c.mangle_count += 1; |
| 252 | return c.mangle_count; | 277 | return c.mangle_count; |
| ... | @@ -267,6 +292,46 @@ pub const Context = struct { | ... | @@ -267,6 +292,46 @@ pub const Context = struct { |
| 267 | const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc); | 292 | const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc); |
| 268 | return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column }); | 293 | return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column }); |
| 269 | } | 294 | } |
| | 295 | |
| | 296 | fn createCall(c: *Context, fn_expr: *ast.Node, params_len: ast.NodeIndex) !*ast.Node.Call { |
| | 297 | _ = try appendToken(c, .LParen, "("); |
| | 298 | const node = try ast.Node.Call.alloc(c.arena, params_len); |
| | 299 | node.* = .{ |
| | 300 | .lhs = fn_expr, |
| | 301 | .params_len = params_len, |
| | 302 | .async_token = null, |
| | 303 | .rtoken = undefined, // set after appending args |
| | 304 | }; |
| | 305 | return node; |
| | 306 | } |
| | 307 | |
| | 308 | fn createBuiltinCall(c: *Context, name: []const u8, params_len: ast.NodeIndex) !*ast.Node.BuiltinCall { |
| | 309 | const builtin_token = try appendToken(c, .Builtin, name); |
| | 310 | _ = try appendToken(c, .LParen, "("); |
| | 311 | const node = try ast.Node.BuiltinCall.alloc(c.arena, params_len); |
| | 312 | node.* = .{ |
| | 313 | .builtin_token = builtin_token, |
| | 314 | .params_len = params_len, |
| | 315 | .rparen_token = undefined, // set after appending args |
| | 316 | }; |
| | 317 | return node; |
| | 318 | } |
| | 319 | |
| | 320 | fn createBlock(c: *Context, label: ?[]const u8, statements_len: ast.NodeIndex) !*ast.Node.Block { |
| | 321 | const label_node = if (label) |l| blk: { |
| | 322 | const ll = try appendIdentifier(c, l); |
| | 323 | _ = try appendToken(c, .Colon, ":"); |
| | 324 | break :blk ll; |
| | 325 | } else null; |
| | 326 | const block_node = try ast.Node.Block.alloc(c.arena, statements_len); |
| | 327 | block_node.* = .{ |
| | 328 | .label = label_node, |
| | 329 | .lbrace = try appendToken(c, .LBrace, "{"), |
| | 330 | .statements_len = statements_len, |
| | 331 | .rbrace = undefined, |
| | 332 | }; |
| | 333 | return block_node; |
| | 334 | } |
| 270 | }; | 335 | }; |
| 271 | | 336 | |
| 272 | pub fn translate( | 337 | pub fn translate( |
| ... | @@ -307,14 +372,16 @@ pub fn translate( | ... | @@ -307,14 +372,16 @@ pub fn translate( |
| 307 | .global_scope = try arena.allocator.create(Scope.Root), | 372 | .global_scope = try arena.allocator.create(Scope.Root), |
| 308 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, | 373 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, |
| 309 | .global_names = std.StringHashMap(void).init(gpa), | 374 | .global_names = std.StringHashMap(void).init(gpa), |
| 310 | .tokens = .{}, | 375 | .token_ids = .{}, |
| | 376 | .token_locs = .{}, |
| 311 | .errors = .{}, | 377 | .errors = .{}, |
| 312 | .root_decls = .{}, | 378 | .root_decls = .{}, |
| 313 | }; | 379 | }; |
| 314 | context.global_scope.* = Scope.Root.init(&context); | 380 | context.global_scope.* = Scope.Root.init(&context); |
| 315 | defer context.decl_table.deinit(); | 381 | defer context.decl_table.deinit(); |
| 316 | defer context.alias_list.deinit(); | 382 | defer context.alias_list.deinit(); |
| 317 | defer context.tokens.deinit(gpa); | 383 | defer context.token_ids.deinit(gpa); |
| | 384 | defer context.token_locs.deinit(gpa); |
| 318 | defer context.errors.deinit(gpa); | 385 | defer context.errors.deinit(gpa); |
| 319 | defer context.global_names.deinit(); | 386 | defer context.global_names.deinit(); |
| 320 | defer context.root_decls.deinit(gpa); | 387 | defer context.root_decls.deinit(gpa); |
| ... | @@ -349,7 +416,8 @@ pub fn translate( | ... | @@ -349,7 +416,8 @@ pub fn translate( |
| 349 | tree.* = .{ | 416 | tree.* = .{ |
| 350 | .gpa = gpa, | 417 | .gpa = gpa, |
| 351 | .source = try arena.allocator.dupe(u8, source_buffer.items), | 418 | .source = try arena.allocator.dupe(u8, source_buffer.items), |
| 352 | .tokens = context.tokens.toOwnedSlice(gpa), | 419 | .token_ids = context.token_ids.toOwnedSlice(gpa), |
| | 420 | .token_locs = context.token_locs.toOwnedSlice(gpa), |
| 353 | .errors = context.errors.toOwnedSlice(gpa), | 421 | .errors = context.errors.toOwnedSlice(gpa), |
| 354 | .root_node = root_node, | 422 | .root_node = root_node, |
| 355 | .arena = arena.state, | 423 | .arena = arena.state, |
| ... | @@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 508 | | 576 | |
| 509 | // actual function definition with body | 577 | // actual function definition with body |
| 510 | const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); | 578 | const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); |
| 511 | const block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null); | 579 | var block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null); |
| | 580 | defer block_scope.deinit(); |
| 512 | var scope = &block_scope.base; | 581 | var scope = &block_scope.base; |
| 513 | const block_node = try transCreateNodeBlock(rp.c, null); | | |
| 514 | block_scope.setBlockNode(block_node); | | |
| 515 | | 582 | |
| 516 | var param_id: c_uint = 0; | 583 | var param_id: c_uint = 0; |
| 517 | for (proto_node.params()) |param, i| { | 584 | for (proto_node.params()) |param, i| { |
| ... | @@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 541 | node.eq_token = try appendToken(c, .Equal, "="); | 608 | node.eq_token = try appendToken(c, .Equal, "="); |
| 542 | node.init_node = try transCreateNodeIdentifier(c, arg_name); | 609 | node.init_node = try transCreateNodeIdentifier(c, arg_name); |
| 543 | node.semicolon_token = try appendToken(c, .Semicolon, ";"); | 610 | node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 544 | block_scope.block_statements_it = try c.llpush(*ast.Node, block_scope.block_statements_it, &node.base); | 611 | try block_scope.statements.append(&node.base); |
| 545 | param.name_token = try appendIdentifier(c, arg_name); | 612 | param.name_token = try appendIdentifier(c, arg_name); |
| 546 | _ = try appendToken(c, .Colon, ":"); | 613 | _ = try appendToken(c, .Colon, ":"); |
| 547 | } | 614 | } |
| ... | @@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 549 | param_id += 1; | 616 | param_id += 1; |
| 550 | } | 617 | } |
| 551 | | 618 | |
| 552 | transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) { | 619 | const casted_body = @ptrCast(*const ZigClangCompoundStmt, body_stmt); |
| | 620 | transCompoundStmtInline(rp, &block_scope.base, casted_body, &block_scope) catch |err| switch (err) { |
| 553 | error.OutOfMemory => |e| return e, | 621 | error.OutOfMemory => |e| return e, |
| 554 | error.UnsupportedTranslation, | 622 | error.UnsupportedTranslation, |
| 555 | error.UnsupportedType, | 623 | error.UnsupportedType, |
| 556 | => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}), | 624 | => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}), |
| 557 | }; | 625 | }; |
| 558 | block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 626 | proto_node.body_node = try block_scope.complete(rp.c); |
| 559 | proto_node.body_node = &block_node.base; | | |
| 560 | return addTopLevelDecl(c, fn_name, &proto_node.base); | 627 | return addTopLevelDecl(c, fn_name, &proto_node.base); |
| 561 | } | 628 | } |
| 562 | | 629 | |
| ... | @@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 999 | // At this point we can rely on the enum emitting successfully. | 1066 | // At this point we can rely on the enum emitting successfully. |
| 1000 | const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name); | 1067 | const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name); |
| 1001 | tld_node.eq_token = try appendToken(c, .Equal, "="); | 1068 | tld_node.eq_token = try appendToken(c, .Equal, "="); |
| 1002 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); | 1069 | const cast_node = try rp.c.createBuiltinCall("@enumToInt", 1); |
| 1003 | const enum_ident = try transCreateNodeIdentifier(c, name); | 1070 | const enum_ident = try transCreateNodeIdentifier(c, name); |
| 1004 | const period_tok = try appendToken(c, .Period, "."); | 1071 | const period_tok = try appendToken(c, .Period, "."); |
| 1005 | const field_ident = try transCreateNodeIdentifier(c, field_name); | 1072 | const field_ident = try transCreateNodeIdentifier(c, field_name); |
| ... | @@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1010 | .op = .Period, | 1077 | .op = .Period, |
| 1011 | .rhs = field_ident, | 1078 | .rhs = field_ident, |
| 1012 | }; | 1079 | }; |
| 1013 | try cast_node.params.push(&field_access_node.base); | 1080 | cast_node.params()[0] = &field_access_node.base; |
| 1014 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1081 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1015 | tld_node.init_node = &cast_node.base; | 1082 | tld_node.init_node = &cast_node.base; |
| 1016 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); | 1083 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| ... | @@ -1104,7 +1171,7 @@ fn transStmt( | ... | @@ -1104,7 +1171,7 @@ fn transStmt( |
| 1104 | .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)), | 1171 | .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)), |
| 1105 | .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)), | 1172 | .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)), |
| 1106 | .NullStmtClass => { | 1173 | .NullStmtClass => { |
| 1107 | const block = try transCreateNodeBlock(rp.c, null); | 1174 | const block = try rp.c.createBlock(null, 0); |
| 1108 | block.rbrace = try appendToken(rp.c, .RBrace, "}"); | 1175 | block.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 1109 | return &block.base; | 1176 | return &block.base; |
| 1110 | }, | 1177 | }, |
| ... | @@ -1170,27 +1237,23 @@ fn transBinaryOperator( | ... | @@ -1170,27 +1237,23 @@ fn transBinaryOperator( |
| 1170 | .Comma => { | 1237 | .Comma => { |
| 1171 | const block_scope = try scope.findBlockScope(rp.c); | 1238 | const block_scope = try scope.findBlockScope(rp.c); |
| 1172 | const expr = block_scope.base.parent == scope; | 1239 | const expr = block_scope.base.parent == scope; |
| 1173 | const lparen = if (expr) blk: { | 1240 | const lparen = if (expr) try appendToken(rp.c, .LParen, "(") else undefined; |
| 1174 | const l = try appendToken(rp.c, .LParen, "("); | | |
| 1175 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | | |
| 1176 | break :blk l; | | |
| 1177 | } else undefined; | | |
| 1178 | | 1241 | |
| 1179 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); | 1242 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); |
| 1180 | try block_scope.statements.push(lhs); | 1243 | try block_scope.statements.append(lhs); |
| 1181 | | 1244 | |
| 1182 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 1245 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1183 | if (expr) { | 1246 | if (expr) { |
| 1184 | _ = try appendToken(rp.c, .Semicolon, ";"); | 1247 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1185 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 1248 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 1186 | break_node.rhs = rhs; | 1249 | break_node.rhs = rhs; |
| 1187 | try block_scope.block_node.statements.push(&break_node.base); | 1250 | try block_scope.statements.append(&break_node.base); |
| 1188 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 1251 | const block_node = try block_scope.complete(rp.c); |
| 1189 | const rparen = try appendToken(rp.c, .RParen, ")"); | 1252 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 1190 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 1253 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 1191 | grouped_expr.* = .{ | 1254 | grouped_expr.* = .{ |
| 1192 | .lparen = lparen, | 1255 | .lparen = lparen, |
| 1193 | .expr = &block_scope.block_node.base, | 1256 | .expr = &block_node.base, |
| 1194 | .rparen = rparen, | 1257 | .rparen = rparen, |
| 1195 | }; | 1258 | }; |
| 1196 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); | 1259 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); |
| ... | @@ -1201,11 +1264,11 @@ fn transBinaryOperator( | ... | @@ -1201,11 +1264,11 @@ fn transBinaryOperator( |
| 1201 | .Div => { | 1264 | .Div => { |
| 1202 | if (cIsSignedInteger(qt)) { | 1265 | if (cIsSignedInteger(qt)) { |
| 1203 | // signed integer division uses @divTrunc | 1266 | // signed integer division uses @divTrunc |
| 1204 | const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc"); | 1267 | const div_trunc_node = try rp.c.createBuiltinCall("@divTrunc", 2); |
| 1205 | try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); | 1268 | div_trunc_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 1206 | _ = try appendToken(rp.c, .Comma, ","); | 1269 | _ = try appendToken(rp.c, .Comma, ","); |
| 1207 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 1270 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1208 | try div_trunc_node.params.push(rhs); | 1271 | div_trunc_node.params()[1] = rhs; |
| 1209 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1272 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1210 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); | 1273 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); |
| 1211 | } | 1274 | } |
| ... | @@ -1213,11 +1276,11 @@ fn transBinaryOperator( | ... | @@ -1213,11 +1276,11 @@ fn transBinaryOperator( |
| 1213 | .Rem => { | 1276 | .Rem => { |
| 1214 | if (cIsSignedInteger(qt)) { | 1277 | if (cIsSignedInteger(qt)) { |
| 1215 | // signed integer division uses @rem | 1278 | // signed integer division uses @rem |
| 1216 | const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem"); | 1279 | const rem_node = try rp.c.createBuiltinCall("@rem", 2); |
| 1217 | try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); | 1280 | rem_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 1218 | _ = try appendToken(rp.c, .Comma, ","); | 1281 | _ = try appendToken(rp.c, .Comma, ","); |
| 1219 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 1282 | const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1220 | try rem_node.params.push(rhs); | 1283 | rem_node.params()[1] = rhs; |
| 1221 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1284 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1222 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); | 1285 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); |
| 1223 | } | 1286 | } |
| ... | @@ -1321,15 +1384,15 @@ fn transBinaryOperator( | ... | @@ -1321,15 +1384,15 @@ fn transBinaryOperator( |
| 1321 | const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 1384 | const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1322 | | 1385 | |
| 1323 | const lhs = if (isBoolRes(lhs_node)) init: { | 1386 | const lhs = if (isBoolRes(lhs_node)) init: { |
| 1324 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1387 | const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1325 | try cast_node.params.push(lhs_node); | 1388 | cast_node.params()[0] = lhs_node; |
| 1326 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1389 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1327 | break :init &cast_node.base; | 1390 | break :init &cast_node.base; |
| 1328 | } else lhs_node; | 1391 | } else lhs_node; |
| 1329 | | 1392 | |
| 1330 | const rhs = if (isBoolRes(rhs_node)) init: { | 1393 | const rhs = if (isBoolRes(rhs_node)) init: { |
| 1331 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1394 | const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1332 | try cast_node.params.push(rhs_node); | 1395 | cast_node.params()[0] = rhs_node; |
| 1333 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1396 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1334 | break :init &cast_node.base; | 1397 | break :init &cast_node.base; |
| 1335 | } else rhs_node; | 1398 | } else rhs_node; |
| ... | @@ -1341,23 +1404,22 @@ fn transCompoundStmtInline( | ... | @@ -1341,23 +1404,22 @@ fn transCompoundStmtInline( |
| 1341 | rp: RestorePoint, | 1404 | rp: RestorePoint, |
| 1342 | parent_scope: *Scope, | 1405 | parent_scope: *Scope, |
| 1343 | stmt: *const ZigClangCompoundStmt, | 1406 | stmt: *const ZigClangCompoundStmt, |
| 1344 | block_node: *ast.Node.Block, | 1407 | block: *Scope.Block, |
| 1345 | ) TransError!void { | 1408 | ) TransError!void { |
| 1346 | var it = ZigClangCompoundStmt_body_begin(stmt); | 1409 | var it = ZigClangCompoundStmt_body_begin(stmt); |
| 1347 | const end_it = ZigClangCompoundStmt_body_end(stmt); | 1410 | const end_it = ZigClangCompoundStmt_body_end(stmt); |
| 1348 | while (it != end_it) : (it += 1) { | 1411 | while (it != end_it) : (it += 1) { |
| 1349 | const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value); | 1412 | const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value); |
| 1350 | if (result != &block_node.base) | 1413 | try block.statements.append(result); |
| 1351 | try block_node.statements.push(result); | | |
| 1352 | } | 1414 | } |
| 1353 | } | 1415 | } |
| 1354 | | 1416 | |
| 1355 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { | 1417 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { |
| 1356 | const block_scope = try Scope.Block.init(rp.c, scope, null); | 1418 | var block_scope = try Scope.Block.init(rp.c, scope, null); |
| 1357 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, null)); | 1419 | defer block_scope.deinit(); |
| 1358 | try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node); | 1420 | try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope); |
| 1359 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 1421 | const node = block_scope.complete(c); |
| 1360 | return &block_scope.block_node.base; | 1422 | return &node.base; |
| 1361 | } | 1423 | } |
| 1362 | | 1424 | |
| 1363 | fn transCStyleCastExprClass( | 1425 | fn transCStyleCastExprClass( |
| ... | @@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) | ... | @@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) |
| 1411 | else | 1473 | else |
| 1412 | try transCreateNodeUndefinedLiteral(c); | 1474 | try transCreateNodeUndefinedLiteral(c); |
| 1413 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { | 1475 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| 1414 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1476 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1415 | try builtin_node.params.push(init_node); | 1477 | builtin_node.params()[0] = init_node; |
| 1416 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1478 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1417 | init_node = &builtin_node.base; | 1479 | init_node = &builtin_node.base; |
| 1418 | } | 1480 | } |
| 1419 | node.init_node = init_node; | 1481 | node.init_node = init_node; |
| 1420 | node.semicolon_token = try appendToken(c, .Semicolon, ";"); | 1482 | node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 1421 | try block_scope.block_node.statements.push(&node.base); | 1483 | try block_scope.statements.append(&node.base); |
| 1422 | }, | 1484 | }, |
| 1423 | .Typedef => { | 1485 | .Typedef => { |
| 1424 | const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); | 1486 | const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); |
| ... | @@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) | ... | @@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) |
| 1437 | }); | 1499 | }); |
| 1438 | } else { | 1500 | } else { |
| 1439 | const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation; | 1501 | const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation; |
| 1440 | try block_scope.block_node.statements.push(&node.base); | 1502 | try block_scope.statements.append(&node.base); |
| 1441 | } | 1503 | } |
| 1442 | }, | 1504 | }, |
| 1443 | else => |kind| return revertAndWarn( | 1505 | else => |kind| return revertAndWarn( |
| ... | @@ -1499,8 +1561,8 @@ fn transImplicitCastExpr( | ... | @@ -1499,8 +1561,8 @@ fn transImplicitCastExpr( |
| 1499 | }, | 1561 | }, |
| 1500 | .PointerToBoolean => { | 1562 | .PointerToBoolean => { |
| 1501 | // @ptrToInt(val) != 0 | 1563 | // @ptrToInt(val) != 0 |
| 1502 | const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); | 1564 | const ptr_to_int = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 1503 | try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value)); | 1565 | ptr_to_int.params()[0] = try transExpr(rp, scope, sub_expr, .used, .r_value); |
| 1504 | ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1566 | ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1505 | | 1567 | |
| 1506 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1568 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| ... | @@ -1724,13 +1786,11 @@ fn transIntegerLiteral( | ... | @@ -1724,13 +1786,11 @@ fn transIntegerLiteral( |
| 1724 | | 1786 | |
| 1725 | // @as(T, x) | 1787 | // @as(T, x) |
| 1726 | const expr_base = @ptrCast(*const ZigClangExpr, expr); | 1788 | const expr_base = @ptrCast(*const ZigClangExpr, expr); |
| 1727 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 1789 | const as_node = try rp.c.createBuiltinCall("@as", 2); |
| 1728 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); | 1790 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); |
| 1729 | try as_node.params.push(ty_node); | 1791 | as_node.params()[0] = ty_node; |
| 1730 | _ = try appendToken(rp.c, .Comma, ","); | 1792 | _ = try appendToken(rp.c, .Comma, ","); |
| 1731 | | 1793 | as_node.params()[1] = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); |
| 1732 | const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); | | |
| 1733 | try as_node.params.push(int_lit_node); | | |
| 1734 | | 1794 | |
| 1735 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1795 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1736 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); | 1796 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); |
| ... | @@ -1840,35 +1900,35 @@ fn transCCast( | ... | @@ -1840,35 +1900,35 @@ fn transCCast( |
| 1840 | // 2. Bit-cast to correct signed-ness | 1900 | // 2. Bit-cast to correct signed-ness |
| 1841 | | 1901 | |
| 1842 | // @bitCast(dest_type, intermediate_value) | 1902 | // @bitCast(dest_type, intermediate_value) |
| 1843 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); | 1903 | const cast_node = try rp.c.createBuiltinCall("@bitCast", 2); |
| 1844 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | 1904 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1845 | _ = try appendToken(rp.c, .Comma, ","); | 1905 | _ = try appendToken(rp.c, .Comma, ","); |
| 1846 | | 1906 | |
| 1847 | switch (cIntTypeCmp(dst_type, src_type)) { | 1907 | switch (cIntTypeCmp(dst_type, src_type)) { |
| 1848 | .lt => { | 1908 | .lt => { |
| 1849 | // @truncate(SameSignSmallerInt, src_type) | 1909 | // @truncate(SameSignSmallerInt, src_type) |
| 1850 | const trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@truncate"); | 1910 | const trunc_node = try rp.c.createBuiltinCall("@truncate", 2); |
| 1851 | const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type)); | 1911 | const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type)); |
| 1852 | try trunc_node.params.push(ty_node); | 1912 | trunc_node.params()[0] = ty_node; |
| 1853 | _ = try appendToken(rp.c, .Comma, ","); | 1913 | _ = try appendToken(rp.c, .Comma, ","); |
| 1854 | try trunc_node.params.push(expr); | 1914 | trunc_node.params()[1] = expr; |
| 1855 | trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1915 | trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1856 | | 1916 | |
| 1857 | try cast_node.params.push(&trunc_node.base); | 1917 | cast_node.params()[1] = &trunc_node.base; |
| 1858 | }, | 1918 | }, |
| 1859 | .gt => { | 1919 | .gt => { |
| 1860 | // @as(SameSignBiggerInt, src_type) | 1920 | // @as(SameSignBiggerInt, src_type) |
| 1861 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 1921 | const as_node = try rp.c.createBuiltinCall("@as", 2); |
| 1862 | const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type)); | 1922 | const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type)); |
| 1863 | try as_node.params.push(ty_node); | 1923 | as_node.params()[0] = ty_node; |
| 1864 | _ = try appendToken(rp.c, .Comma, ","); | 1924 | _ = try appendToken(rp.c, .Comma, ","); |
| 1865 | try as_node.params.push(expr); | 1925 | as_node.params()[1] = expr; |
| 1866 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1926 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1867 | | 1927 | |
| 1868 | try cast_node.params.push(&as_node.base); | 1928 | cast_node.params()[1] = &as_node.base; |
| 1869 | }, | 1929 | }, |
| 1870 | .eq => { | 1930 | .eq => { |
| 1871 | try cast_node.params.push(expr); | 1931 | cast_node.params()[1] = expr; |
| 1872 | }, | 1932 | }, |
| 1873 | } | 1933 | } |
| 1874 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1934 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -1876,46 +1936,46 @@ fn transCCast( | ... | @@ -1876,46 +1936,46 @@ fn transCCast( |
| 1876 | } | 1936 | } |
| 1877 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { | 1937 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 1878 | // @intCast(dest_type, @ptrToInt(val)) | 1938 | // @intCast(dest_type, @ptrToInt(val)) |
| 1879 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 1939 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1880 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | 1940 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1881 | _ = try appendToken(rp.c, .Comma, ","); | 1941 | _ = try appendToken(rp.c, .Comma, ","); |
| 1882 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); | 1942 | const builtin_node = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 1883 | try builtin_node.params.push(expr); | 1943 | builtin_node.params()[0] = expr; |
| 1884 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1944 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1885 | try cast_node.params.push(&builtin_node.base); | 1945 | cast_node.params()[1] = &builtin_node.base; |
| 1886 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1946 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1887 | return &cast_node.base; | 1947 | return &cast_node.base; |
| 1888 | } | 1948 | } |
| 1889 | if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { | 1949 | if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| 1890 | // @intToPtr(dest_type, val) | 1950 | // @intToPtr(dest_type, val) |
| 1891 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); | 1951 | const builtin_node = try rp.c.createBuiltinCall("@intToPtr", 2); |
| 1892 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1952 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1893 | _ = try appendToken(rp.c, .Comma, ","); | 1953 | _ = try appendToken(rp.c, .Comma, ","); |
| 1894 | try builtin_node.params.push(expr); | 1954 | builtin_node.params()[1] = expr; |
| 1895 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1955 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1896 | return &builtin_node.base; | 1956 | return &builtin_node.base; |
| 1897 | } | 1957 | } |
| 1898 | if (cIsFloating(src_type) and cIsFloating(dst_type)) { | 1958 | if (cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1899 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast"); | 1959 | const builtin_node = try rp.c.createBuiltinCall("@floatCast", 2); |
| 1900 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1960 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1901 | _ = try appendToken(rp.c, .Comma, ","); | 1961 | _ = try appendToken(rp.c, .Comma, ","); |
| 1902 | try builtin_node.params.push(expr); | 1962 | builtin_node.params()[1] = expr; |
| 1903 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1963 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1904 | return &builtin_node.base; | 1964 | return &builtin_node.base; |
| 1905 | } | 1965 | } |
| 1906 | if (cIsFloating(src_type) and !cIsFloating(dst_type)) { | 1966 | if (cIsFloating(src_type) and !cIsFloating(dst_type)) { |
| 1907 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt"); | 1967 | const builtin_node = try rp.c.createBuiltinCall("@floatToInt", 2); |
| 1908 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1968 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1909 | _ = try appendToken(rp.c, .Comma, ","); | 1969 | _ = try appendToken(rp.c, .Comma, ","); |
| 1910 | try builtin_node.params.push(expr); | 1970 | builtin_node.params()[1] = expr; |
| 1911 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1971 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1912 | return &builtin_node.base; | 1972 | return &builtin_node.base; |
| 1913 | } | 1973 | } |
| 1914 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { | 1974 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1915 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat"); | 1975 | const builtin_node = try rp.c.createBuiltinCall("@intToFloat", 2); |
| 1916 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 1976 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1917 | _ = try appendToken(rp.c, .Comma, ","); | 1977 | _ = try appendToken(rp.c, .Comma, ","); |
| 1918 | try builtin_node.params.push(expr); | 1978 | builtin_node.params()[1] = expr; |
| 1919 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1979 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1920 | return &builtin_node.base; | 1980 | return &builtin_node.base; |
| 1921 | } | 1981 | } |
| ... | @@ -1923,54 +1983,54 @@ fn transCCast( | ... | @@ -1923,54 +1983,54 @@ fn transCCast( |
| 1923 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) | 1983 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) |
| 1924 | { | 1984 | { |
| 1925 | // @boolToInt returns either a comptime_int or a u1 | 1985 | // @boolToInt returns either a comptime_int or a u1 |
| 1926 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1986 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1927 | try builtin_node.params.push(expr); | 1987 | builtin_node.params()[0] = expr; |
| 1928 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1988 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1929 | | 1989 | |
| 1930 | const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 1990 | const inner_cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1931 | try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1")); | 1991 | inner_cast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "u1"); |
| 1932 | _ = try appendToken(rp.c, .Comma, ","); | 1992 | _ = try appendToken(rp.c, .Comma, ","); |
| 1933 | try inner_cast_node.params.push(&builtin_node.base); | 1993 | inner_cast_node.params()[1] = &builtin_node.base; |
| 1934 | inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1994 | inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1935 | | 1995 | |
| 1936 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 1996 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1937 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | 1997 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1938 | _ = try appendToken(rp.c, .Comma, ","); | 1998 | _ = try appendToken(rp.c, .Comma, ","); |
| 1939 | | 1999 | |
| 1940 | if (cIsSignedInteger(dst_type)) { | 2000 | if (cIsSignedInteger(dst_type)) { |
| 1941 | const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); | 2001 | const bitcast_node = try rp.c.createBuiltinCall("@bitCast", 2); |
| 1942 | try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1")); | 2002 | bitcast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "i1"); |
| 1943 | _ = try appendToken(rp.c, .Comma, ","); | 2003 | _ = try appendToken(rp.c, .Comma, ","); |
| 1944 | try bitcast_node.params.push(&inner_cast_node.base); | 2004 | bitcast_node.params()[1] = &inner_cast_node.base; |
| 1945 | bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2005 | bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1946 | try cast_node.params.push(&bitcast_node.base); | 2006 | cast_node.params()[1] = &bitcast_node.base; |
| 1947 | } else { | 2007 | } else { |
| 1948 | try cast_node.params.push(&inner_cast_node.base); | 2008 | cast_node.params()[1] = &inner_cast_node.base; |
| 1949 | } | 2009 | } |
| 1950 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2010 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1951 | | 2011 | |
| 1952 | return &cast_node.base; | 2012 | return &cast_node.base; |
| 1953 | } | 2013 | } |
| 1954 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { | 2014 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { |
| 1955 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); | 2015 | const builtin_node = try rp.c.createBuiltinCall("@intToEnum", 2); |
| 1956 | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); | 2016 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1957 | _ = try appendToken(rp.c, .Comma, ","); | 2017 | _ = try appendToken(rp.c, .Comma, ","); |
| 1958 | try builtin_node.params.push(expr); | 2018 | builtin_node.params()[1] = expr; |
| 1959 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2019 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1960 | return &builtin_node.base; | 2020 | return &builtin_node.base; |
| 1961 | } | 2021 | } |
| 1962 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and | 2022 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and |
| 1963 | ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum) | 2023 | ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum) |
| 1964 | { | 2024 | { |
| 1965 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); | 2025 | const builtin_node = try rp.c.createBuiltinCall("@enumToInt", 1); |
| 1966 | try builtin_node.params.push(expr); | 2026 | builtin_node.params()[0] = expr; |
| 1967 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2027 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1968 | return &builtin_node.base; | 2028 | return &builtin_node.base; |
| 1969 | } | 2029 | } |
| 1970 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 2030 | const cast_node = try rp.c.createBuiltinCall("@as", 2); |
| 1971 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | 2031 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1972 | _ = try appendToken(rp.c, .Comma, ","); | 2032 | _ = try appendToken(rp.c, .Comma, ","); |
| 1973 | try cast_node.params.push(expr); | 2033 | cast_node.params()[1] = expr; |
| 1974 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2034 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1975 | return &cast_node.base; | 2035 | return &cast_node.base; |
| 1976 | } | 2036 | } |
| ... | @@ -2077,12 +2137,13 @@ fn transInitListExprRecord( | ... | @@ -2077,12 +2137,13 @@ fn transInitListExprRecord( |
| 2077 | | 2137 | |
| 2078 | _ = try appendToken(c, .LBrace, "{"); | 2138 | _ = try appendToken(c, .LBrace, "{"); |
| 2079 | | 2139 | |
| 2080 | const node = try rp.c.arena.create(ast.Node.StructInitializer); | 2140 | const node = try ast.Node.StructInitializer.alloc(rp.c.arena, field_inits.items.len); |
| 2081 | node.* = .{ | 2141 | node.* = .{ |
| 2082 | .lhs = ty, | 2142 | .lhs = ty, |
| 2083 | .rtoken = try appendToken(rp.c, .RBrace, "}"), | 2143 | .rtoken = try appendToken(rp.c, .RBrace, "}"), |
| 2084 | .list = try rp.c.arena.dupe(*ast.Node, field_inits.items), | 2144 | .list_len = field_inits.items.len, |
| 2085 | }; | 2145 | }; |
| | 2146 | mem.copy(*ast.Node, node.list(), field_inits.items); |
| 2086 | return &node.base; | 2147 | return &node.base; |
| 2087 | } | 2148 | } |
| 2088 | | 2149 | |
| ... | @@ -2292,11 +2353,15 @@ fn transIfStmt( | ... | @@ -2292,11 +2353,15 @@ fn transIfStmt( |
| 2292 | // if (c) t else e | 2353 | // if (c) t else e |
| 2293 | const if_node = try transCreateNodeIf(rp.c); | 2354 | const if_node = try transCreateNodeIf(rp.c); |
| 2294 | | 2355 | |
| 2295 | var cond_scope = Scope{ | 2356 | var cond_scope = Scope.Condition{ |
| 2296 | .parent = scope, | 2357 | .base = .{ |
| 2297 | .id = .Condition, | 2358 | .parent = scope, |
| | 2359 | .id = .Condition, |
| | 2360 | }, |
| 2298 | }; | 2361 | }; |
| 2299 | if_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false); | 2362 | defer cond_scope.deinit(); |
| | 2363 | const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)); |
| | 2364 | if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false); |
| 2300 | _ = try appendToken(rp.c, .RParen, ")"); | 2365 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2301 | | 2366 | |
| 2302 | if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value); | 2367 | if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value); |
| ... | @@ -2316,11 +2381,15 @@ fn transWhileLoop( | ... | @@ -2316,11 +2381,15 @@ fn transWhileLoop( |
| 2316 | ) TransError!*ast.Node { | 2381 | ) TransError!*ast.Node { |
| 2317 | const while_node = try transCreateNodeWhile(rp.c); | 2382 | const while_node = try transCreateNodeWhile(rp.c); |
| 2318 | | 2383 | |
| 2319 | var cond_scope = Scope{ | 2384 | var cond_scope = Scope.Condition{ |
| 2320 | .parent = scope, | 2385 | .base = .{ |
| 2321 | .id = .Condition, | 2386 | .parent = scope, |
| | 2387 | .id = .Condition, |
| | 2388 | }, |
| 2322 | }; | 2389 | }; |
| 2323 | while_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)), .used, .r_value, false); | 2390 | defer cond_scope.deinit(); |
| | 2391 | const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)); |
| | 2392 | while_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false); |
| 2324 | _ = try appendToken(rp.c, .RParen, ")"); | 2393 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2325 | | 2394 | |
| 2326 | var loop_scope = Scope{ | 2395 | var loop_scope = Scope{ |
| ... | @@ -2349,12 +2418,15 @@ fn transDoWhileLoop( | ... | @@ -2349,12 +2418,15 @@ fn transDoWhileLoop( |
| 2349 | | 2418 | |
| 2350 | // if (!cond) break; | 2419 | // if (!cond) break; |
| 2351 | const if_node = try transCreateNodeIf(rp.c); | 2420 | const if_node = try transCreateNodeIf(rp.c); |
| 2352 | var cond_scope = Scope{ | 2421 | var cond_scope = Scope.Condition{ |
| 2353 | .parent = scope, | 2422 | .base = .{ |
| 2354 | .id = .Condition, | 2423 | .parent = scope, |
| | 2424 | .id = .Condition, |
| | 2425 | }, |
| 2355 | }; | 2426 | }; |
| | 2427 | defer cond_scope.deinit(); |
| 2356 | const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); | 2428 | const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); |
| 2357 | prefix_op.rhs = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true); | 2429 | prefix_op.rhs = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true); |
| 2358 | _ = try appendToken(rp.c, .RParen, ")"); | 2430 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2359 | if_node.condition = &prefix_op.base; | 2431 | if_node.condition = &prefix_op.base; |
| 2360 | if_node.body = &(try transCreateNodeBreak(rp.c, null)).base; | 2432 | if_node.body = &(try transCreateNodeBreak(rp.c, null)).base; |
| ... | @@ -2404,24 +2476,26 @@ fn transForLoop( | ... | @@ -2404,24 +2476,26 @@ fn transForLoop( |
| 2404 | .id = .Loop, | 2476 | .id = .Loop, |
| 2405 | }; | 2477 | }; |
| 2406 | | 2478 | |
| 2407 | var block_scope: ?*Scope.Block = null; | 2479 | var block_scope: ?Scope.Block = null; |
| | 2480 | defer if (block_scope) |*bs| bs.deinit(); |
| | 2481 | |
| 2408 | if (ZigClangForStmt_getInit(stmt)) |init| { | 2482 | if (ZigClangForStmt_getInit(stmt)) |init| { |
| 2409 | block_scope = try Scope.Block.init(rp.c, scope, null); | 2483 | block_scope = try Scope.Block.init(rp.c, scope, null); |
| 2410 | const block = try transCreateNodeBlock(rp.c, null); | | |
| 2411 | block_scope.?.setBlockNode(block); | | |
| 2412 | loop_scope.parent = &block_scope.?.base; | 2484 | loop_scope.parent = &block_scope.?.base; |
| 2413 | const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); | 2485 | const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); |
| 2414 | if (result != &block.base) | 2486 | try block_scope.statements.push(result); |
| 2415 | try block.statements.push(result); | | |
| 2416 | } | 2487 | } |
| 2417 | var cond_scope = Scope{ | 2488 | var cond_scope = Scope.Condition{ |
| 2418 | .parent = scope, | 2489 | .base = .{ |
| 2419 | .id = .Condition, | 2490 | .parent = scope, |
| | 2491 | .id = .Condition, |
| | 2492 | }, |
| 2420 | }; | 2493 | }; |
| | 2494 | defer cond_scope.deinit(); |
| 2421 | | 2495 | |
| 2422 | const while_node = try transCreateNodeWhile(rp.c); | 2496 | const while_node = try transCreateNodeWhile(rp.c); |
| 2423 | while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond| | 2497 | while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond| |
| 2424 | try transBoolExpr(rp, &cond_scope, cond, .used, .r_value, false) | 2498 | try transBoolExpr(rp, &cond_scope.base, cond, .used, .r_value, false) |
| 2425 | else | 2499 | else |
| 2426 | try transCreateNodeBoolLiteral(rp.c, true); | 2500 | try transCreateNodeBoolLiteral(rp.c, true); |
| 2427 | _ = try appendToken(rp.c, .RParen, ")"); | 2501 | _ = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -2429,62 +2503,90 @@ fn transForLoop( | ... | @@ -2429,62 +2503,90 @@ fn transForLoop( |
| 2429 | if (ZigClangForStmt_getInc(stmt)) |incr| { | 2503 | if (ZigClangForStmt_getInc(stmt)) |incr| { |
| 2430 | _ = try appendToken(rp.c, .Colon, ":"); | 2504 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2431 | _ = try appendToken(rp.c, .LParen, "("); | 2505 | _ = try appendToken(rp.c, .LParen, "("); |
| 2432 | while_node.continue_expr = try transExpr(rp, &cond_scope, incr, .unused, .r_value); | 2506 | while_node.continue_expr = try transExpr(rp, &cond_scope.base, incr, .unused, .r_value); |
| 2433 | _ = try appendToken(rp.c, .RParen, ")"); | 2507 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2434 | } | 2508 | } |
| 2435 | | 2509 | |
| 2436 | while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value); | 2510 | while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value); |
| 2437 | if (block_scope != null) { | 2511 | if (block_scope) |*bs| { |
| 2438 | try block_scope.?.block_node.statements.push(&while_node.base); | 2512 | try bs.statements.push(&while_node.base); |
| 2439 | block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 2513 | const node = bs.complete(rp.c); |
| 2440 | return &block_scope.?.block_node.base; | 2514 | return &node.base; |
| 2441 | } else { | 2515 | } else { |
| 2442 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2516 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2443 | return &while_node.base; | 2517 | return &while_node.base; |
| 2444 | } | 2518 | } |
| 2445 | } | 2519 | } |
| 2446 | | 2520 | |
| | 2521 | fn getSwitchCaseCount(stmt: *const ZigClangSwitchStmt) usize { |
| | 2522 | const stmt = ZigClangSwitchStmt_getBody(stmt); |
| | 2523 | const comp = ZigClangStmtExpr_getSubStmt(stmt); |
| | 2524 | return ZigClangCompoundStmt_body_end(comp) - ZigClangCompoundStmt_body_begin(comp); |
| | 2525 | } |
| | 2526 | |
| 2447 | fn transSwitch( | 2527 | fn transSwitch( |
| 2448 | rp: RestorePoint, | 2528 | rp: RestorePoint, |
| 2449 | scope: *Scope, | 2529 | scope: *Scope, |
| 2450 | stmt: *const ZigClangSwitchStmt, | 2530 | stmt: *const ZigClangSwitchStmt, |
| 2451 | ) TransError!*ast.Node { | 2531 | ) TransError!*ast.Node { |
| 2452 | const switch_node = try transCreateNodeSwitch(rp.c); | 2532 | const switch_tok = try appendToken(rp.c, .Keyword_switch, "switch"); |
| | 2533 | _ = try appendToken(rp.c, .LParen, "("); |
| | 2534 | |
| | 2535 | const cases_len = getSwitchCaseCount(ZigClangSwitchStmt_getBody(stmt)); |
| | 2536 | |
| | 2537 | var cond_scope = Scope.Condition{ |
| | 2538 | .base = .{ |
| | 2539 | .parent = scope, |
| | 2540 | .id = .Condition, |
| | 2541 | }, |
| | 2542 | }; |
| | 2543 | defer cond_scope.deinit(); |
| | 2544 | const switch_expr = try transExpr(rp, &cond_scope.base, ZigClangSwitchStmt_getCond(stmt), .used, .r_value); |
| | 2545 | _ = try appendToken(rp.c, .RParen, ")"); |
| | 2546 | _ = try appendToken(rp.c, .LBrace, "{"); |
| | 2547 | // reserve +1 case in case there is no default case |
| | 2548 | const switch_node = try ast.Node.Switch.alloc(rp.c.arena, cases_len + 1); |
| | 2549 | switch_node.* = .{ |
| | 2550 | .switch_token = switch_tok, |
| | 2551 | .expr = switch_expr, |
| | 2552 | .cases_len = cases_len + 1, |
| | 2553 | .rbrace = try appendToken(rp.c, .RBrace, "}"), |
| | 2554 | }; |
| | 2555 | |
| 2453 | var switch_scope = Scope.Switch{ | 2556 | var switch_scope = Scope.Switch{ |
| 2454 | .base = .{ | 2557 | .base = .{ |
| 2455 | .id = .Switch, | 2558 | .id = .Switch, |
| 2456 | .parent = scope, | 2559 | .parent = scope, |
| 2457 | }, | 2560 | }, |
| 2458 | .cases = &switch_node.cases, | 2561 | .cases = switch_node.cases(), |
| | 2562 | .case_index = 0, |
| 2459 | .pending_block = undefined, | 2563 | .pending_block = undefined, |
| 2460 | }; | 2564 | }; |
| 2461 | | 2565 | |
| 2462 | var cond_scope = Scope{ | | |
| 2463 | .parent = scope, | | |
| 2464 | .id = .Condition, | | |
| 2465 | }; | | |
| 2466 | switch_node.expr = try transExpr(rp, &cond_scope, ZigClangSwitchStmt_getCond(stmt), .used, .r_value); | | |
| 2467 | _ = try appendToken(rp.c, .RParen, ")"); | | |
| 2468 | _ = try appendToken(rp.c, .LBrace, "{"); | | |
| 2469 | switch_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | | |
| 2470 | | | |
| 2471 | const block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null); | | |
| 2472 | // tmp block that all statements will go before being picked up by a case or default | 2566 | // tmp block that all statements will go before being picked up by a case or default |
| 2473 | const block = try transCreateNodeBlock(rp.c, null); | 2567 | var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null); |
| 2474 | block_scope.setBlockNode(block); | 2568 | defer block_scope.deinit(); |
| 2475 | | 2569 | |
| 2476 | const switch_block = try transCreateNodeBlock(rp.c, null); | 2570 | // Note that we do not defer a deinit here; the switch_scope.pending_block field |
| 2477 | try switch_block.statements.push(&switch_node.base); | 2571 | // has its own memory management. This resource is freed inside `transCase` and |
| 2478 | switch_scope.pending_block = switch_block; | 2572 | // then the final pending_block is freed at the bottom of this function with |
| | 2573 | // pending_block.deinit(). |
| | 2574 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); |
| | 2575 | try switch_scope.pending_block.statements.append(&switch_node.base); |
| 2479 | | 2576 | |
| 2480 | const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); | 2577 | _ = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); |
| 2481 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2578 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2482 | | 2579 | |
| 2483 | // take all pending statements | 2580 | // take all pending statements |
| 2484 | var it = last.cast(ast.Node.Block).?.statements.iterator(0); | 2581 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2485 | while (it.next()) |n| { | 2582 | // TODO delete the following commented out code |
| 2486 | try switch_scope.pending_block.statements.push(n.*); | 2583 | //const last_block_stmts = last.cast(ast.Node.Block).?.statements(); |
| 2487 | } | 2584 | //switch_scope.pending_block.statements.ensureCapacity( |
| | 2585 | // switch_scope.pending_block.statements.items.len + last_block_stmts.len, |
| | 2586 | //); |
| | 2587 | //for (last_block_stmts) |n| { |
| | 2588 | // switch_scope.pending_block.statements.appendAssumeCapacity(n); |
| | 2589 | //} |
| 2488 | | 2590 | |
| 2489 | switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch"); | 2591 | switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch"); |
| 2490 | _ = try appendToken(rp.c, .Colon, ":"); | 2592 | _ = try appendToken(rp.c, .Colon, ":"); |
| ... | @@ -2492,10 +2594,16 @@ fn transSwitch( | ... | @@ -2492,10 +2594,16 @@ fn transSwitch( |
| 2492 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); | 2594 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2493 | else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base; | 2595 | else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base; |
| 2494 | _ = try appendToken(rp.c, .Comma, ","); | 2596 | _ = try appendToken(rp.c, .Comma, ","); |
| 2495 | try switch_node.cases.push(&else_prong.base); | 2597 | switch_node.cases[switch_node.case_index] = &else_prong.base; |
| | 2598 | switch_node.case_index += 1; |
| 2496 | } | 2599 | } |
| 2497 | switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}"); | 2600 | // We overallocated in case there was no default, so now we correct |
| 2498 | return &switch_scope.pending_block.base; | 2601 | // the number of cases in the AST node. |
| | 2602 | switch_node.cases_len = switch_scope.case_index; |
| | 2603 | |
| | 2604 | const result_node = try switch_scope.pending_block.complete(rp.c); |
| | 2605 | switch_scope.pending_block.deinit(); |
| | 2606 | return &result_node.base; |
| 2499 | } | 2607 | } |
| 2500 | | 2608 | |
| 2501 | fn transCase( | 2609 | fn transCase( |
| ... | @@ -2527,22 +2635,21 @@ fn transCase( | ... | @@ -2527,22 +2635,21 @@ fn transCase( |
| 2527 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); | 2635 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); |
| 2528 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; | 2636 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; |
| 2529 | _ = try appendToken(rp.c, .Comma, ","); | 2637 | _ = try appendToken(rp.c, .Comma, ","); |
| 2530 | try switch_scope.cases.push(&switch_prong.base); | 2638 | switch_scope.cases[switch_scope.case_index] = &switch_prong.base; |
| | 2639 | switch_scope.case_index += 1; |
| 2531 | | 2640 | |
| 2532 | const block = try transCreateNodeBlock(rp.c, null); | | |
| 2533 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); | 2641 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); |
| 2534 | _ = try appendToken(rp.c, .Colon, ":"); | 2642 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2535 | switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}"); | | |
| 2536 | try block.statements.push(&switch_scope.pending_block.base); | | |
| 2537 | | 2643 | |
| 2538 | // take all pending statements | 2644 | // take all pending statements |
| 2539 | var it = block_scope.block_node.statements.iterator(0); | 2645 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2540 | while (it.next()) |n| { | 2646 | block_scope.statements.shrink(0); |
| 2541 | try switch_scope.pending_block.statements.push(n.*); | 2647 | |
| 2542 | } | 2648 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 2543 | block_scope.block_node.statements.shrink(0); | 2649 | switch_scope.pending_block.deinit(); |
| | 2650 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); |
| 2544 | | 2651 | |
| 2545 | switch_scope.pending_block = block; | 2652 | try switch_scope.pending_block.statements.append(&pending_node.base); |
| 2546 | | 2653 | |
| 2547 | return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value); | 2654 | return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value); |
| 2548 | } | 2655 | } |
| ... | @@ -2561,22 +2668,21 @@ fn transDefault( | ... | @@ -2561,22 +2668,21 @@ fn transDefault( |
| 2561 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); | 2668 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2562 | else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; | 2669 | else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; |
| 2563 | _ = try appendToken(rp.c, .Comma, ","); | 2670 | _ = try appendToken(rp.c, .Comma, ","); |
| 2564 | try switch_scope.cases.push(&else_prong.base); | 2671 | switch_scope.cases[switch_scope.case_index] = &else_prong.base; |
| | 2672 | switch_scope.case_index += 1; |
| 2565 | | 2673 | |
| 2566 | const block = try transCreateNodeBlock(rp.c, null); | | |
| 2567 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); | 2674 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); |
| 2568 | _ = try appendToken(rp.c, .Colon, ":"); | 2675 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2569 | switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}"); | | |
| 2570 | try block.statements.push(&switch_scope.pending_block.base); | | |
| 2571 | | 2676 | |
| 2572 | // take all pending statements | 2677 | // take all pending statements |
| 2573 | var it = block_scope.block_node.statements.iterator(0); | 2678 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2574 | while (it.next()) |n| { | 2679 | block_scope.statements.shrink(0); |
| 2575 | try switch_scope.pending_block.statements.push(n.*); | 2680 | |
| 2576 | } | 2681 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 2577 | block_scope.block_node.statements.shrink(0); | 2682 | switch_scope.pending_block.deinit(); |
| | 2683 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); |
| | 2684 | try switch_scope.pending_block.statements.append(&pending_node.base); |
| 2578 | | 2685 | |
| 2579 | switch_scope.pending_block = block; | | |
| 2580 | return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value); | 2686 | return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value); |
| 2581 | } | 2687 | } |
| 2582 | | 2688 | |
| ... | @@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr, | ... | @@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr, |
| 2591 | // See comment in `transIntegerLiteral` for why this code is here. | 2697 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2592 | // @as(T, x) | 2698 | // @as(T, x) |
| 2593 | const expr_base = @ptrCast(*const ZigClangExpr, expr); | 2699 | const expr_base = @ptrCast(*const ZigClangExpr, expr); |
| 2594 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 2700 | const as_node = try rp.c.createBuiltinCall("@as", 2); |
| 2595 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); | 2701 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); |
| 2596 | try as_node.params.push(ty_node); | 2702 | as_node.params()[0] = ty_node; |
| 2597 | _ = try appendToken(rp.c, .Comma, ","); | 2703 | _ = try appendToken(rp.c, .Comma, ","); |
| 2598 | | 2704 | |
| 2599 | const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val)); | 2705 | const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val)); |
| 2600 | try as_node.params.push(int_lit_node); | 2706 | as_node.params()[1] = int_lit_node; |
| 2601 | | 2707 | |
| 2602 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2708 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2603 | | 2709 | |
| ... | @@ -2653,12 +2759,11 @@ fn transCharLiteral( | ... | @@ -2653,12 +2759,11 @@ fn transCharLiteral( |
| 2653 | // See comment in `transIntegerLiteral` for why this code is here. | 2759 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2654 | // @as(T, x) | 2760 | // @as(T, x) |
| 2655 | const expr_base = @ptrCast(*const ZigClangExpr, stmt); | 2761 | const expr_base = @ptrCast(*const ZigClangExpr, stmt); |
| 2656 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | 2762 | const as_node = try rp.c.createBuiltinCall("@as", 2); |
| 2657 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); | 2763 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); |
| 2658 | try as_node.params.push(ty_node); | 2764 | as_node.params()[0] = ty_node; |
| 2659 | _ = try appendToken(rp.c, .Comma, ","); | 2765 | _ = try appendToken(rp.c, .Comma, ","); |
| 2660 | | 2766 | as_node.params()[1] = int_lit_node; |
| 2661 | try as_node.params.push(int_lit_node); | | |
| 2662 | | 2767 | |
| 2663 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2768 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2664 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); | 2769 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); |
| ... | @@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, | ... | @@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, |
| 2671 | } | 2776 | } |
| 2672 | const lparen = try appendToken(rp.c, .LParen, "("); | 2777 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 2673 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 2778 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2674 | const block = try transCreateNodeBlock(rp.c, "blk"); | 2779 | defer block_scope.deinit(); |
| 2675 | block_scope.setBlockNode(block); | | |
| 2676 | | 2780 | |
| 2677 | var it = ZigClangCompoundStmt_body_begin(comp); | 2781 | var it = ZigClangCompoundStmt_body_begin(comp); |
| 2678 | const end_it = ZigClangCompoundStmt_body_end(comp); | 2782 | const end_it = ZigClangCompoundStmt_body_end(comp); |
| 2679 | while (it != end_it - 1) : (it += 1) { | 2783 | while (it != end_it - 1) : (it += 1) { |
| 2680 | const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value); | 2784 | const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value); |
| 2681 | if (result != &block.base) | 2785 | try block_scope.statements.append(result); |
| 2682 | try block.statements.push(result); | | |
| 2683 | } | 2786 | } |
| 2684 | const break_node = try transCreateNodeBreak(rp.c, "blk"); | 2787 | const break_node = try transCreateNodeBreak(rp.c, "blk"); |
| 2685 | break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value); | 2788 | break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value); |
| 2686 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2789 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2687 | try block.statements.push(&break_node.base); | 2790 | try block_scope.statements.append(&break_node.base); |
| 2688 | block.rbrace = try appendToken(rp.c, .RBrace, "}"); | 2791 | const block_node = try block_scope.complete(rp.c); |
| 2689 | const rparen = try appendToken(rp.c, .RParen, ")"); | 2792 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 2690 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 2793 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 2691 | grouped_expr.* = .{ | 2794 | grouped_expr.* = .{ |
| 2692 | .lparen = lparen, | 2795 | .lparen = lparen, |
| 2693 | .expr = &block.base, | 2796 | .expr = &block_node.base, |
| 2694 | .rparen = rparen, | 2797 | .rparen = rparen, |
| 2695 | }; | 2798 | }; |
| 2696 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); | 2799 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| ... | @@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS | ... | @@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS |
| 2746 | const is_signed = cIsSignedInteger(qt); | 2849 | const is_signed = cIsSignedInteger(qt); |
| 2747 | | 2850 | |
| 2748 | if (is_longlong or is_signed) { | 2851 | if (is_longlong or is_signed) { |
| 2749 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 2852 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 2750 | // check if long long first so that signed long long doesn't just become unsigned long long | 2853 | // check if long long first so that signed long long doesn't just become unsigned long long |
| 2751 | var typeid_node = if (is_longlong) try transCreateNodeIdentifier(rp.c, "usize") else try transQualTypeIntWidthOf(rp.c, qt, false); | 2854 | var typeid_node = if (is_longlong) try transCreateNodeIdentifier(rp.c, "usize") else try transQualTypeIntWidthOf(rp.c, qt, false); |
| 2752 | try cast_node.params.push(typeid_node); | 2855 | cast_node.params()[0] = typeid_node; |
| 2753 | _ = try appendToken(rp.c, .Comma, ","); | 2856 | _ = try appendToken(rp.c, .Comma, ","); |
| 2754 | try cast_node.params.push(try transExpr(rp, scope, subscr_expr, .used, .r_value)); | 2857 | cast_node.params()[1] = try transExpr(rp, scope, subscr_expr, .used, .r_value); |
| 2755 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2858 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2756 | node.rtoken = try appendToken(rp.c, .RBrace, "]"); | 2859 | node.rtoken = try appendToken(rp.c, .RBrace, "]"); |
| 2757 | node.op.ArrayAccess = &cast_node.base; | 2860 | node.op.ArrayAccess = &cast_node.base; |
| ... | @@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, | ... | @@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2787 | break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr); | 2890 | break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr); |
| 2788 | } else | 2891 | } else |
| 2789 | raw_fn_expr; | 2892 | raw_fn_expr; |
| 2790 | const node = try transCreateNodeFnCall(rp.c, fn_expr); | | |
| 2791 | | 2893 | |
| 2792 | const num_args = ZigClangCallExpr_getNumArgs(stmt); | 2894 | const num_args = ZigClangCallExpr_getNumArgs(stmt); |
| | 2895 | const node = try c.createCall(fn_expr, num_args); |
| | 2896 | const call_params = node.params(); |
| | 2897 | |
| 2793 | const args = ZigClangCallExpr_getArgs(stmt); | 2898 | const args = ZigClangCallExpr_getArgs(stmt); |
| 2794 | var i: usize = 0; | 2899 | var i: usize = 0; |
| 2795 | while (i < num_args) : (i += 1) { | 2900 | while (i < num_args) : (i += 1) { |
| 2796 | if (i != 0) { | 2901 | if (i != 0) { |
| 2797 | _ = try appendToken(rp.c, .Comma, ","); | 2902 | _ = try appendToken(rp.c, .Comma, ","); |
| 2798 | } | 2903 | } |
| 2799 | const arg = try transExpr(rp, scope, args[i], .used, .r_value); | 2904 | call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value); |
| 2800 | try node.op.Call.params.push(arg); | | |
| 2801 | } | 2905 | } |
| 2802 | node.rtoken = try appendToken(rp.c, .RParen, ")"); | 2906 | node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 2803 | | 2907 | |
| ... | @@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr( | ... | @@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr( |
| 2856 | ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt), | 2960 | ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt), |
| 2857 | ); | 2961 | ); |
| 2858 | | 2962 | |
| 2859 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@sizeOf"); | 2963 | const builtin_node = try rp.c.createBuiltinCall("@sizeOf", 1); |
| 2860 | try builtin_node.params.push(type_node); | 2964 | builtin_node.params()[0] = type_node; |
| 2861 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 2965 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2862 | return maybeSuppressResult(rp, scope, result_used, &builtin_node.base); | 2966 | return maybeSuppressResult(rp, scope, result_used, &builtin_node.base); |
| 2863 | } | 2967 | } |
| ... | @@ -2966,8 +3070,8 @@ fn transCreatePreCrement( | ... | @@ -2966,8 +3070,8 @@ fn transCreatePreCrement( |
| 2966 | // zig: _ref.* += 1; | 3070 | // zig: _ref.* += 1; |
| 2967 | // zig: break :blk _ref.* | 3071 | // zig: break :blk _ref.* |
| 2968 | // zig: }) | 3072 | // zig: }) |
| 2969 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3073 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2970 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | 3074 | defer block_scope.deinit(); |
| 2971 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3075 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 2972 | | 3076 | |
| 2973 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); | 3077 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | @@ -2976,7 +3080,7 @@ fn transCreatePreCrement( | ... | @@ -2976,7 +3080,7 @@ fn transCreatePreCrement( |
| 2976 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); | 3080 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 2977 | node.init_node = &rhs_node.base; | 3081 | node.init_node = &rhs_node.base; |
| 2978 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3082 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 2979 | try block_scope.block_node.statements.push(&node.base); | 3083 | try block_scope.statements.append(&node.base); |
| 2980 | | 3084 | |
| 2981 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); | 3085 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 2982 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); | 3086 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | @@ -2985,18 +3089,18 @@ fn transCreatePreCrement( | ... | @@ -2985,18 +3089,18 @@ fn transCreatePreCrement( |
| 2985 | const one = try transCreateNodeInt(rp.c, 1); | 3089 | const one = try transCreateNodeInt(rp.c, 1); |
| 2986 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3090 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2987 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); | 3091 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); |
| 2988 | try block_scope.block_node.statements.push(assign); | 3092 | try block_scope.statements.append(assign); |
| 2989 | | 3093 | |
| 2990 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 3094 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 2991 | break_node.rhs = ref_node; | 3095 | break_node.rhs = ref_node; |
| 2992 | try block_scope.block_node.statements.push(&break_node.base); | 3096 | try block_scope.statements.push(&break_node.base); |
| 2993 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 3097 | const block_node = try block_scope.complete(rp.c); |
| 2994 | // semicolon must immediately follow rbrace because it is the last token in a block | 3098 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 2995 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3099 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2996 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 3100 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 2997 | grouped_expr.* = .{ | 3101 | grouped_expr.* = .{ |
| 2998 | .lparen = try appendToken(rp.c, .LParen, "("), | 3102 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 2999 | .expr = &block_scope.block_node.base, | 3103 | .expr = &block_node.base, |
| 3000 | .rparen = try appendToken(rp.c, .RParen, ")"), | 3104 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3001 | }; | 3105 | }; |
| 3002 | return &grouped_expr.base; | 3106 | return &grouped_expr.base; |
| ... | @@ -3032,8 +3136,8 @@ fn transCreatePostCrement( | ... | @@ -3032,8 +3136,8 @@ fn transCreatePostCrement( |
| 3032 | // zig: _ref.* += 1; | 3136 | // zig: _ref.* += 1; |
| 3033 | // zig: break :blk _tmp | 3137 | // zig: break :blk _tmp |
| 3034 | // zig: }) | 3138 | // zig: }) |
| 3035 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3139 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3036 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | 3140 | defer block_scope.deinit(); |
| 3037 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3141 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3038 | | 3142 | |
| 3039 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); | 3143 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | @@ -3042,7 +3146,7 @@ fn transCreatePostCrement( | ... | @@ -3042,7 +3146,7 @@ fn transCreatePostCrement( |
| 3042 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); | 3146 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 3043 | node.init_node = &rhs_node.base; | 3147 | node.init_node = &rhs_node.base; |
| 3044 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3148 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 3045 | try block_scope.block_node.statements.push(&node.base); | 3149 | try block_scope.statements.push(&node.base); |
| 3046 | | 3150 | |
| 3047 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); | 3151 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 3048 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); | 3152 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | @@ -3053,23 +3157,23 @@ fn transCreatePostCrement( | ... | @@ -3053,23 +3157,23 @@ fn transCreatePostCrement( |
| 3053 | tmp_node.eq_token = try appendToken(rp.c, .Equal, "="); | 3157 | tmp_node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3054 | tmp_node.init_node = ref_node; | 3158 | tmp_node.init_node = ref_node; |
| 3055 | tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3159 | tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 3056 | try block_scope.block_node.statements.push(&tmp_node.base); | 3160 | try block_scope.statements.push(&tmp_node.base); |
| 3057 | | 3161 | |
| 3058 | const token = try appendToken(rp.c, op_tok_id, bytes); | 3162 | const token = try appendToken(rp.c, op_tok_id, bytes); |
| 3059 | const one = try transCreateNodeInt(rp.c, 1); | 3163 | const one = try transCreateNodeInt(rp.c, 1); |
| 3060 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3164 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3061 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); | 3165 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); |
| 3062 | try block_scope.block_node.statements.push(assign); | 3166 | try block_scope.statements.push(assign); |
| 3063 | | 3167 | |
| 3064 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 3168 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3065 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); | 3169 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); |
| 3066 | try block_scope.block_node.statements.push(&break_node.base); | 3170 | try block_scope.statements.push(&break_node.base); |
| 3067 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3171 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3068 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 3172 | const block_node = try block_scope.complete(rp.c); |
| 3069 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 3173 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3070 | grouped_expr.* = .{ | 3174 | grouped_expr.* = .{ |
| 3071 | .lparen = try appendToken(rp.c, .LParen, "("), | 3175 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 3072 | .expr = &block_scope.block_node.base, | 3176 | .expr = &block_node.base, |
| 3073 | .rparen = try appendToken(rp.c, .RParen, ")"), | 3177 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3074 | }; | 3178 | }; |
| 3075 | return &grouped_expr.base; | 3179 | return &grouped_expr.base; |
| ... | @@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign( | ... | @@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign( |
| 3134 | const op_token = try appendToken(rp.c, .Equal, "="); | 3238 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 3135 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); | 3239 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); |
| 3136 | const builtin = if (is_mod) "@rem" else "@divTrunc"; | 3240 | const builtin = if (is_mod) "@rem" else "@divTrunc"; |
| 3137 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin); | 3241 | const builtin_node = try rp.c.createBuiltinCall(builtin, 2); |
| 3138 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); | 3242 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); |
| 3139 | try builtin_node.params.push(lhs_node); | 3243 | builtin_node.params()[0] = lhs_node; |
| 3140 | _ = try appendToken(rp.c, .Comma, ","); | 3244 | _ = try appendToken(rp.c, .Comma, ","); |
| 3141 | try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value)); | 3245 | builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value); |
| 3142 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3246 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3143 | op_node.* = .{ | 3247 | op_node.* = .{ |
| 3144 | .op_token = op_token, | 3248 | .op_token = op_token, |
| ... | @@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign( | ... | @@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign( |
| 3158 | try transExpr(rp, scope, rhs, .used, .r_value); | 3262 | try transExpr(rp, scope, rhs, .used, .r_value); |
| 3159 | | 3263 | |
| 3160 | if (is_shift) { | 3264 | if (is_shift) { |
| 3161 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 3265 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3162 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); | 3266 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); |
| 3163 | try cast_node.params.push(rhs_type); | 3267 | cast_node.params()[0] = rhs_type; |
| 3164 | _ = try appendToken(rp.c, .Comma, ","); | 3268 | _ = try appendToken(rp.c, .Comma, ","); |
| 3165 | try cast_node.params.push(rhs_node); | 3269 | cast_node.params()[1] = rhs_node; |
| 3166 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3270 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3167 | rhs_node = &cast_node.base; | 3271 | rhs_node = &cast_node.base; |
| 3168 | } | 3272 | } |
| ... | @@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign( | ... | @@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign( |
| 3177 | // zig: _ref.* = _ref.* + rhs; | 3281 | // zig: _ref.* = _ref.* + rhs; |
| 3178 | // zig: break :blk _ref.* | 3282 | // zig: break :blk _ref.* |
| 3179 | // zig: }) | 3283 | // zig: }) |
| 3180 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3284 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3181 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | 3285 | defer block_scope.deinit(); |
| 3182 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3286 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3183 | | 3287 | |
| 3184 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); | 3288 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | @@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign( | ... | @@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign( |
| 3187 | addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value); | 3291 | addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value); |
| 3188 | node.init_node = &addr_node.base; | 3292 | node.init_node = &addr_node.base; |
| 3189 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3293 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 3190 | try block_scope.block_node.statements.push(&node.base); | 3294 | try block_scope.statements.append(&node.base); |
| 3191 | | 3295 | |
| 3192 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); | 3296 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 3193 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); | 3297 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | @@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign( | ... | @@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign( |
| 3197 | const op_token = try appendToken(rp.c, .Equal, "="); | 3301 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 3198 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); | 3302 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); |
| 3199 | const builtin = if (is_mod) "@rem" else "@divTrunc"; | 3303 | const builtin = if (is_mod) "@rem" else "@divTrunc"; |
| 3200 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin); | 3304 | const builtin_node = try rp.c.createBuiltinCall(builtin, 2); |
| 3201 | try builtin_node.params.push(try transCreateNodePtrDeref(rp.c, lhs_node)); | 3305 | builtin_node.params()[0] = try transCreateNodePtrDeref(rp.c, lhs_node); |
| 3202 | _ = try appendToken(rp.c, .Comma, ","); | 3306 | _ = try appendToken(rp.c, .Comma, ","); |
| 3203 | try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value)); | 3307 | builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value); |
| 3204 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3308 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3205 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3309 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3206 | op_node.* = .{ | 3310 | op_node.* = .{ |
| ... | @@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign( | ... | @@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign( |
| 3210 | .rhs = &builtin_node.base, | 3314 | .rhs = &builtin_node.base, |
| 3211 | }; | 3315 | }; |
| 3212 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3316 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3213 | try block_scope.block_node.statements.push(&op_node.base); | 3317 | try block_scope.statements.append(&op_node.base); |
| 3214 | } else { | 3318 | } else { |
| 3215 | const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes); | 3319 | const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes); |
| 3216 | var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); | 3320 | var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); |
| 3217 | | 3321 | |
| 3218 | if (is_shift) { | 3322 | if (is_shift) { |
| 3219 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 3323 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3220 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); | 3324 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); |
| 3221 | try cast_node.params.push(rhs_type); | 3325 | cast_node.params()[0] = rhs_type; |
| 3222 | _ = try appendToken(rp.c, .Comma, ","); | 3326 | _ = try appendToken(rp.c, .Comma, ","); |
| 3223 | try cast_node.params.push(rhs_node); | 3327 | cast_node.params()[1] = rhs_node; |
| 3224 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3328 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3225 | rhs_node = &cast_node.base; | 3329 | rhs_node = &cast_node.base; |
| 3226 | } | 3330 | } |
| ... | @@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign( | ... | @@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign( |
| 3230 | | 3334 | |
| 3231 | const eq_token = try appendToken(rp.c, .Equal, "="); | 3335 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| 3232 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false); | 3336 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false); |
| 3233 | try block_scope.block_node.statements.push(assign); | 3337 | try block_scope.statements.append(assign); |
| 3234 | } | 3338 | } |
| 3235 | | 3339 | |
| 3236 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 3340 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3237 | break_node.rhs = ref_node; | 3341 | break_node.rhs = ref_node; |
| 3238 | try block_scope.block_node.statements.push(&break_node.base); | 3342 | try block_scope.statements.append(&break_node.base); |
| 3239 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 3343 | const block_node = try block_scope.complete(rp.c); |
| 3240 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 3344 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3241 | grouped_expr.* = .{ | 3345 | grouped_expr.* = .{ |
| 3242 | .lparen = try appendToken(rp.c, .LParen, "("), | 3346 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 3243 | .expr = &block_scope.block_node.base, | 3347 | .expr = &block_node.base, |
| 3244 | .rparen = try appendToken(rp.c, .RParen, ")"), | 3348 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3245 | }; | 3349 | }; |
| 3246 | return &grouped_expr.base; | 3350 | return &grouped_expr.base; |
| ... | @@ -3264,43 +3368,43 @@ fn transCPtrCast( | ... | @@ -3264,43 +3368,43 @@ fn transCPtrCast( |
| 3264 | !ZigClangQualType_isVolatileQualified(child_type))) | 3368 | !ZigClangQualType_isVolatileQualified(child_type))) |
| 3265 | { | 3369 | { |
| 3266 | // Casting away const or volatile requires us to use @intToPtr | 3370 | // Casting away const or volatile requires us to use @intToPtr |
| 3267 | const inttoptr_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); | 3371 | const inttoptr_node = try rp.c.createBuiltinCall("@intToPtr", 2); |
| 3268 | const dst_type_node = try transType(rp, ty, loc); | 3372 | const dst_type_node = try transType(rp, ty, loc); |
| 3269 | try inttoptr_node.params.push(dst_type_node); | 3373 | inttoptr_node.params()[0] = dst_type_node; |
| 3270 | _ = try appendToken(rp.c, .Comma, ","); | 3374 | _ = try appendToken(rp.c, .Comma, ","); |
| 3271 | | 3375 | |
| 3272 | const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); | 3376 | const ptrtoint_node = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 3273 | try ptrtoint_node.params.push(expr); | 3377 | ptrtoint_node.params()[0] = expr; |
| 3274 | ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3378 | ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3275 | | 3379 | |
| 3276 | try inttoptr_node.params.push(&ptrtoint_node.base); | 3380 | inttoptr_node.params()[1] = &ptrtoint_node.base; |
| 3277 | inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3381 | inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3278 | return &inttoptr_node.base; | 3382 | return &inttoptr_node.base; |
| 3279 | } else { | 3383 | } else { |
| 3280 | // Implicit downcasting from higher to lower alignment values is forbidden, | 3384 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| 3281 | // use @alignCast to side-step this problem | 3385 | // use @alignCast to side-step this problem |
| 3282 | const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); | 3386 | const ptrcast_node = try rp.c.createBuiltinCall("@ptrCast", 2); |
| 3283 | const dst_type_node = try transType(rp, ty, loc); | 3387 | const dst_type_node = try transType(rp, ty, loc); |
| 3284 | try ptrcast_node.params.push(dst_type_node); | 3388 | ptrcast_node.params()[0] = dst_type_node; |
| 3285 | _ = try appendToken(rp.c, .Comma, ","); | 3389 | _ = try appendToken(rp.c, .Comma, ","); |
| 3286 | | 3390 | |
| 3287 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { | 3391 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { |
| 3288 | // void has 1-byte alignment, so @alignCast is not needed | 3392 | // void has 1-byte alignment, so @alignCast is not needed |
| 3289 | try ptrcast_node.params.push(expr); | 3393 | ptrcast_node.params()[1] = expr; |
| 3290 | } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) { | 3394 | } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) { |
| 3291 | // For opaque types a ptrCast is enough | 3395 | // For opaque types a ptrCast is enough |
| 3292 | try ptrcast_node.params.push(expr); | 3396 | ptrcast_node.params()[1] = expr; |
| 3293 | } else { | 3397 | } else { |
| 3294 | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); | 3398 | const aligncast_node = try rp.c.createBuiltinCall("@alignCast", 2); |
| 3295 | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); | 3399 | const alignof_node = try rp.c.createBuiltinCall("@alignOf", 1); |
| 3296 | const child_type_node = try transQualType(rp, child_type, loc); | 3400 | const child_type_node = try transQualType(rp, child_type, loc); |
| 3297 | try alignof_node.params.push(child_type_node); | 3401 | alignof_node.params()[0] = child_type_node; |
| 3298 | alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3402 | alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3299 | try aligncast_node.params.push(&alignof_node.base); | 3403 | aligncast_node.params()[0] = &alignof_node.base; |
| 3300 | _ = try appendToken(rp.c, .Comma, ","); | 3404 | _ = try appendToken(rp.c, .Comma, ","); |
| 3301 | try aligncast_node.params.push(expr); | 3405 | aligncast_node.params()[1] = expr; |
| 3302 | aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3406 | aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3303 | try ptrcast_node.params.push(&aligncast_node.base); | 3407 | ptrcast_node.params()[1] = &aligncast_node.base; |
| 3304 | } | 3408 | } |
| 3305 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3409 | ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3306 | | 3410 | |
| ... | @@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const | ... | @@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const |
| 3343 | // }) | 3447 | // }) |
| 3344 | const lparen = try appendToken(rp.c, .LParen, "("); | 3448 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 3345 | | 3449 | |
| 3346 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3450 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3347 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | 3451 | defer block_scope.deinit(); |
| 3348 | | 3452 | |
| 3349 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); | 3453 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); |
| 3350 | const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name); | 3454 | const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name); |
| 3351 | tmp_var.eq_token = try appendToken(rp.c, .Equal, "="); | 3455 | tmp_var.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3352 | tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value); | 3456 | tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value); |
| 3353 | tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3457 | tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 3354 | try block_scope.block_node.statements.push(&tmp_var.base); | 3458 | try block_scope.statements.append(&tmp_var.base); |
| 3355 | | 3459 | |
| 3356 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 3460 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3357 | | 3461 | |
| 3358 | const if_node = try transCreateNodeIf(rp.c); | 3462 | const if_node = try transCreateNodeIf(rp.c); |
| 3359 | var cond_scope = Scope{ | 3463 | var cond_scope = Scope.Condition{ |
| 3360 | .parent = &block_scope.base, | 3464 | .base = .{ |
| 3361 | .id = .Condition, | 3465 | .parent = &block_scope.base, |
| | 3466 | .id = .Condition, |
| | 3467 | }, |
| 3362 | }; | 3468 | }; |
| | 3469 | defer cond_scope.deinit(); |
| 3363 | const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name); | 3470 | const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name); |
| 3364 | | 3471 | |
| 3365 | const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr)); | 3472 | const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr)); |
| 3366 | const cond_node = try finishBoolExpr(rp, &block_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used); | 3473 | const cond_node = try finishBoolExpr(rp, &cond_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used); |
| 3367 | if_node.condition = cond_node; | 3474 | if_node.condition = cond_node; |
| 3368 | _ = try appendToken(rp.c, .RParen, ")"); | 3475 | _ = try appendToken(rp.c, .RParen, ")"); |
| 3369 | | 3476 | |
| ... | @@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const | ... | @@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const |
| 3374 | | 3481 | |
| 3375 | break_node.rhs = &if_node.base; | 3482 | break_node.rhs = &if_node.base; |
| 3376 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3483 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3377 | try block_scope.block_node.statements.push(&break_node.base); | 3484 | try block_scope.statements.append(&break_node.base); |
| 3378 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 3485 | const block_node = block_scope.complete(rp.c); |
| 3379 | | 3486 | |
| 3380 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 3487 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3381 | grouped_expr.* = .{ | 3488 | grouped_expr.* = .{ |
| 3382 | .lparen = lparen, | 3489 | .lparen = lparen, |
| 3383 | .expr = &block_scope.block_node.base, | 3490 | .expr = &block_node.base, |
| 3384 | .rparen = try appendToken(rp.c, .RParen, ")"), | 3491 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3385 | }; | 3492 | }; |
| 3386 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); | 3493 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| ... | @@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla | ... | @@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 3390 | const grouped = scope.id == .Condition; | 3497 | const grouped = scope.id == .Condition; |
| 3391 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; | 3498 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; |
| 3392 | const if_node = try transCreateNodeIf(rp.c); | 3499 | const if_node = try transCreateNodeIf(rp.c); |
| 3393 | var cond_scope = Scope{ | 3500 | var cond_scope = Scope.Condition{ |
| 3394 | .parent = scope, | 3501 | .base = .{ |
| 3395 | .id = .Condition, | 3502 | .parent = scope, |
| | 3503 | .id = .Condition, |
| | 3504 | }, |
| 3396 | }; | 3505 | }; |
| | 3506 | defer cond_scope.deinit(); |
| 3397 | | 3507 | |
| 3398 | const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt); | 3508 | const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt); |
| 3399 | const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt); | 3509 | const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt); |
| 3400 | const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt); | 3510 | const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt); |
| 3401 | const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt); | 3511 | const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt); |
| 3402 | | 3512 | |
| 3403 | if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false); | 3513 | if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false); |
| 3404 | _ = try appendToken(rp.c, .RParen, ")"); | 3514 | _ = try appendToken(rp.c, .RParen, ")"); |
| 3405 | | 3515 | |
| 3406 | if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value); | 3516 | if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value); |
| ... | @@ -3571,19 +3681,19 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC | ... | @@ -3571,19 +3681,19 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC |
| 3571 | // Symbol "Log2Int" | 3681 | // Symbol "Log2Int" |
| 3572 | // Symbol <zig_type_node> (var from above) | 3682 | // Symbol <zig_type_node> (var from above) |
| 3573 | | 3683 | |
| 3574 | const import_fn_call = try transCreateNodeBuiltinFnCall(rp.c, "@import"); | 3684 | const import_fn_call = try rp.c.createBuiltinCall("@import", 1); |
| 3575 | const std_token = try appendToken(rp.c, .StringLiteral, "\"std\""); | 3685 | const std_token = try appendToken(rp.c, .StringLiteral, "\"std\""); |
| 3576 | const std_node = try rp.c.arena.create(ast.Node.StringLiteral); | 3686 | const std_node = try rp.c.arena.create(ast.Node.StringLiteral); |
| 3577 | std_node.* = .{ | 3687 | std_node.* = .{ |
| 3578 | .token = std_token, | 3688 | .token = std_token, |
| 3579 | }; | 3689 | }; |
| 3580 | try import_fn_call.params.push(&std_node.base); | 3690 | import_fn_call.params()[0] = &std_node.base; |
| 3581 | import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3691 | import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3582 | | 3692 | |
| 3583 | const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math"); | 3693 | const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math"); |
| 3584 | const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int"); | 3694 | const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int"); |
| 3585 | const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access); | 3695 | const log2int_fn_call = try rp.c.createCall(outer_field_access, 1); |
| 3586 | try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node); | 3696 | log2int_fn_call.params()[0] = zig_type_node; |
| 3587 | log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")"); | 3697 | log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 3588 | | 3698 | |
| 3589 | return &log2int_fn_call.base; | 3699 | return &log2int_fn_call.base; |
| ... | @@ -3757,8 +3867,8 @@ fn transCreateNodeAssign( | ... | @@ -3757,8 +3867,8 @@ fn transCreateNodeAssign( |
| 3757 | const eq_token = try appendToken(rp.c, .Equal, "="); | 3867 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| 3758 | var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value); | 3868 | var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value); |
| 3759 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { | 3869 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3760 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 3870 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 3761 | try builtin_node.params.push(rhs_node); | 3871 | builtin_node.params()[0] = rhs_node; |
| 3762 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3872 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3763 | rhs_node = &builtin_node.base; | 3873 | rhs_node = &builtin_node.base; |
| 3764 | } | 3874 | } |
| ... | @@ -3774,22 +3884,23 @@ fn transCreateNodeAssign( | ... | @@ -3774,22 +3884,23 @@ fn transCreateNodeAssign( |
| 3774 | // zig: lhs = _tmp; | 3884 | // zig: lhs = _tmp; |
| 3775 | // zig: break :blk _tmp | 3885 | // zig: break :blk _tmp |
| 3776 | // zig: }) | 3886 | // zig: }) |
| 3777 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3887 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3778 | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); | 3888 | defer block_scope.deinit(); |
| | 3889 | |
| 3779 | const tmp = try block_scope.makeMangledName(rp.c, "tmp"); | 3890 | const tmp = try block_scope.makeMangledName(rp.c, "tmp"); |
| 3780 | | 3891 | |
| 3781 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); | 3892 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); |
| 3782 | node.eq_token = try appendToken(rp.c, .Equal, "="); | 3893 | node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3783 | var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value); | 3894 | var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value); |
| 3784 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { | 3895 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3785 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 3896 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 3786 | try builtin_node.params.push(rhs_node); | 3897 | builtin_node.params()[0] = rhs_node; |
| 3787 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3898 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3788 | rhs_node = &builtin_node.base; | 3899 | rhs_node = &builtin_node.base; |
| 3789 | } | 3900 | } |
| 3790 | node.init_node = rhs_node; | 3901 | node.init_node = rhs_node; |
| 3791 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | 3902 | node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| 3792 | try block_scope.block_node.statements.push(&node.base); | 3903 | try block_scope.statements.append(&node.base); |
| 3793 | | 3904 | |
| 3794 | const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value); | 3905 | const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value); |
| 3795 | const eq_token = try appendToken(rp.c, .Equal, "="); | 3906 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| ... | @@ -3797,44 +3908,16 @@ fn transCreateNodeAssign( | ... | @@ -3797,44 +3908,16 @@ fn transCreateNodeAssign( |
| 3797 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3908 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3798 | | 3909 | |
| 3799 | const assign = try transCreateNodeInfixOp(rp, &block_scope.base, lhs_node, .Assign, eq_token, ident, .used, false); | 3910 | const assign = try transCreateNodeInfixOp(rp, &block_scope.base, lhs_node, .Assign, eq_token, ident, .used, false); |
| 3800 | try block_scope.block_node.statements.push(assign); | 3911 | try block_scope.statements.append(assign); |
| 3801 | | 3912 | |
| 3802 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 3913 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3803 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); | 3914 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); |
| 3804 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3915 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3805 | try block_scope.block_node.statements.push(&break_node.base); | 3916 | try block_scope.statements.append(&break_node.base); |
| 3806 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 3917 | const block_node = try block_scope.complete(rp.c); |
| 3807 | // semicolon must immediately follow rbrace because it is the last token in a block | 3918 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 3808 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3919 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3809 | return &block_scope.block_node.base; | 3920 | return &block_node.base; |
| 3810 | } | | |
| 3811 | | | |
| 3812 | fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall { | | |
| 3813 | const builtin_token = try appendToken(c, .Builtin, name); | | |
| 3814 | _ = try appendToken(c, .LParen, "("); | | |
| 3815 | const node = try c.arena.create(ast.Node.BuiltinCall); | | |
| 3816 | node.* = .{ | | |
| 3817 | .builtin_token = builtin_token, | | |
| 3818 | .params = ast.Node.BuiltinCall.ParamList{}, | | |
| 3819 | .rparen_token = undefined, // set after appending args | | |
| 3820 | }; | | |
| 3821 | return node; | | |
| 3822 | } | | |
| 3823 | | | |
| 3824 | fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { | | |
| 3825 | _ = try appendToken(c, .LParen, "("); | | |
| 3826 | const node = try c.arena.create(ast.Node.SuffixOp); | | |
| 3827 | node.* = .{ | | |
| 3828 | .lhs = fn_expr, | | |
| 3829 | .op = .{ | | |
| 3830 | .Call = .{ | | |
| 3831 | .params = ast.Node.SuffixOp.Op.Call.ParamList{}, | | |
| 3832 | .async_token = null, | | |
| 3833 | }, | | |
| 3834 | }, | | |
| 3835 | .rtoken = undefined, // set after appending args | | |
| 3836 | }; | | |
| 3837 | return node; | | |
| 3838 | } | 3921 | } |
| 3839 | | 3922 | |
| 3840 | fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node { | 3923 | fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node { |
| ... | @@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node { | ... | @@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node { |
| 4083 | } | 4166 | } |
| 4084 | | 4167 | |
| 4085 | fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { | 4168 | fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { |
| 4086 | const call_node = try transCreateNodeBuiltinFnCall(c, "@Type"); | 4169 | const call_node = try c.createBuiltinCall("@Type", 1); |
| 4087 | try call_node.params.push(try transCreateNodeEnumLiteral(c, "Opaque")); | 4170 | call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque"); |
| 4088 | call_node.rparen_token = try appendToken(c, .RParen, ")"); | 4171 | call_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 4089 | return &call_node.base; | 4172 | return &call_node.base; |
| 4090 | } | 4173 | } |
| ... | @@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a | ... | @@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 4139 | }; | 4222 | }; |
| 4140 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); | 4223 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); |
| 4141 | | 4224 | |
| 4142 | const block = try transCreateNodeBlock(c, null); | 4225 | const block_lbrace = try appendToken(c, .LBrace, "{"); |
| 4143 | var block_statements_it = &block.statements.first; | | |
| 4144 | | 4226 | |
| 4145 | const return_expr = try transCreateNodeReturnExpr(c); | 4227 | const return_expr = try transCreateNodeReturnExpr(c); |
| 4146 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); | 4228 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); |
| 4147 | const call_expr = try transCreateNodeFnCall(c, unwrap_expr); | 4229 | |
| 4148 | var call_params_it = &call_expr.op.Call.params.first; | 4230 | const call_expr = try c.createCall(unwrap_expr, fn_params.items.len); |
| | 4231 | const call_params = call_expr.params(); |
| 4149 | | 4232 | |
| 4150 | for (fn_params.items) |param, i| { | 4233 | for (fn_params.items) |param, i| { |
| 4151 | if (i != 0) { | 4234 | if (i != 0) { |
| 4152 | _ = try appendToken(c, .Comma, ","); | 4235 | _ = try appendToken(c, .Comma, ","); |
| 4153 | } | 4236 | } |
| 4154 | call_params_it = try c.llpush(*ast.Node, call_params_it, try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)),); | 4237 | call_params[i] = try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)); |
| 4155 | } | 4238 | } |
| 4156 | call_expr.rtoken = try appendToken(c, .RParen, ")"); | 4239 | call_expr.rtoken = try appendToken(c, .RParen, ")"); |
| | 4240 | |
| 4157 | return_expr.rhs = &call_expr.base; | 4241 | return_expr.rhs = &call_expr.base; |
| 4158 | _ = try appendToken(c, .Semicolon, ";"); | 4242 | _ = try appendToken(c, .Semicolon, ";"); |
| 4159 | | 4243 | |
| 4160 | block.rbrace = try appendToken(c, .RBrace, "}"); | 4244 | const block = try ast.Node.Block.alloc(c.arena, 1); |
| 4161 | block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base); | 4245 | block.* = .{ |
| | 4246 | .label = null, |
| | 4247 | .lbrace = block_lbrace, |
| | 4248 | .statements_len = 1, |
| | 4249 | .rbrace = try appendToken(c, .RBrace, "}"), |
| | 4250 | }; |
| | 4251 | block.statements()[0] = &return_expr.base; |
| 4162 | fn_proto.body_node = &block.base; | 4252 | fn_proto.body_node = &block.base; |
| 4163 | return &fn_proto.base; | 4253 | return &fn_proto.base; |
| 4164 | } | 4254 | } |
| ... | @@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { | ... | @@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { |
| 4216 | return node; | 4306 | return node; |
| 4217 | } | 4307 | } |
| 4218 | | 4308 | |
| 4219 | fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block { | | |
| 4220 | const label_node = if (label) |l| blk: { | | |
| 4221 | const ll = try appendIdentifier(c, l); | | |
| 4222 | _ = try appendToken(c, .Colon, ":"); | | |
| 4223 | break :blk ll; | | |
| 4224 | } else null; | | |
| 4225 | const block_node = try c.arena.create(ast.Node.Block); | | |
| 4226 | block_node.* = .{ | | |
| 4227 | .label = label_node, | | |
| 4228 | .lbrace = try appendToken(c, .LBrace, "{"), | | |
| 4229 | .statements = ast.Node.Block.StatementList{}, | | |
| 4230 | .rbrace = undefined, | | |
| 4231 | }; | | |
| 4232 | return block_node; | | |
| 4233 | } | | |
| 4234 | | | |
| 4235 | fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression { | 4309 | fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression { |
| 4236 | const ltoken = try appendToken(c, .Keyword_break, "break"); | 4310 | const ltoken = try appendToken(c, .Keyword_break, "break"); |
| 4237 | const label_node = if (label) |l| blk: { | 4311 | const label_node = if (label) |l| blk: { |
| ... | @@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node { | ... | @@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node { |
| 4302 | return &node.base; | 4376 | return &node.base; |
| 4303 | } | 4377 | } |
| 4304 | | 4378 | |
| 4305 | fn transCreateNodeSwitch(c: *Context) !*ast.Node.Switch { | | |
| 4306 | const switch_tok = try appendToken(c, .Keyword_switch, "switch"); | | |
| 4307 | _ = try appendToken(c, .LParen, "("); | | |
| 4308 | | | |
| 4309 | const node = try c.arena.create(ast.Node.Switch); | | |
| 4310 | node.* = .{ | | |
| 4311 | .switch_token = switch_tok, | | |
| 4312 | .expr = undefined, | | |
| 4313 | .cases = ast.Node.Switch.CaseList{}, | | |
| 4314 | .rbrace = undefined, | | |
| 4315 | }; | | |
| 4316 | return node; | | |
| 4317 | } | | |
| 4318 | | | |
| 4319 | fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase { | 4379 | fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase { |
| 4320 | const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>"); | 4380 | const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>"); |
| 4321 | | 4381 | |
| ... | @@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp( | ... | @@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp( |
| 4356 | const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value); | 4416 | const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value); |
| 4357 | const op_token = try appendToken(rp.c, op_tok_id, bytes); | 4417 | const op_token = try appendToken(rp.c, op_tok_id, bytes); |
| 4358 | | 4418 | |
| 4359 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | 4419 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 4360 | const rhs_type = try qualTypeToLog2IntRef(rp, ZigClangBinaryOperator_getType(stmt), rhs_location); | 4420 | const rhs_type = try qualTypeToLog2IntRef(rp, ZigClangBinaryOperator_getType(stmt), rhs_location); |
| 4361 | try cast_node.params.push(rhs_type); | 4421 | cast_node.params()[0] = rhs_type; |
| 4362 | _ = try appendToken(rp.c, .Comma, ","); | 4422 | _ = try appendToken(rp.c, .Comma, ","); |
| 4363 | const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value); | 4423 | const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value); |
| 4364 | try cast_node.params.push(rhs); | 4424 | cast_node.params()[1] = rhs; |
| 4365 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 4425 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 4366 | | 4426 | |
| 4367 | const node = try rp.c.arena.create(ast.Node.InfixOp); | 4427 | const node = try rp.c.arena.create(ast.Node.InfixOp); |
| ... | @@ -4832,14 +4892,13 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp | ... | @@ -4832,14 +4892,13 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp |
| 4832 | .token = msg_tok, | 4892 | .token = msg_tok, |
| 4833 | }; | 4893 | }; |
| 4834 | | 4894 | |
| 4835 | const call_node = try c.arena.create(ast.Node.BuiltinCall); | 4895 | const call_node = try ast.Node.BuiltinCall.alloc(c.arena, 1); |
| 4836 | call_node.* = .{ | 4896 | call_node.* = .{ |
| 4837 | .builtin_token = builtin_tok, | 4897 | .builtin_token = builtin_tok, |
| 4838 | .params = ast.Node.BuiltinCall.ParamList{}, | 4898 | .params_len = 1, |
| 4839 | .rparen_token = rparen_tok, | 4899 | .rparen_token = rparen_tok, |
| 4840 | }; | 4900 | }; |
| 4841 | var call_params_it = &call_node.params.first; | 4901 | call_node.params()[0] = &msg_node.base; |
| 4842 | call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base); | | |
| 4843 | | 4902 | |
| 4844 | const var_decl_node = try c.arena.create(ast.Node.VarDecl); | 4903 | const var_decl_node = try c.arena.create(ast.Node.VarDecl); |
| 4845 | var_decl_node.* = .{ | 4904 | var_decl_node.* = .{ |
| ... | @@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd | ... | @@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd |
| 4868 | | 4927 | |
| 4869 | fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex { | 4928 | fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex { |
| 4870 | assert(token_id != .Invalid); | 4929 | assert(token_id != .Invalid); |
| 4871 | const start_index = c.source_buffer.items.len; | | |
| 4872 | errdefer c.source_buffer.shrink(start_index); | | |
| 4873 | | 4930 | |
| 4874 | try c.source_buffer.outStream().print(format, args); | 4931 | try c.token_ids.ensureCapacity(c.gpa, c.token_ids.items.len + 1); |
| 4875 | const end_index = c.source_buffer.items.len; | 4932 | try c.token_locs.ensureCapacity(c.gpa, c.token_locs.items.len + 1); |
| 4876 | const token_index = c.tokens.items.len; | | |
| 4877 | const new_token = try c.tokens.addOne(c.gpa); | | |
| 4878 | errdefer c.tokens.shrink(c.gpa, token_index); | | |
| 4879 | | 4933 | |
| 4880 | new_token.* = .{ | 4934 | const start_index = c.source_buffer.items.len; |
| 4881 | .id = token_id, | 4935 | try c.source_buffer.outStream().print(format ++ " ", args); |
| | 4936 | |
| | 4937 | c.token_ids.appendAssumeCapacity(token_id); |
| | 4938 | c.token_locs.appendAssumeCapacity(.{ |
| 4882 | .start = start_index, | 4939 | .start = start_index, |
| 4883 | .end = end_index, | 4940 | .end = c.source_buffer.items.len - 1, // back up before the space |
| 4884 | }; | 4941 | }); |
| 4885 | try c.source_buffer.append(' '); | | |
| 4886 | | 4942 | |
| 4887 | return token_index; | 4943 | return c.token_ids.items.len - 1; |
| 4888 | } | 4944 | } |
| 4889 | | 4945 | |
| 4890 | // TODO hook up with codegen | 4946 | // TODO hook up with codegen |
| ... | @@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n | ... | @@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n |
| 5072 | } | 5128 | } |
| 5073 | | 5129 | |
| 5074 | fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { | 5130 | fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 5075 | const block_scope = try Scope.Block.init(c, &c.global_scope.base, null); | 5131 | var block_scope = try Scope.Block.init(c, &c.global_scope.base, null); |
| | 5132 | defer block_scope.deinit(); |
| 5076 | const scope = &block_scope.base; | 5133 | const scope = &block_scope.base; |
| 5077 | | 5134 | |
| 5078 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); | 5135 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| ... | @@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5142 | | 5199 | |
| 5143 | _ = try appendToken(c, .RParen, ")"); | 5200 | _ = try appendToken(c, .RParen, ")"); |
| 5144 | | 5201 | |
| 5145 | const type_of = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); | 5202 | const type_of = try c.createBuiltinCall("@TypeOf", 1); |
| 5146 | type_of.rparen_token = try appendToken(c, .RParen, ")"); | | |
| 5147 | var type_of_params = c.llpusher(&type_of.params); | | |
| 5148 | | 5203 | |
| 5149 | const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len); | 5204 | const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len); |
| 5150 | fn_proto.* = .{ | 5205 | fn_proto.* = .{ |
| ... | @@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5164 | }; | 5219 | }; |
| 5165 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); | 5220 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); |
| 5166 | | 5221 | |
| 5167 | const block = try transCreateNodeBlock(c, null); | | |
| 5168 | var block_statements = c.llpusher(&block.statements); | | |
| 5169 | | | |
| 5170 | const return_expr = try transCreateNodeReturnExpr(c); | 5222 | const return_expr = try transCreateNodeReturnExpr(c); |
| 5171 | const expr = try parseCExpr(c, it, source, source_loc, scope); | 5223 | const expr = try parseCExpr(c, it, source, source_loc, scope); |
| 5172 | const last = it.next().?; | 5224 | const last = it.next().?; |
| ... | @@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5186 | const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last); | 5238 | const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last); |
| 5187 | break :blk br.rhs.?; | 5239 | break :blk br.rhs.?; |
| 5188 | }; | 5240 | }; |
| 5189 | try type_of_params.push(type_of_arg); | 5241 | type_of.params()[0] = type_of_arg; |
| | 5242 | type_of.rparen_token = try appendToken(c, .RParen, ")"); |
| 5190 | return_expr.rhs = expr; | 5243 | return_expr.rhs = expr; |
| 5191 | | 5244 | |
| 5192 | block.rbrace = try appendToken(c, .RBrace, "}"); | 5245 | try block_scope.statements.append(&return_expr.base); |
| 5193 | try block_statements.push(&return_expr.base); | 5246 | const block_node = try block_scope.complete(c); |
| 5194 | fn_proto.body_node = &block.base; | 5247 | fn_proto.body_node = &block_node.base; |
| 5195 | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); | 5248 | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); |
| 5196 | } | 5249 | } |
| 5197 | | 5250 | |
| ... | @@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ | ... | @@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ |
| 5223 | }, | 5276 | }, |
| 5224 | .Comma => { | 5277 | .Comma => { |
| 5225 | _ = try appendToken(c, .Semicolon, ";"); | 5278 | _ = try appendToken(c, .Semicolon, ";"); |
| 5226 | const block_scope = try Scope.Block.init(c, scope, "blk"); | 5279 | var block_scope = try Scope.Block.init(c, scope, "blk"); |
| 5227 | block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label)); | 5280 | defer block_scope.deinit(); |
| 5228 | | 5281 | |
| 5229 | var last = node; | 5282 | var last = node; |
| 5230 | while (true) { | 5283 | while (true) { |
| ... | @@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ | ... | @@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ |
| 5238 | .op = .Assign, | 5291 | .op = .Assign, |
| 5239 | .rhs = last, | 5292 | .rhs = last, |
| 5240 | }; | 5293 | }; |
| 5241 | try block_scope.block_node.statements.push(&op_node.base); | 5294 | try block_scope.statements.append(&op_node.base); |
| 5242 | | 5295 | |
| 5243 | last = try parseCPrefixOpExpr(c, it, source, source_loc, scope); | 5296 | last = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5244 | _ = try appendToken(c, .Semicolon, ";"); | 5297 | _ = try appendToken(c, .Semicolon, ";"); |
| ... | @@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ | ... | @@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ |
| 5250 | | 5303 | |
| 5251 | const break_node = try transCreateNodeBreak(c, block_scope.label); | 5304 | const break_node = try transCreateNodeBreak(c, block_scope.label); |
| 5252 | break_node.rhs = last; | 5305 | break_node.rhs = last; |
| 5253 | try block_scope.block_node.statements.push(&break_node.base); | 5306 | try block_scope.statements.append(&break_node.base); |
| 5254 | block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}"); | 5307 | const block_node = try block_scope.complete(c); |
| 5255 | return &block_scope.block_node.base; | 5308 | return &block_node.base; |
| 5256 | }, | 5309 | }, |
| 5257 | else => { | 5310 | else => { |
| 5258 | _ = it.prev(); | 5311 | _ = it.prev(); |
| ... | @@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl | ... | @@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5283 | return transCreateNodeInt(c, lit_bytes); | 5336 | return transCreateNodeInt(c, lit_bytes); |
| 5284 | } | 5337 | } |
| 5285 | | 5338 | |
| 5286 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); | 5339 | const cast_node = try c.createBuiltinCall("@as", 2); |
| 5287 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) { | 5340 | cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) { |
| 5288 | .U => "c_uint", | 5341 | .U => "c_uint", |
| 5289 | .L => "c_long", | 5342 | .L => "c_long", |
| 5290 | .LU => "c_ulong", | 5343 | .LU => "c_ulong", |
| 5291 | .LL => "c_longlong", | 5344 | .LL => "c_longlong", |
| 5292 | .LLU => "c_ulonglong", | 5345 | .LLU => "c_ulonglong", |
| 5293 | else => unreachable, | 5346 | else => unreachable, |
| 5294 | })); | 5347 | }); |
| 5295 | lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) { | 5348 | lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) { |
| 5296 | .U, .L => @as(u8, 1), | 5349 | .U, .L => @as(u8, 1), |
| 5297 | .LU, .LL => 2, | 5350 | .LU, .LL => 2, |
| ... | @@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl | ... | @@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5299 | else => unreachable, | 5352 | else => unreachable, |
| 5300 | }]; | 5353 | }]; |
| 5301 | _ = try appendToken(c, .Comma, ","); | 5354 | _ = try appendToken(c, .Comma, ","); |
| 5302 | try cast_node.params.push(try transCreateNodeInt(c, lit_bytes)); | 5355 | cast_node.params()[1] = try transCreateNodeInt(c, lit_bytes); |
| 5303 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); | 5356 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5304 | return &cast_node.base; | 5357 | return &cast_node.base; |
| 5305 | } else if (tok.id == .FloatLiteral) { | 5358 | } else if (tok.id == .FloatLiteral) { |
| ... | @@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl | ... | @@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5308 | if (tok.id.FloatLiteral == .None) { | 5361 | if (tok.id.FloatLiteral == .None) { |
| 5309 | return transCreateNodeFloat(c, lit_bytes); | 5362 | return transCreateNodeFloat(c, lit_bytes); |
| 5310 | } | 5363 | } |
| 5311 | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); | 5364 | const cast_node = try c.createBuiltinCall("@as", 2); |
| 5312 | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) { | 5365 | cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) { |
| 5313 | .F => "f32", | 5366 | .F => "f32", |
| 5314 | .L => "c_longdouble", | 5367 | .L => "c_longdouble", |
| 5315 | else => unreachable, | 5368 | else => unreachable, |
| 5316 | })); | 5369 | }); |
| 5317 | _ = try appendToken(c, .Comma, ","); | 5370 | _ = try appendToken(c, .Comma, ","); |
| 5318 | try cast_node.params.push(try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1])); | 5371 | cast_node.params()[1] = try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]); |
| 5319 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); | 5372 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5320 | return &cast_node.base; | 5373 | return &cast_node.base; |
| 5321 | } else unreachable; | 5374 | } else unreachable; |
| ... | @@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5585 | //else | 5638 | //else |
| 5586 | // @as(dest, x) ) | 5639 | // @as(dest, x) ) |
| 5587 | const if_node = try transCreateNodeIf(c); | 5640 | const if_node = try transCreateNodeIf(c); |
| 5588 | const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | 5641 | const type_info_node = try rp.c.createBuiltinCall("@typeInfo", 1); |
| 5589 | try type_info_node.params.push(inner_node); | 5642 | type_info_node.params()[0] = inner_node; |
| 5590 | type_info_node.rparen_token = try appendToken(c, .LParen, ")"); | 5643 | type_info_node.rparen_token = try appendToken(c, .LParen, ")"); |
| 5591 | const cmp_node = try c.arena.create(ast.Node.InfixOp); | 5644 | const cmp_node = try c.arena.create(ast.Node.InfixOp); |
| 5592 | cmp_node.* = .{ | 5645 | cmp_node.* = .{ |
| ... | @@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5598 | if_node.condition = &cmp_node.base; | 5651 | if_node.condition = &cmp_node.base; |
| 5599 | _ = try appendToken(c, .RParen, ")"); | 5652 | _ = try appendToken(c, .RParen, ")"); |
| 5600 | | 5653 | |
| 5601 | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); | 5654 | const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2); |
| 5602 | try int_to_ptr.params.push(inner_node); | 5655 | int_to_ptr.params()[0] = inner_node; |
| 5603 | try int_to_ptr.params.push(node_to_cast); | 5656 | int_to_ptr.params()[1] = node_to_cast; |
| 5604 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); | 5657 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| 5605 | if_node.body = &int_to_ptr.base; | 5658 | if_node.body = &int_to_ptr.base; |
| 5606 | | 5659 | |
| 5607 | const else_node = try transCreateNodeElse(c); | 5660 | const else_node = try transCreateNodeElse(c); |
| 5608 | if_node.@"else" = else_node; | 5661 | if_node.@"else" = else_node; |
| 5609 | | 5662 | |
| 5610 | const as_node = try transCreateNodeBuiltinFnCall(c, "@as"); | 5663 | const as_node = try c.createBuiltinCall("@as", 2); |
| 5611 | try as_node.params.push(inner_node); | 5664 | as_node.params()[0] = inner_node; |
| 5612 | try as_node.params.push(node_to_cast); | 5665 | as_node.params()[1] = node_to_cast; |
| 5613 | as_node.rparen_token = try appendToken(c, .RParen, ")"); | 5666 | as_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5614 | else_node.body = &as_node.base; | 5667 | else_node.body = &as_node.base; |
| 5615 | | 5668 | |
| ... | @@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5630 | // @as(dest, x) ) | 5683 | // @as(dest, x) ) |
| 5631 | | 5684 | |
| 5632 | const if_1 = try transCreateNodeIf(c); | 5685 | const if_1 = try transCreateNodeIf(c); |
| 5633 | const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | 5686 | const type_info_1 = try c.createBuiltinCall("@typeInfo", 1); |
| 5634 | const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); | 5687 | const type_of_1 = try c.createBuiltinCall("@TypeOf", 1); |
| 5635 | try type_info_1.params.push(&type_of_1.base); | 5688 | type_info_1.params()[0] = &type_of_1.base; |
| 5636 | try type_of_1.params.push(node_to_cast); | 5689 | type_of_1.params()[0] = node_to_cast; |
| 5637 | type_of_1.rparen_token = try appendToken(c, .RParen, ")"); | 5690 | type_of_1.rparen_token = try appendToken(c, .RParen, ")"); |
| 5638 | type_info_1.rparen_token = try appendToken(c, .RParen, ")"); | 5691 | type_info_1.rparen_token = try appendToken(c, .RParen, ")"); |
| 5639 | | 5692 | |
| ... | @@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5657 | .rhs = child_ident, | 5710 | .rhs = child_ident, |
| 5658 | }; | 5711 | }; |
| 5659 | | 5712 | |
| 5660 | const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf"); | 5713 | const align_of = try rp.c.createBuiltinCall("@alignOf", 1); |
| 5661 | try align_of.params.push(&inner_node_child.base); | 5714 | align_of.params()[0] = &inner_node_child.base; |
| 5662 | align_of.rparen_token = try appendToken(c, .RParen, ")"); | 5715 | align_of.rparen_token = try appendToken(c, .RParen, ")"); |
| 5663 | // hack to get zig fmt to render a comma in builtin calls | 5716 | // hack to get zig fmt to render a comma in builtin calls |
| 5664 | _ = try appendToken(c, .Comma, ","); | 5717 | _ = try appendToken(c, .Comma, ","); |
| 5665 | | 5718 | |
| 5666 | const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast"); | 5719 | const align_cast = try c.createBuiltinCall("@alignCast", 2); |
| 5667 | try align_cast.params.push(&align_of.base); | 5720 | align_cast.params()[0] = &align_of.base; |
| 5668 | try align_cast.params.push(node_to_cast); | 5721 | align_cast.params()[1] = node_to_cast; |
| 5669 | align_cast.rparen_token = try appendToken(c, .RParen, ")"); | 5722 | align_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| 5670 | | 5723 | |
| 5671 | const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast"); | 5724 | const ptr_cast = try c.createBuiltinCall("@ptrCast", 2); |
| 5672 | try ptr_cast.params.push(inner_node); | 5725 | ptr_cast.params()[0] = inner_node; |
| 5673 | try ptr_cast.params.push(&align_cast.base); | 5726 | ptr_cast.params()[1] = &align_cast.base; |
| 5674 | ptr_cast.rparen_token = try appendToken(c, .RParen, ")"); | 5727 | ptr_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| 5675 | if_1.body = &ptr_cast.base; | 5728 | if_1.body = &ptr_cast.base; |
| 5676 | | 5729 | |
| ... | @@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5678 | if_1.@"else" = else_1; | 5731 | if_1.@"else" = else_1; |
| 5679 | | 5732 | |
| 5680 | const if_2 = try transCreateNodeIf(c); | 5733 | const if_2 = try transCreateNodeIf(c); |
| 5681 | const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | 5734 | const type_info_2 = try c.createBuiltinCall("@typeInfo", 1); |
| 5682 | const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); | 5735 | const type_of_2 = try c.createBuiltinCall("@TypeOf", 1); |
| 5683 | try type_info_2.params.push(&type_of_2.base); | 5736 | type_info_2.params()[0] = &type_of_2.base; |
| 5684 | try type_of_2.params.push(node_to_cast); | 5737 | type_of_2.params()[0] = node_to_cast; |
| 5685 | type_of_2.rparen_token = try appendToken(c, .RParen, ")"); | 5738 | type_of_2.rparen_token = try appendToken(c, .RParen, ")"); |
| 5686 | type_info_2.rparen_token = try appendToken(c, .RParen, ")"); | 5739 | type_info_2.rparen_token = try appendToken(c, .RParen, ")"); |
| 5687 | | 5740 | |
| ... | @@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5700 | .op = .BoolAnd, | 5753 | .op = .BoolAnd, |
| 5701 | .rhs = undefined, | 5754 | .rhs = undefined, |
| 5702 | }; | 5755 | }; |
| 5703 | const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); | 5756 | const type_info_3 = try c.createBuiltinCall("@typeInfo", 1); |
| 5704 | try type_info_3.params.push(inner_node); | 5757 | type_info_3.params()[0] = inner_node; |
| 5705 | type_info_3.rparen_token = try appendToken(c, .LParen, ")"); | 5758 | type_info_3.rparen_token = try appendToken(c, .LParen, ")"); |
| 5706 | const cmp_3 = try c.arena.create(ast.Node.InfixOp); | 5759 | const cmp_3 = try c.arena.create(ast.Node.InfixOp); |
| 5707 | cmp_3.* = .{ | 5760 | cmp_3.* = .{ |
| ... | @@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5715 | else_1.body = &if_2.base; | 5768 | else_1.body = &if_2.base; |
| 5716 | _ = try appendToken(c, .RParen, ")"); | 5769 | _ = try appendToken(c, .RParen, ")"); |
| 5717 | | 5770 | |
| 5718 | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); | 5771 | const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2); |
| 5719 | try int_to_ptr.params.push(inner_node); | 5772 | int_to_ptr.params()[0] = inner_node; |
| 5720 | try int_to_ptr.params.push(node_to_cast); | 5773 | int_to_ptr.params()[1] = node_to_cast; |
| 5721 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); | 5774 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| 5722 | if_2.body = &int_to_ptr.base; | 5775 | if_2.body = &int_to_ptr.base; |
| 5723 | | 5776 | |
| 5724 | const else_2 = try transCreateNodeElse(c); | 5777 | const else_2 = try transCreateNodeElse(c); |
| 5725 | if_2.@"else" = else_2; | 5778 | if_2.@"else" = else_2; |
| 5726 | | 5779 | |
| 5727 | const as = try transCreateNodeBuiltinFnCall(c, "@as"); | 5780 | const as = try c.createBuiltinCall("@as", 2); |
| 5728 | try as.params.push(inner_node); | 5781 | as.params()[0] = inner_node; |
| 5729 | try as.params.push(node_to_cast); | 5782 | as.params()[1] = node_to_cast; |
| 5730 | as.rparen_token = try appendToken(c, .RParen, ")"); | 5783 | as.rparen_token = try appendToken(c, .RParen, ")"); |
| 5731 | else_2.body = &as.base; | 5784 | else_2.body = &as.base; |
| 5732 | | 5785 | |
| ... | @@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node { | ... | @@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node { |
| 5765 | return &group_node.base; | 5818 | return &group_node.base; |
| 5766 | } | 5819 | } |
| 5767 | | 5820 | |
| 5768 | const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt"); | 5821 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 5769 | try builtin_node.params.push(node); | 5822 | builtin_node.params()[0] = node; |
| 5770 | builtin_node.rparen_token = try appendToken(c, .RParen, ")"); | 5823 | builtin_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5771 | return &builtin_node.base; | 5824 | return &builtin_node.base; |
| 5772 | } | 5825 | } |
| ... | @@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5944 | continue; | 5997 | continue; |
| 5945 | }, | 5998 | }, |
| 5946 | .LParen => { | 5999 | .LParen => { |
| 5947 | const call_node = try transCreateNodeFnCall(c, node); | 6000 | _ = try appendToken(c, .LParen, "("); |
| | 6001 | var call_params = std.ArrayList(*ast.Node).init(c.gpa); |
| | 6002 | defer call_params.deinit(); |
| 5948 | while (true) { | 6003 | while (true) { |
| 5949 | const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope); | 6004 | const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5950 | try call_node.op.Call.params.push(arg); | 6005 | try call_params.append(arg); |
| 5951 | const next = it.next().?; | 6006 | const next = it.next().?; |
| 5952 | if (next.id == .Comma) | 6007 | if (next.id == .Comma) |
| 5953 | _ = try appendToken(c, .Comma, ",") | 6008 | _ = try appendToken(c, .Comma, ",") |
| ... | @@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5965 | return error.ParseError; | 6020 | return error.ParseError; |
| 5966 | } | 6021 | } |
| 5967 | } | 6022 | } |
| 5968 | call_node.rtoken = try appendToken(c, .RParen, ")"); | 6023 | const call_node = try ast.Node.Call.alloc(c.arena, call_params.items.len); |
| | 6024 | call_node.* = .{ |
| | 6025 | .lhs = node, |
| | 6026 | .params_len = call_params.items.len, |
| | 6027 | .async_token = null, |
| | 6028 | .rtoken = try appendToken(c, .RParen, ")"), |
| | 6029 | }; |
| | 6030 | mem.copy(*ast.Node, call_node.params(), call_params.items); |
| 5969 | node = &call_node.base; | 6031 | node = &call_node.base; |
| 5970 | continue; | 6032 | continue; |
| 5971 | }, | 6033 | }, |