| ... | ... | @@ -54,44 +54,79 @@ const Scope = struct { |
| 54 | 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 | 60 | const Switch = struct { |
| 58 | 61 | base: Scope, |
| 59 | | pending_block: *ast.Node.Block, |
| 60 | | cases: *ast.Node.Switch.CaseList, |
| 62 | pending_block: *Block, |
| 63 | cases: []*ast.Node, |
| 64 | case_index: usize, |
| 61 | 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 | 89 | const Block = struct { |
| 65 | 90 | base: Scope, |
| 66 | | block_node: *ast.Node.Block, |
| 67 | | statements_it: *?*std.SinglyLinkedList(*ast.Node), |
| 91 | statements: std.ArrayList(*ast.Node), |
| 68 | 92 | variables: AliasList, |
| 69 | | label: ?[]const u8, |
| 93 | label: ?ast.TokenIndex, |
| 70 | 94 | mangle_count: u32 = 0, |
| 95 | lbrace: ast.TokenIndex, |
| 71 | 96 | |
| 72 | | /// Don't forget to set rbrace token and block_node later |
| 73 | | fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block { |
| 74 | | const block = try c.arena.create(Block); |
| 75 | | block.* = .{ |
| 97 | fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block { |
| 98 | return Block{ |
| 76 | 99 | .base = .{ |
| 77 | 100 | .id = .Block, |
| 78 | 101 | .parent = parent, |
| 79 | 102 | }, |
| 80 | | .block_node = undefined, |
| 81 | | .statements_it = undefined, |
| 82 | | .variables = AliasList.init(c.arena), |
| 83 | | .label = label, |
| 103 | .statements = std.ArrayList(*ast.Node).init(c.gpa), |
| 104 | .variables = AliasList.init(c.gpa), |
| 105 | .label = if (self.label) |l| blk: { |
| 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 { |
| 89 | | self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt); |
| 114 | fn deinit(self: *Block) void { |
| 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 { |
| 93 | | self.block_node = block; |
| 94 | | self.statements_it = &block.statements.first; |
| 120 | fn complete(self: *Block, c: *Context) !*ast.Node.Block { |
| 121 | const node = try ast.Node.Block.alloc(c.arena, self.statements.items.len); |
| 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 | 132 | /// Given the desired name, return a name that does not shadow anything from outer scopes. |
| ... | ... | @@ -102,12 +137,13 @@ const Scope = struct { |
| 102 | 137 | scope.mangle_count += 1; |
| 103 | 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 | 141 | return proposed_name; |
| 107 | 142 | } |
| 108 | 143 | |
| 109 | 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 | 147 | if (mem.eql(u8, p.name, name)) |
| 112 | 148 | return p.alias; |
| 113 | 149 | } |
| ... | ... | @@ -115,7 +151,8 @@ const Scope = struct { |
| 115 | 151 | } |
| 116 | 152 | |
| 117 | 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 | 156 | if (mem.eql(u8, p.name, name)) |
| 120 | 157 | return true; |
| 121 | 158 | } |
| ... | ... | @@ -167,10 +204,7 @@ const Scope = struct { |
| 167 | 204 | switch (scope.id) { |
| 168 | 205 | .Root => unreachable, |
| 169 | 206 | .Block => return @fieldParentPtr(Block, "base", scope), |
| 170 | | .Condition => { |
| 171 | | // comma operator used |
| 172 | | return try Block.init(c, scope, "blk"); |
| 173 | | }, |
| 207 | .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c), |
| 174 | 208 | else => scope = scope.parent.?, |
| 175 | 209 | } |
| 176 | 210 | } |
| ... | ... | @@ -219,7 +253,8 @@ const Scope = struct { |
| 219 | 253 | pub const Context = struct { |
| 220 | 254 | gpa: *mem.Allocator, |
| 221 | 255 | arena: *mem.Allocator, |
| 222 | | tokens: std.ArrayListUnmanaged(Token), |
| 256 | token_ids: std.ArrayListUnmanaged(Token.Id), |
| 257 | token_locs: std.ArrayListUnmanaged(Token.Loc), |
| 223 | 258 | errors: std.ArrayListUnmanaged(ast.Error), |
| 224 | 259 | source_buffer: *std.ArrayList(u8), |
| 225 | 260 | err: Error, |
| ... | ... | @@ -237,16 +272,6 @@ pub const Context = struct { |
| 237 | 272 | /// up front in a pre-processing step. |
| 238 | 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 | 275 | fn getMangle(c: *Context) u32 { |
| 251 | 276 | c.mangle_count += 1; |
| 252 | 277 | return c.mangle_count; |
| ... | ... | @@ -267,6 +292,46 @@ pub const Context = struct { |
| 267 | 292 | const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc); |
| 268 | 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 | 337 | pub fn translate( |
| ... | ... | @@ -307,14 +372,16 @@ pub fn translate( |
| 307 | 372 | .global_scope = try arena.allocator.create(Scope.Root), |
| 308 | 373 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, |
| 309 | 374 | .global_names = std.StringHashMap(void).init(gpa), |
| 310 | | .tokens = .{}, |
| 375 | .token_ids = .{}, |
| 376 | .token_locs = .{}, |
| 311 | 377 | .errors = .{}, |
| 312 | 378 | .root_decls = .{}, |
| 313 | 379 | }; |
| 314 | 380 | context.global_scope.* = Scope.Root.init(&context); |
| 315 | 381 | defer context.decl_table.deinit(); |
| 316 | 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 | 385 | defer context.errors.deinit(gpa); |
| 319 | 386 | defer context.global_names.deinit(); |
| 320 | 387 | defer context.root_decls.deinit(gpa); |
| ... | ... | @@ -349,7 +416,8 @@ pub fn translate( |
| 349 | 416 | tree.* = .{ |
| 350 | 417 | .gpa = gpa, |
| 351 | 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 | 421 | .errors = context.errors.toOwnedSlice(gpa), |
| 354 | 422 | .root_node = root_node, |
| 355 | 423 | .arena = arena.state, |
| ... | ... | @@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 508 | 576 | |
| 509 | 577 | // actual function definition with body |
| 510 | 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 | 581 | var scope = &block_scope.base; |
| 513 | | const block_node = try transCreateNodeBlock(rp.c, null); |
| 514 | | block_scope.setBlockNode(block_node); |
| 515 | 582 | |
| 516 | 583 | var param_id: c_uint = 0; |
| 517 | 584 | for (proto_node.params()) |param, i| { |
| ... | ... | @@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 541 | 608 | node.eq_token = try appendToken(c, .Equal, "="); |
| 542 | 609 | node.init_node = try transCreateNodeIdentifier(c, arg_name); |
| 543 | 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 | 612 | param.name_token = try appendIdentifier(c, arg_name); |
| 546 | 613 | _ = try appendToken(c, .Colon, ":"); |
| 547 | 614 | } |
| ... | ... | @@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 549 | 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 | 621 | error.OutOfMemory => |e| return e, |
| 554 | 622 | error.UnsupportedTranslation, |
| 555 | 623 | error.UnsupportedType, |
| 556 | 624 | => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}), |
| 557 | 625 | }; |
| 558 | | block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 559 | | proto_node.body_node = &block_node.base; |
| 626 | proto_node.body_node = try block_scope.complete(rp.c); |
| 560 | 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 | 1066 | // At this point we can rely on the enum emitting successfully. |
| 1000 | 1067 | const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name); |
| 1001 | 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 | 1070 | const enum_ident = try transCreateNodeIdentifier(c, name); |
| 1004 | 1071 | const period_tok = try appendToken(c, .Period, "."); |
| 1005 | 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 | 1077 | .op = .Period, |
| 1011 | 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 | 1081 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1015 | 1082 | tld_node.init_node = &cast_node.base; |
| 1016 | 1083 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| ... | ... | @@ -1104,7 +1171,7 @@ fn transStmt( |
| 1104 | 1171 | .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)), |
| 1105 | 1172 | .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)), |
| 1106 | 1173 | .NullStmtClass => { |
| 1107 | | const block = try transCreateNodeBlock(rp.c, null); |
| 1174 | const block = try rp.c.createBlock(null, 0); |
| 1108 | 1175 | block.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 1109 | 1176 | return &block.base; |
| 1110 | 1177 | }, |
| ... | ... | @@ -1170,27 +1237,23 @@ fn transBinaryOperator( |
| 1170 | 1237 | .Comma => { |
| 1171 | 1238 | const block_scope = try scope.findBlockScope(rp.c); |
| 1172 | 1239 | const expr = block_scope.base.parent == scope; |
| 1173 | | const lparen = if (expr) blk: { |
| 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; |
| 1240 | const lparen = if (expr) try appendToken(rp.c, .LParen, "(") else undefined; |
| 1178 | 1241 | |
| 1179 | 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 | 1245 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1183 | 1246 | if (expr) { |
| 1184 | 1247 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1185 | 1248 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 1186 | 1249 | break_node.rhs = rhs; |
| 1187 | | try block_scope.block_node.statements.push(&break_node.base); |
| 1188 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 1250 | try block_scope.statements.append(&break_node.base); |
| 1251 | const block_node = try block_scope.complete(rp.c); |
| 1189 | 1252 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 1190 | 1253 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 1191 | 1254 | grouped_expr.* = .{ |
| 1192 | 1255 | .lparen = lparen, |
| 1193 | | .expr = &block_scope.block_node.base, |
| 1256 | .expr = &block_node.base, |
| 1194 | 1257 | .rparen = rparen, |
| 1195 | 1258 | }; |
| 1196 | 1259 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); |
| ... | ... | @@ -1201,11 +1264,11 @@ fn transBinaryOperator( |
| 1201 | 1264 | .Div => { |
| 1202 | 1265 | if (cIsSignedInteger(qt)) { |
| 1203 | 1266 | // signed integer division uses @divTrunc |
| 1204 | | const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc"); |
| 1205 | | try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); |
| 1267 | const div_trunc_node = try rp.c.createBuiltinCall("@divTrunc", 2); |
| 1268 | div_trunc_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 1206 | 1269 | _ = try appendToken(rp.c, .Comma, ","); |
| 1207 | 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 | 1272 | div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1210 | 1273 | return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base); |
| 1211 | 1274 | } |
| ... | ... | @@ -1213,11 +1276,11 @@ fn transBinaryOperator( |
| 1213 | 1276 | .Rem => { |
| 1214 | 1277 | if (cIsSignedInteger(qt)) { |
| 1215 | 1278 | // signed integer division uses @rem |
| 1216 | | const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem"); |
| 1217 | | try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value)); |
| 1279 | const rem_node = try rp.c.createBuiltinCall("@rem", 2); |
| 1280 | rem_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); |
| 1218 | 1281 | _ = try appendToken(rp.c, .Comma, ","); |
| 1219 | 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 | 1284 | rem_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1222 | 1285 | return maybeSuppressResult(rp, scope, result_used, &rem_node.base); |
| 1223 | 1286 | } |
| ... | ... | @@ -1321,15 +1384,15 @@ fn transBinaryOperator( |
| 1321 | 1384 | const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1322 | 1385 | |
| 1323 | 1386 | const lhs = if (isBoolRes(lhs_node)) init: { |
| 1324 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1325 | | try cast_node.params.push(lhs_node); |
| 1387 | const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1388 | cast_node.params()[0] = lhs_node; |
| 1326 | 1389 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1327 | 1390 | break :init &cast_node.base; |
| 1328 | 1391 | } else lhs_node; |
| 1329 | 1392 | |
| 1330 | 1393 | const rhs = if (isBoolRes(rhs_node)) init: { |
| 1331 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1332 | | try cast_node.params.push(rhs_node); |
| 1394 | const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1395 | cast_node.params()[0] = rhs_node; |
| 1333 | 1396 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1334 | 1397 | break :init &cast_node.base; |
| 1335 | 1398 | } else rhs_node; |
| ... | ... | @@ -1341,23 +1404,22 @@ fn transCompoundStmtInline( |
| 1341 | 1404 | rp: RestorePoint, |
| 1342 | 1405 | parent_scope: *Scope, |
| 1343 | 1406 | stmt: *const ZigClangCompoundStmt, |
| 1344 | | block_node: *ast.Node.Block, |
| 1407 | block: *Scope.Block, |
| 1345 | 1408 | ) TransError!void { |
| 1346 | 1409 | var it = ZigClangCompoundStmt_body_begin(stmt); |
| 1347 | 1410 | const end_it = ZigClangCompoundStmt_body_end(stmt); |
| 1348 | 1411 | while (it != end_it) : (it += 1) { |
| 1349 | 1412 | const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value); |
| 1350 | | if (result != &block_node.base) |
| 1351 | | try block_node.statements.push(result); |
| 1413 | try block.statements.append(result); |
| 1352 | 1414 | } |
| 1353 | 1415 | } |
| 1354 | 1416 | |
| 1355 | 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); |
| 1357 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, null)); |
| 1358 | | try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node); |
| 1359 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 1360 | | return &block_scope.block_node.base; |
| 1418 | var block_scope = try Scope.Block.init(rp.c, scope, null); |
| 1419 | defer block_scope.deinit(); |
| 1420 | try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope); |
| 1421 | const node = block_scope.complete(c); |
| 1422 | return &node.base; |
| 1361 | 1423 | } |
| 1362 | 1424 | |
| 1363 | 1425 | fn transCStyleCastExprClass( |
| ... | ... | @@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) |
| 1411 | 1473 | else |
| 1412 | 1474 | try transCreateNodeUndefinedLiteral(c); |
| 1413 | 1475 | if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) { |
| 1414 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1415 | | try builtin_node.params.push(init_node); |
| 1476 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1477 | builtin_node.params()[0] = init_node; |
| 1416 | 1478 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1417 | 1479 | init_node = &builtin_node.base; |
| 1418 | 1480 | } |
| 1419 | 1481 | node.init_node = init_node; |
| 1420 | 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 | 1485 | .Typedef => { |
| 1424 | 1486 | const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]); |
| ... | ... | @@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) |
| 1437 | 1499 | }); |
| 1438 | 1500 | } else { |
| 1439 | 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 | 1505 | else => |kind| return revertAndWarn( |
| ... | ... | @@ -1499,8 +1561,8 @@ fn transImplicitCastExpr( |
| 1499 | 1561 | }, |
| 1500 | 1562 | .PointerToBoolean => { |
| 1501 | 1563 | // @ptrToInt(val) != 0 |
| 1502 | | const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 1503 | | try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value)); |
| 1564 | const ptr_to_int = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 1565 | ptr_to_int.params()[0] = try transExpr(rp, scope, sub_expr, .used, .r_value); |
| 1504 | 1566 | ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1505 | 1567 | |
| 1506 | 1568 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| ... | ... | @@ -1724,13 +1786,11 @@ fn transIntegerLiteral( |
| 1724 | 1786 | |
| 1725 | 1787 | // @as(T, x) |
| 1726 | 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 | 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 | 1792 | _ = try appendToken(rp.c, .Comma, ","); |
| 1731 | | |
| 1732 | | const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); |
| 1733 | | try as_node.params.push(int_lit_node); |
| 1793 | as_node.params()[1] = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); |
| 1734 | 1794 | |
| 1735 | 1795 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1736 | 1796 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); |
| ... | ... | @@ -1840,35 +1900,35 @@ fn transCCast( |
| 1840 | 1900 | // 2. Bit-cast to correct signed-ness |
| 1841 | 1901 | |
| 1842 | 1902 | // @bitCast(dest_type, intermediate_value) |
| 1843 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); |
| 1844 | | try cast_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1903 | const cast_node = try rp.c.createBuiltinCall("@bitCast", 2); |
| 1904 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1845 | 1905 | _ = try appendToken(rp.c, .Comma, ","); |
| 1846 | 1906 | |
| 1847 | 1907 | switch (cIntTypeCmp(dst_type, src_type)) { |
| 1848 | 1908 | .lt => { |
| 1849 | 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 | 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 | 1913 | _ = try appendToken(rp.c, .Comma, ","); |
| 1854 | | try trunc_node.params.push(expr); |
| 1914 | trunc_node.params()[1] = expr; |
| 1855 | 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 | 1919 | .gt => { |
| 1860 | 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 | 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 | 1924 | _ = try appendToken(rp.c, .Comma, ","); |
| 1865 | | try as_node.params.push(expr); |
| 1925 | as_node.params()[1] = expr; |
| 1866 | 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 | 1930 | .eq => { |
| 1871 | | try cast_node.params.push(expr); |
| 1931 | cast_node.params()[1] = expr; |
| 1872 | 1932 | }, |
| 1873 | 1933 | } |
| 1874 | 1934 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -1876,46 +1936,46 @@ fn transCCast( |
| 1876 | 1936 | } |
| 1877 | 1937 | if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 1878 | 1938 | // @intCast(dest_type, @ptrToInt(val)) |
| 1879 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); |
| 1880 | | try cast_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1939 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1940 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1881 | 1941 | _ = try appendToken(rp.c, .Comma, ","); |
| 1882 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 1883 | | try builtin_node.params.push(expr); |
| 1942 | const builtin_node = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 1943 | builtin_node.params()[0] = expr; |
| 1884 | 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 | 1946 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1887 | 1947 | return &cast_node.base; |
| 1888 | 1948 | } |
| 1889 | 1949 | if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| 1890 | 1950 | // @intToPtr(dest_type, val) |
| 1891 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); |
| 1892 | | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1951 | const builtin_node = try rp.c.createBuiltinCall("@intToPtr", 2); |
| 1952 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1893 | 1953 | _ = try appendToken(rp.c, .Comma, ","); |
| 1894 | | try builtin_node.params.push(expr); |
| 1954 | builtin_node.params()[1] = expr; |
| 1895 | 1955 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1896 | 1956 | return &builtin_node.base; |
| 1897 | 1957 | } |
| 1898 | 1958 | if (cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1899 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast"); |
| 1900 | | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1959 | const builtin_node = try rp.c.createBuiltinCall("@floatCast", 2); |
| 1960 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1901 | 1961 | _ = try appendToken(rp.c, .Comma, ","); |
| 1902 | | try builtin_node.params.push(expr); |
| 1962 | builtin_node.params()[1] = expr; |
| 1903 | 1963 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1904 | 1964 | return &builtin_node.base; |
| 1905 | 1965 | } |
| 1906 | 1966 | if (cIsFloating(src_type) and !cIsFloating(dst_type)) { |
| 1907 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt"); |
| 1908 | | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1967 | const builtin_node = try rp.c.createBuiltinCall("@floatToInt", 2); |
| 1968 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1909 | 1969 | _ = try appendToken(rp.c, .Comma, ","); |
| 1910 | | try builtin_node.params.push(expr); |
| 1970 | builtin_node.params()[1] = expr; |
| 1911 | 1971 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1912 | 1972 | return &builtin_node.base; |
| 1913 | 1973 | } |
| 1914 | 1974 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 1915 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat"); |
| 1916 | | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1975 | const builtin_node = try rp.c.createBuiltinCall("@intToFloat", 2); |
| 1976 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1917 | 1977 | _ = try appendToken(rp.c, .Comma, ","); |
| 1918 | | try builtin_node.params.push(expr); |
| 1978 | builtin_node.params()[1] = expr; |
| 1919 | 1979 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1920 | 1980 | return &builtin_node.base; |
| 1921 | 1981 | } |
| ... | ... | @@ -1923,54 +1983,54 @@ fn transCCast( |
| 1923 | 1983 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) |
| 1924 | 1984 | { |
| 1925 | 1985 | // @boolToInt returns either a comptime_int or a u1 |
| 1926 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1927 | | try builtin_node.params.push(expr); |
| 1986 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 1987 | builtin_node.params()[0] = expr; |
| 1928 | 1988 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1929 | 1989 | |
| 1930 | | const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); |
| 1931 | | try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1")); |
| 1990 | const inner_cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1991 | inner_cast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "u1"); |
| 1932 | 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 | 1994 | inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1935 | 1995 | |
| 1936 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); |
| 1937 | | try cast_node.params.push(try transQualType(rp, dst_type, loc)); |
| 1996 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 1997 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1938 | 1998 | _ = try appendToken(rp.c, .Comma, ","); |
| 1939 | 1999 | |
| 1940 | 2000 | if (cIsSignedInteger(dst_type)) { |
| 1941 | | const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); |
| 1942 | | try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1")); |
| 2001 | const bitcast_node = try rp.c.createBuiltinCall("@bitCast", 2); |
| 2002 | bitcast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "i1"); |
| 1943 | 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 | 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 | 2007 | } else { |
| 1948 | | try cast_node.params.push(&inner_cast_node.base); |
| 2008 | cast_node.params()[1] = &inner_cast_node.base; |
| 1949 | 2009 | } |
| 1950 | 2010 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1951 | 2011 | |
| 1952 | 2012 | return &cast_node.base; |
| 1953 | 2013 | } |
| 1954 | 2014 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { |
| 1955 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); |
| 1956 | | try builtin_node.params.push(try transQualType(rp, dst_type, loc)); |
| 2015 | const builtin_node = try rp.c.createBuiltinCall("@intToEnum", 2); |
| 2016 | builtin_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1957 | 2017 | _ = try appendToken(rp.c, .Comma, ","); |
| 1958 | | try builtin_node.params.push(expr); |
| 2018 | builtin_node.params()[1] = expr; |
| 1959 | 2019 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1960 | 2020 | return &builtin_node.base; |
| 1961 | 2021 | } |
| 1962 | 2022 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and |
| 1963 | 2023 | ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum) |
| 1964 | 2024 | { |
| 1965 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); |
| 1966 | | try builtin_node.params.push(expr); |
| 2025 | const builtin_node = try rp.c.createBuiltinCall("@enumToInt", 1); |
| 2026 | builtin_node.params()[0] = expr; |
| 1967 | 2027 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1968 | 2028 | return &builtin_node.base; |
| 1969 | 2029 | } |
| 1970 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); |
| 1971 | | try cast_node.params.push(try transQualType(rp, dst_type, loc)); |
| 2030 | const cast_node = try rp.c.createBuiltinCall("@as", 2); |
| 2031 | cast_node.params()[0] = try transQualType(rp, dst_type, loc); |
| 1972 | 2032 | _ = try appendToken(rp.c, .Comma, ","); |
| 1973 | | try cast_node.params.push(expr); |
| 2033 | cast_node.params()[1] = expr; |
| 1974 | 2034 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1975 | 2035 | return &cast_node.base; |
| 1976 | 2036 | } |
| ... | ... | @@ -2077,12 +2137,13 @@ fn transInitListExprRecord( |
| 2077 | 2137 | |
| 2078 | 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 | 2141 | node.* = .{ |
| 2082 | 2142 | .lhs = ty, |
| 2083 | 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 | 2147 | return &node.base; |
| 2087 | 2148 | } |
| 2088 | 2149 | |
| ... | ... | @@ -2292,11 +2353,15 @@ fn transIfStmt( |
| 2292 | 2353 | // if (c) t else e |
| 2293 | 2354 | const if_node = try transCreateNodeIf(rp.c); |
| 2294 | 2355 | |
| 2295 | | var cond_scope = Scope{ |
| 2296 | | .parent = scope, |
| 2297 | | .id = .Condition, |
| 2356 | var cond_scope = Scope.Condition{ |
| 2357 | .base = .{ |
| 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 | 2365 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2301 | 2366 | |
| 2302 | 2367 | if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value); |
| ... | ... | @@ -2316,11 +2381,15 @@ fn transWhileLoop( |
| 2316 | 2381 | ) TransError!*ast.Node { |
| 2317 | 2382 | const while_node = try transCreateNodeWhile(rp.c); |
| 2318 | 2383 | |
| 2319 | | var cond_scope = Scope{ |
| 2320 | | .parent = scope, |
| 2321 | | .id = .Condition, |
| 2384 | var cond_scope = Scope.Condition{ |
| 2385 | .base = .{ |
| 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 | 2393 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2325 | 2394 | |
| 2326 | 2395 | var loop_scope = Scope{ |
| ... | ... | @@ -2349,12 +2418,15 @@ fn transDoWhileLoop( |
| 2349 | 2418 | |
| 2350 | 2419 | // if (!cond) break; |
| 2351 | 2420 | const if_node = try transCreateNodeIf(rp.c); |
| 2352 | | var cond_scope = Scope{ |
| 2353 | | .parent = scope, |
| 2354 | | .id = .Condition, |
| 2421 | var cond_scope = Scope.Condition{ |
| 2422 | .base = .{ |
| 2423 | .parent = scope, |
| 2424 | .id = .Condition, |
| 2425 | }, |
| 2355 | 2426 | }; |
| 2427 | defer cond_scope.deinit(); |
| 2356 | 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 | 2430 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2359 | 2431 | if_node.condition = &prefix_op.base; |
| 2360 | 2432 | if_node.body = &(try transCreateNodeBreak(rp.c, null)).base; |
| ... | ... | @@ -2404,24 +2476,26 @@ fn transForLoop( |
| 2404 | 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 | 2482 | if (ZigClangForStmt_getInit(stmt)) |init| { |
| 2409 | 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 | 2484 | loop_scope.parent = &block_scope.?.base; |
| 2413 | 2485 | const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); |
| 2414 | | if (result != &block.base) |
| 2415 | | try block.statements.push(result); |
| 2486 | try block_scope.statements.push(result); |
| 2416 | 2487 | } |
| 2417 | | var cond_scope = Scope{ |
| 2418 | | .parent = scope, |
| 2419 | | .id = .Condition, |
| 2488 | var cond_scope = Scope.Condition{ |
| 2489 | .base = .{ |
| 2490 | .parent = scope, |
| 2491 | .id = .Condition, |
| 2492 | }, |
| 2420 | 2493 | }; |
| 2494 | defer cond_scope.deinit(); |
| 2421 | 2495 | |
| 2422 | 2496 | const while_node = try transCreateNodeWhile(rp.c); |
| 2423 | 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 | 2499 | else |
| 2426 | 2500 | try transCreateNodeBoolLiteral(rp.c, true); |
| 2427 | 2501 | _ = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -2429,62 +2503,90 @@ fn transForLoop( |
| 2429 | 2503 | if (ZigClangForStmt_getInc(stmt)) |incr| { |
| 2430 | 2504 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2431 | 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 | 2507 | _ = try appendToken(rp.c, .RParen, ")"); |
| 2434 | 2508 | } |
| 2435 | 2509 | |
| 2436 | 2510 | while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value); |
| 2437 | | if (block_scope != null) { |
| 2438 | | try block_scope.?.block_node.statements.push(&while_node.base); |
| 2439 | | block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2440 | | return &block_scope.?.block_node.base; |
| 2511 | if (block_scope) |*bs| { |
| 2512 | try bs.statements.push(&while_node.base); |
| 2513 | const node = bs.complete(rp.c); |
| 2514 | return &node.base; |
| 2441 | 2515 | } else { |
| 2442 | 2516 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2443 | 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 | 2527 | fn transSwitch( |
| 2448 | 2528 | rp: RestorePoint, |
| 2449 | 2529 | scope: *Scope, |
| 2450 | 2530 | stmt: *const ZigClangSwitchStmt, |
| 2451 | 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 | 2556 | var switch_scope = Scope.Switch{ |
| 2454 | 2557 | .base = .{ |
| 2455 | 2558 | .id = .Switch, |
| 2456 | 2559 | .parent = scope, |
| 2457 | 2560 | }, |
| 2458 | | .cases = &switch_node.cases, |
| 2561 | .cases = switch_node.cases(), |
| 2562 | .case_index = 0, |
| 2459 | 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 | 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); |
| 2474 | | block_scope.setBlockNode(block); |
| 2567 | var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null); |
| 2568 | defer block_scope.deinit(); |
| 2475 | 2569 | |
| 2476 | | const switch_block = try transCreateNodeBlock(rp.c, null); |
| 2477 | | try switch_block.statements.push(&switch_node.base); |
| 2478 | | switch_scope.pending_block = switch_block; |
| 2570 | // Note that we do not defer a deinit here; the switch_scope.pending_block field |
| 2571 | // has its own memory management. This resource is freed inside `transCase` and |
| 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 | 2578 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2482 | 2579 | |
| 2483 | 2580 | // take all pending statements |
| 2484 | | var it = last.cast(ast.Node.Block).?.statements.iterator(0); |
| 2485 | | while (it.next()) |n| { |
| 2486 | | try switch_scope.pending_block.statements.push(n.*); |
| 2487 | | } |
| 2581 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2582 | // TODO delete the following commented out code |
| 2583 | //const last_block_stmts = last.cast(ast.Node.Block).?.statements(); |
| 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 | 2591 | switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch"); |
| 2490 | 2592 | _ = try appendToken(rp.c, .Colon, ":"); |
| ... | ... | @@ -2492,10 +2594,16 @@ fn transSwitch( |
| 2492 | 2594 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2493 | 2595 | else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base; |
| 2494 | 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, "}"); |
| 2498 | | return &switch_scope.pending_block.base; |
| 2600 | // We overallocated in case there was no default, so now we correct |
| 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 | 2609 | fn transCase( |
| ... | ... | @@ -2527,22 +2635,21 @@ fn transCase( |
| 2527 | 2635 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); |
| 2528 | 2636 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; |
| 2529 | 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 | 2641 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); |
| 2534 | 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 | 2644 | // take all pending statements |
| 2539 | | var it = block_scope.block_node.statements.iterator(0); |
| 2540 | | while (it.next()) |n| { |
| 2541 | | try switch_scope.pending_block.statements.push(n.*); |
| 2542 | | } |
| 2543 | | block_scope.block_node.statements.shrink(0); |
| 2645 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2646 | block_scope.statements.shrink(0); |
| 2647 | |
| 2648 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 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 | 2654 | return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value); |
| 2548 | 2655 | } |
| ... | ... | @@ -2561,22 +2668,21 @@ fn transDefault( |
| 2561 | 2668 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2562 | 2669 | else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base; |
| 2563 | 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 | 2674 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); |
| 2568 | 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 | 2677 | // take all pending statements |
| 2573 | | var it = block_scope.block_node.statements.iterator(0); |
| 2574 | | while (it.next()) |n| { |
| 2575 | | try switch_scope.pending_block.statements.push(n.*); |
| 2576 | | } |
| 2577 | | block_scope.block_node.statements.shrink(0); |
| 2678 | try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items); |
| 2679 | block_scope.statements.shrink(0); |
| 2680 | |
| 2681 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 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 | 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 | 2697 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2592 | 2698 | // @as(T, x) |
| 2593 | 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 | 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 | 2703 | _ = try appendToken(rp.c, .Comma, ","); |
| 2598 | 2704 | |
| 2599 | 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 | 2708 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2603 | 2709 | |
| ... | ... | @@ -2653,12 +2759,11 @@ fn transCharLiteral( |
| 2653 | 2759 | // See comment in `transIntegerLiteral` for why this code is here. |
| 2654 | 2760 | // @as(T, x) |
| 2655 | 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 | 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 | 2765 | _ = try appendToken(rp.c, .Comma, ","); |
| 2660 | | |
| 2661 | | try as_node.params.push(int_lit_node); |
| 2766 | as_node.params()[1] = int_lit_node; |
| 2662 | 2767 | |
| 2663 | 2768 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2664 | 2769 | return maybeSuppressResult(rp, scope, result_used, &as_node.base); |
| ... | ... | @@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, |
| 2671 | 2776 | } |
| 2672 | 2777 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 2673 | 2778 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2674 | | const block = try transCreateNodeBlock(rp.c, "blk"); |
| 2675 | | block_scope.setBlockNode(block); |
| 2779 | defer block_scope.deinit(); |
| 2676 | 2780 | |
| 2677 | 2781 | var it = ZigClangCompoundStmt_body_begin(comp); |
| 2678 | 2782 | const end_it = ZigClangCompoundStmt_body_end(comp); |
| 2679 | 2783 | while (it != end_it - 1) : (it += 1) { |
| 2680 | 2784 | const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value); |
| 2681 | | if (result != &block.base) |
| 2682 | | try block.statements.push(result); |
| 2785 | try block_scope.statements.append(result); |
| 2683 | 2786 | } |
| 2684 | 2787 | const break_node = try transCreateNodeBreak(rp.c, "blk"); |
| 2685 | 2788 | break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value); |
| 2686 | 2789 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2687 | | try block.statements.push(&break_node.base); |
| 2688 | | block.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 2790 | try block_scope.statements.append(&break_node.base); |
| 2791 | const block_node = try block_scope.complete(rp.c); |
| 2689 | 2792 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| 2690 | 2793 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 2691 | 2794 | grouped_expr.* = .{ |
| 2692 | 2795 | .lparen = lparen, |
| 2693 | | .expr = &block.base, |
| 2796 | .expr = &block_node.base, |
| 2694 | 2797 | .rparen = rparen, |
| 2695 | 2798 | }; |
| 2696 | 2799 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| ... | ... | @@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS |
| 2746 | 2849 | const is_signed = cIsSignedInteger(qt); |
| 2747 | 2850 | |
| 2748 | 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 | 2853 | // check if long long first so that signed long long doesn't just become unsigned long long |
| 2751 | 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 | 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 | 2858 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2756 | 2859 | node.rtoken = try appendToken(rp.c, .RBrace, "]"); |
| 2757 | 2860 | node.op.ArrayAccess = &cast_node.base; |
| ... | ... | @@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, |
| 2787 | 2890 | break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr); |
| 2788 | 2891 | } else |
| 2789 | 2892 | raw_fn_expr; |
| 2790 | | const node = try transCreateNodeFnCall(rp.c, fn_expr); |
| 2791 | 2893 | |
| 2792 | 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 | 2898 | const args = ZigClangCallExpr_getArgs(stmt); |
| 2794 | 2899 | var i: usize = 0; |
| 2795 | 2900 | while (i < num_args) : (i += 1) { |
| 2796 | 2901 | if (i != 0) { |
| 2797 | 2902 | _ = try appendToken(rp.c, .Comma, ","); |
| 2798 | 2903 | } |
| 2799 | | const arg = try transExpr(rp, scope, args[i], .used, .r_value); |
| 2800 | | try node.op.Call.params.push(arg); |
| 2904 | call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value); |
| 2801 | 2905 | } |
| 2802 | 2906 | node.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 2803 | 2907 | |
| ... | ... | @@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr( |
| 2856 | 2960 | ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt), |
| 2857 | 2961 | ); |
| 2858 | 2962 | |
| 2859 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@sizeOf"); |
| 2860 | | try builtin_node.params.push(type_node); |
| 2963 | const builtin_node = try rp.c.createBuiltinCall("@sizeOf", 1); |
| 2964 | builtin_node.params()[0] = type_node; |
| 2861 | 2965 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2862 | 2966 | return maybeSuppressResult(rp, scope, result_used, &builtin_node.base); |
| 2863 | 2967 | } |
| ... | ... | @@ -2966,8 +3070,8 @@ fn transCreatePreCrement( |
| 2966 | 3070 | // zig: _ref.* += 1; |
| 2967 | 3071 | // zig: break :blk _ref.* |
| 2968 | 3072 | // zig: }) |
| 2969 | | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 2970 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); |
| 3073 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3074 | defer block_scope.deinit(); |
| 2971 | 3075 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 2972 | 3076 | |
| 2973 | 3077 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | ... | @@ -2976,7 +3080,7 @@ fn transCreatePreCrement( |
| 2976 | 3080 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 2977 | 3081 | node.init_node = &rhs_node.base; |
| 2978 | 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 | 3085 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 2982 | 3086 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | ... | @@ -2985,18 +3089,18 @@ fn transCreatePreCrement( |
| 2985 | 3089 | const one = try transCreateNodeInt(rp.c, 1); |
| 2986 | 3090 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2987 | 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 | 3094 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 2991 | 3095 | break_node.rhs = ref_node; |
| 2992 | | try block_scope.block_node.statements.push(&break_node.base); |
| 2993 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 3096 | try block_scope.statements.push(&break_node.base); |
| 3097 | const block_node = try block_scope.complete(rp.c); |
| 2994 | 3098 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 2995 | 3099 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2996 | 3100 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 2997 | 3101 | grouped_expr.* = .{ |
| 2998 | 3102 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 2999 | | .expr = &block_scope.block_node.base, |
| 3103 | .expr = &block_node.base, |
| 3000 | 3104 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3001 | 3105 | }; |
| 3002 | 3106 | return &grouped_expr.base; |
| ... | ... | @@ -3032,8 +3136,8 @@ fn transCreatePostCrement( |
| 3032 | 3136 | // zig: _ref.* += 1; |
| 3033 | 3137 | // zig: break :blk _tmp |
| 3034 | 3138 | // zig: }) |
| 3035 | | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3036 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); |
| 3139 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3140 | defer block_scope.deinit(); |
| 3037 | 3141 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3038 | 3142 | |
| 3039 | 3143 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | ... | @@ -3042,7 +3146,7 @@ fn transCreatePostCrement( |
| 3042 | 3146 | rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value); |
| 3043 | 3147 | node.init_node = &rhs_node.base; |
| 3044 | 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 | 3151 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 3048 | 3152 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | ... | @@ -3053,23 +3157,23 @@ fn transCreatePostCrement( |
| 3053 | 3157 | tmp_node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3054 | 3158 | tmp_node.init_node = ref_node; |
| 3055 | 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 | 3162 | const token = try appendToken(rp.c, op_tok_id, bytes); |
| 3059 | 3163 | const one = try transCreateNodeInt(rp.c, 1); |
| 3060 | 3164 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3061 | 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 | 3168 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3065 | 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 | 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 | 3173 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3070 | 3174 | grouped_expr.* = .{ |
| 3071 | 3175 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 3072 | | .expr = &block_scope.block_node.base, |
| 3176 | .expr = &block_node.base, |
| 3073 | 3177 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3074 | 3178 | }; |
| 3075 | 3179 | return &grouped_expr.base; |
| ... | ... | @@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign( |
| 3134 | 3238 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 3135 | 3239 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); |
| 3136 | 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 | 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 | 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 | 3246 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3143 | 3247 | op_node.* = .{ |
| 3144 | 3248 | .op_token = op_token, |
| ... | ... | @@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign( |
| 3158 | 3262 | try transExpr(rp, scope, rhs, .used, .r_value); |
| 3159 | 3263 | |
| 3160 | 3264 | if (is_shift) { |
| 3161 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); |
| 3265 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3162 | 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 | 3268 | _ = try appendToken(rp.c, .Comma, ","); |
| 3165 | | try cast_node.params.push(rhs_node); |
| 3269 | cast_node.params()[1] = rhs_node; |
| 3166 | 3270 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3167 | 3271 | rhs_node = &cast_node.base; |
| 3168 | 3272 | } |
| ... | ... | @@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign( |
| 3177 | 3281 | // zig: _ref.* = _ref.* + rhs; |
| 3178 | 3282 | // zig: break :blk _ref.* |
| 3179 | 3283 | // zig: }) |
| 3180 | | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3181 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); |
| 3284 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3285 | defer block_scope.deinit(); |
| 3182 | 3286 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3183 | 3287 | |
| 3184 | 3288 | const node = try transCreateNodeVarDecl(rp.c, false, true, ref); |
| ... | ... | @@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign( |
| 3187 | 3291 | addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value); |
| 3188 | 3292 | node.init_node = &addr_node.base; |
| 3189 | 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 | 3296 | const lhs_node = try transCreateNodeIdentifier(rp.c, ref); |
| 3193 | 3297 | const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node); |
| ... | ... | @@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign( |
| 3197 | 3301 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 3198 | 3302 | const op_node = try rp.c.arena.create(ast.Node.InfixOp); |
| 3199 | 3303 | const builtin = if (is_mod) "@rem" else "@divTrunc"; |
| 3200 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin); |
| 3201 | | try builtin_node.params.push(try transCreateNodePtrDeref(rp.c, lhs_node)); |
| 3304 | const builtin_node = try rp.c.createBuiltinCall(builtin, 2); |
| 3305 | builtin_node.params()[0] = try transCreateNodePtrDeref(rp.c, lhs_node); |
| 3202 | 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 | 3308 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3205 | 3309 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3206 | 3310 | op_node.* = .{ |
| ... | ... | @@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign( |
| 3210 | 3314 | .rhs = &builtin_node.base, |
| 3211 | 3315 | }; |
| 3212 | 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 | 3318 | } else { |
| 3215 | 3319 | const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes); |
| 3216 | 3320 | var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); |
| 3217 | 3321 | |
| 3218 | 3322 | if (is_shift) { |
| 3219 | | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); |
| 3323 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3220 | 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 | 3326 | _ = try appendToken(rp.c, .Comma, ","); |
| 3223 | | try cast_node.params.push(rhs_node); |
| 3327 | cast_node.params()[1] = rhs_node; |
| 3224 | 3328 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3225 | 3329 | rhs_node = &cast_node.base; |
| 3226 | 3330 | } |
| ... | ... | @@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign( |
| 3230 | 3334 | |
| 3231 | 3335 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| 3232 | 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 | 3340 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3237 | 3341 | break_node.rhs = ref_node; |
| 3238 | | try block_scope.block_node.statements.push(&break_node.base); |
| 3239 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 3342 | try block_scope.statements.append(&break_node.base); |
| 3343 | const block_node = try block_scope.complete(rp.c); |
| 3240 | 3344 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3241 | 3345 | grouped_expr.* = .{ |
| 3242 | 3346 | .lparen = try appendToken(rp.c, .LParen, "("), |
| 3243 | | .expr = &block_scope.block_node.base, |
| 3347 | .expr = &block_node.base, |
| 3244 | 3348 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3245 | 3349 | }; |
| 3246 | 3350 | return &grouped_expr.base; |
| ... | ... | @@ -3264,43 +3368,43 @@ fn transCPtrCast( |
| 3264 | 3368 | !ZigClangQualType_isVolatileQualified(child_type))) |
| 3265 | 3369 | { |
| 3266 | 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 | 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 | 3374 | _ = try appendToken(rp.c, .Comma, ","); |
| 3271 | 3375 | |
| 3272 | | const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 3273 | | try ptrtoint_node.params.push(expr); |
| 3376 | const ptrtoint_node = try rp.c.createBuiltinCall("@ptrToInt", 1); |
| 3377 | ptrtoint_node.params()[0] = expr; |
| 3274 | 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 | 3381 | inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3278 | 3382 | return &inttoptr_node.base; |
| 3279 | 3383 | } else { |
| 3280 | 3384 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| 3281 | 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 | 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 | 3389 | _ = try appendToken(rp.c, .Comma, ","); |
| 3286 | 3390 | |
| 3287 | 3391 | if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { |
| 3288 | 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 | 3394 | } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) { |
| 3291 | 3395 | // For opaque types a ptrCast is enough |
| 3292 | | try ptrcast_node.params.push(expr); |
| 3396 | ptrcast_node.params()[1] = expr; |
| 3293 | 3397 | } else { |
| 3294 | | const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); |
| 3295 | | const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); |
| 3398 | const aligncast_node = try rp.c.createBuiltinCall("@alignCast", 2); |
| 3399 | const alignof_node = try rp.c.createBuiltinCall("@alignOf", 1); |
| 3296 | 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 | 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 | 3404 | _ = try appendToken(rp.c, .Comma, ","); |
| 3301 | | try aligncast_node.params.push(expr); |
| 3405 | aligncast_node.params()[1] = expr; |
| 3302 | 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 | 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 | 3447 | // }) |
| 3344 | 3448 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 3345 | 3449 | |
| 3346 | | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3347 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); |
| 3450 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3451 | defer block_scope.deinit(); |
| 3348 | 3452 | |
| 3349 | 3453 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); |
| 3350 | 3454 | const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name); |
| 3351 | 3455 | tmp_var.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3352 | 3456 | tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value); |
| 3353 | 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 | 3460 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3357 | 3461 | |
| 3358 | 3462 | const if_node = try transCreateNodeIf(rp.c); |
| 3359 | | var cond_scope = Scope{ |
| 3360 | | .parent = &block_scope.base, |
| 3361 | | .id = .Condition, |
| 3463 | var cond_scope = Scope.Condition{ |
| 3464 | .base = .{ |
| 3465 | .parent = &block_scope.base, |
| 3466 | .id = .Condition, |
| 3467 | }, |
| 3362 | 3468 | }; |
| 3469 | defer cond_scope.deinit(); |
| 3363 | 3470 | const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name); |
| 3364 | 3471 | |
| 3365 | 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 | 3474 | if_node.condition = cond_node; |
| 3368 | 3475 | _ = try appendToken(rp.c, .RParen, ")"); |
| 3369 | 3476 | |
| ... | ... | @@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const |
| 3374 | 3481 | |
| 3375 | 3482 | break_node.rhs = &if_node.base; |
| 3376 | 3483 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3377 | | try block_scope.block_node.statements.push(&break_node.base); |
| 3378 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 3484 | try block_scope.statements.append(&break_node.base); |
| 3485 | const block_node = block_scope.complete(rp.c); |
| 3379 | 3486 | |
| 3380 | 3487 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| 3381 | 3488 | grouped_expr.* = .{ |
| 3382 | 3489 | .lparen = lparen, |
| 3383 | | .expr = &block_scope.block_node.base, |
| 3490 | .expr = &block_node.base, |
| 3384 | 3491 | .rparen = try appendToken(rp.c, .RParen, ")"), |
| 3385 | 3492 | }; |
| 3386 | 3493 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| ... | ... | @@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 3390 | 3497 | const grouped = scope.id == .Condition; |
| 3391 | 3498 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; |
| 3392 | 3499 | const if_node = try transCreateNodeIf(rp.c); |
| 3393 | | var cond_scope = Scope{ |
| 3394 | | .parent = scope, |
| 3395 | | .id = .Condition, |
| 3500 | var cond_scope = Scope.Condition{ |
| 3501 | .base = .{ |
| 3502 | .parent = scope, |
| 3503 | .id = .Condition, |
| 3504 | }, |
| 3396 | 3505 | }; |
| 3506 | defer cond_scope.deinit(); |
| 3397 | 3507 | |
| 3398 | 3508 | const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt); |
| 3399 | 3509 | const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt); |
| 3400 | 3510 | const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt); |
| 3401 | 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 | 3514 | _ = try appendToken(rp.c, .RParen, ")"); |
| 3405 | 3515 | |
| 3406 | 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 | 3681 | // Symbol "Log2Int" |
| 3572 | 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 | 3685 | const std_token = try appendToken(rp.c, .StringLiteral, "\"std\""); |
| 3576 | 3686 | const std_node = try rp.c.arena.create(ast.Node.StringLiteral); |
| 3577 | 3687 | std_node.* = .{ |
| 3578 | 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 | 3691 | import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3582 | 3692 | |
| 3583 | 3693 | const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math"); |
| 3584 | 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); |
| 3586 | | try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node); |
| 3695 | const log2int_fn_call = try rp.c.createCall(outer_field_access, 1); |
| 3696 | log2int_fn_call.params()[0] = zig_type_node; |
| 3587 | 3697 | log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 3588 | 3698 | |
| 3589 | 3699 | return &log2int_fn_call.base; |
| ... | ... | @@ -3757,8 +3867,8 @@ fn transCreateNodeAssign( |
| 3757 | 3867 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| 3758 | 3868 | var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value); |
| 3759 | 3869 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3760 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 3761 | | try builtin_node.params.push(rhs_node); |
| 3870 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 3871 | builtin_node.params()[0] = rhs_node; |
| 3762 | 3872 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3763 | 3873 | rhs_node = &builtin_node.base; |
| 3764 | 3874 | } |
| ... | ... | @@ -3774,22 +3884,23 @@ fn transCreateNodeAssign( |
| 3774 | 3884 | // zig: lhs = _tmp; |
| 3775 | 3885 | // zig: break :blk _tmp |
| 3776 | 3886 | // zig: }) |
| 3777 | | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3778 | | block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label)); |
| 3887 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); |
| 3888 | defer block_scope.deinit(); |
| 3889 | |
| 3779 | 3890 | const tmp = try block_scope.makeMangledName(rp.c, "tmp"); |
| 3780 | 3891 | |
| 3781 | 3892 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); |
| 3782 | 3893 | node.eq_token = try appendToken(rp.c, .Equal, "="); |
| 3783 | 3894 | var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value); |
| 3784 | 3895 | if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) { |
| 3785 | | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 3786 | | try builtin_node.params.push(rhs_node); |
| 3896 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 3897 | builtin_node.params()[0] = rhs_node; |
| 3787 | 3898 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 3788 | 3899 | rhs_node = &builtin_node.base; |
| 3789 | 3900 | } |
| 3790 | 3901 | node.init_node = rhs_node; |
| 3791 | 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 | 3905 | const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value); |
| 3795 | 3906 | const eq_token = try appendToken(rp.c, .Equal, "="); |
| ... | ... | @@ -3797,44 +3908,16 @@ fn transCreateNodeAssign( |
| 3797 | 3908 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3798 | 3909 | |
| 3799 | 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 | 3913 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 3803 | 3914 | break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp); |
| 3804 | 3915 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3805 | | try block_scope.block_node.statements.push(&break_node.base); |
| 3806 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 3916 | try block_scope.statements.append(&break_node.base); |
| 3917 | const block_node = try block_scope.complete(rp.c); |
| 3807 | 3918 | // semicolon must immediately follow rbrace because it is the last token in a block |
| 3808 | 3919 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3809 | | return &block_scope.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; |
| 3920 | return &block_node.base; |
| 3838 | 3921 | } |
| 3839 | 3922 | |
| 3840 | 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 | 4166 | } |
| 4084 | 4167 | |
| 4085 | 4168 | fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { |
| 4086 | | const call_node = try transCreateNodeBuiltinFnCall(c, "@Type"); |
| 4087 | | try call_node.params.push(try transCreateNodeEnumLiteral(c, "Opaque")); |
| 4169 | const call_node = try c.createBuiltinCall("@Type", 1); |
| 4170 | call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque"); |
| 4088 | 4171 | call_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 4089 | 4172 | return &call_node.base; |
| 4090 | 4173 | } |
| ... | ... | @@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 4139 | 4222 | }; |
| 4140 | 4223 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); |
| 4141 | 4224 | |
| 4142 | | const block = try transCreateNodeBlock(c, null); |
| 4143 | | var block_statements_it = &block.statements.first; |
| 4225 | const block_lbrace = try appendToken(c, .LBrace, "{"); |
| 4144 | 4226 | |
| 4145 | 4227 | const return_expr = try transCreateNodeReturnExpr(c); |
| 4146 | 4228 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); |
| 4147 | | const call_expr = try transCreateNodeFnCall(c, unwrap_expr); |
| 4148 | | var call_params_it = &call_expr.op.Call.params.first; |
| 4229 | |
| 4230 | const call_expr = try c.createCall(unwrap_expr, fn_params.items.len); |
| 4231 | const call_params = call_expr.params(); |
| 4149 | 4232 | |
| 4150 | 4233 | for (fn_params.items) |param, i| { |
| 4151 | 4234 | if (i != 0) { |
| 4152 | 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 | 4239 | call_expr.rtoken = try appendToken(c, .RParen, ")"); |
| 4240 | |
| 4157 | 4241 | return_expr.rhs = &call_expr.base; |
| 4158 | 4242 | _ = try appendToken(c, .Semicolon, ";"); |
| 4159 | 4243 | |
| 4160 | | block.rbrace = try appendToken(c, .RBrace, "}"); |
| 4161 | | block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base); |
| 4244 | const block = try ast.Node.Block.alloc(c.arena, 1); |
| 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 | 4252 | fn_proto.body_node = &block.base; |
| 4163 | 4253 | return &fn_proto.base; |
| 4164 | 4254 | } |
| ... | ... | @@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { |
| 4216 | 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 | 4309 | fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression { |
| 4236 | 4310 | const ltoken = try appendToken(c, .Keyword_break, "break"); |
| 4237 | 4311 | const label_node = if (label) |l| blk: { |
| ... | ... | @@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node { |
| 4302 | 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 | 4379 | fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase { |
| 4320 | 4380 | const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>"); |
| 4321 | 4381 | |
| ... | ... | @@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp( |
| 4356 | 4416 | const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value); |
| 4357 | 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 | 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 | 4422 | _ = try appendToken(rp.c, .Comma, ","); |
| 4363 | 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 | 4425 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 4366 | 4426 | |
| 4367 | 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 | 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 | 4896 | call_node.* = .{ |
| 4837 | 4897 | .builtin_token = builtin_tok, |
| 4838 | | .params = ast.Node.BuiltinCall.ParamList{}, |
| 4898 | .params_len = 1, |
| 4839 | 4899 | .rparen_token = rparen_tok, |
| 4840 | 4900 | }; |
| 4841 | | var call_params_it = &call_node.params.first; |
| 4842 | | call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base); |
| 4901 | call_node.params()[0] = &msg_node.base; |
| 4843 | 4902 | |
| 4844 | 4903 | const var_decl_node = try c.arena.create(ast.Node.VarDecl); |
| 4845 | 4904 | var_decl_node.* = .{ |
| ... | ... | @@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd |
| 4868 | 4927 | |
| 4869 | 4928 | fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex { |
| 4870 | 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); |
| 4875 | | const end_index = c.source_buffer.items.len; |
| 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); |
| 4931 | try c.token_ids.ensureCapacity(c.gpa, c.token_ids.items.len + 1); |
| 4932 | try c.token_locs.ensureCapacity(c.gpa, c.token_locs.items.len + 1); |
| 4879 | 4933 | |
| 4880 | | new_token.* = .{ |
| 4881 | | .id = token_id, |
| 4934 | const start_index = c.source_buffer.items.len; |
| 4935 | try c.source_buffer.outStream().print(format ++ " ", args); |
| 4936 | |
| 4937 | c.token_ids.appendAssumeCapacity(token_id); |
| 4938 | c.token_locs.appendAssumeCapacity(.{ |
| 4882 | 4939 | .start = start_index, |
| 4883 | | .end = end_index, |
| 4884 | | }; |
| 4885 | | try c.source_buffer.append(' '); |
| 4940 | .end = c.source_buffer.items.len - 1, // back up before the space |
| 4941 | }); |
| 4886 | 4942 | |
| 4887 | | return token_index; |
| 4943 | return c.token_ids.items.len - 1; |
| 4888 | 4944 | } |
| 4889 | 4945 | |
| 4890 | 4946 | // TODO hook up with codegen |
| ... | ... | @@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n |
| 5072 | 5128 | } |
| 5073 | 5129 | |
| 5074 | 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 | 5133 | const scope = &block_scope.base; |
| 5077 | 5134 | |
| 5078 | 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 | 5199 | |
| 5143 | 5200 | _ = try appendToken(c, .RParen, ")"); |
| 5144 | 5201 | |
| 5145 | | const type_of = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| 5146 | | type_of.rparen_token = try appendToken(c, .RParen, ")"); |
| 5147 | | var type_of_params = c.llpusher(&type_of.params); |
| 5202 | const type_of = try c.createBuiltinCall("@TypeOf", 1); |
| 5148 | 5203 | |
| 5149 | 5204 | const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len); |
| 5150 | 5205 | fn_proto.* = .{ |
| ... | ... | @@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5164 | 5219 | }; |
| 5165 | 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 | 5222 | const return_expr = try transCreateNodeReturnExpr(c); |
| 5171 | 5223 | const expr = try parseCExpr(c, it, source, source_loc, scope); |
| 5172 | 5224 | const last = it.next().?; |
| ... | ... | @@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5186 | 5238 | const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last); |
| 5187 | 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 | 5243 | return_expr.rhs = expr; |
| 5191 | 5244 | |
| 5192 | | block.rbrace = try appendToken(c, .RBrace, "}"); |
| 5193 | | try block_statements.push(&return_expr.base); |
| 5194 | | fn_proto.body_node = &block.base; |
| 5245 | try block_scope.statements.append(&return_expr.base); |
| 5246 | const block_node = try block_scope.complete(c); |
| 5247 | fn_proto.body_node = &block_node.base; |
| 5195 | 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 | 5276 | }, |
| 5224 | 5277 | .Comma => { |
| 5225 | 5278 | _ = try appendToken(c, .Semicolon, ";"); |
| 5226 | | const block_scope = try Scope.Block.init(c, scope, "blk"); |
| 5227 | | block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label)); |
| 5279 | var block_scope = try Scope.Block.init(c, scope, "blk"); |
| 5280 | defer block_scope.deinit(); |
| 5228 | 5281 | |
| 5229 | 5282 | var last = node; |
| 5230 | 5283 | while (true) { |
| ... | ... | @@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ |
| 5238 | 5291 | .op = .Assign, |
| 5239 | 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 | 5296 | last = try parseCPrefixOpExpr(c, it, source, source_loc, scope); |
| 5244 | 5297 | _ = try appendToken(c, .Semicolon, ";"); |
| ... | ... | @@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_ |
| 5250 | 5303 | |
| 5251 | 5304 | const break_node = try transCreateNodeBreak(c, block_scope.label); |
| 5252 | 5305 | break_node.rhs = last; |
| 5253 | | try block_scope.block_node.statements.push(&break_node.base); |
| 5254 | | block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}"); |
| 5255 | | return &block_scope.block_node.base; |
| 5306 | try block_scope.statements.append(&break_node.base); |
| 5307 | const block_node = try block_scope.complete(c); |
| 5308 | return &block_node.base; |
| 5256 | 5309 | }, |
| 5257 | 5310 | else => { |
| 5258 | 5311 | _ = it.prev(); |
| ... | ... | @@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5283 | 5336 | return transCreateNodeInt(c, lit_bytes); |
| 5284 | 5337 | } |
| 5285 | 5338 | |
| 5286 | | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5287 | | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) { |
| 5339 | const cast_node = try c.createBuiltinCall("@as", 2); |
| 5340 | cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) { |
| 5288 | 5341 | .U => "c_uint", |
| 5289 | 5342 | .L => "c_long", |
| 5290 | 5343 | .LU => "c_ulong", |
| 5291 | 5344 | .LL => "c_longlong", |
| 5292 | 5345 | .LLU => "c_ulonglong", |
| 5293 | 5346 | else => unreachable, |
| 5294 | | })); |
| 5347 | }); |
| 5295 | 5348 | lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) { |
| 5296 | 5349 | .U, .L => @as(u8, 1), |
| 5297 | 5350 | .LU, .LL => 2, |
| ... | ... | @@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5299 | 5352 | else => unreachable, |
| 5300 | 5353 | }]; |
| 5301 | 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 | 5356 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5304 | 5357 | return &cast_node.base; |
| 5305 | 5358 | } else if (tok.id == .FloatLiteral) { |
| ... | ... | @@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl |
| 5308 | 5361 | if (tok.id.FloatLiteral == .None) { |
| 5309 | 5362 | return transCreateNodeFloat(c, lit_bytes); |
| 5310 | 5363 | } |
| 5311 | | const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5312 | | try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) { |
| 5364 | const cast_node = try c.createBuiltinCall("@as", 2); |
| 5365 | cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) { |
| 5313 | 5366 | .F => "f32", |
| 5314 | 5367 | .L => "c_longdouble", |
| 5315 | 5368 | else => unreachable, |
| 5316 | | })); |
| 5369 | }); |
| 5317 | 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 | 5372 | cast_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5320 | 5373 | return &cast_node.base; |
| 5321 | 5374 | } else unreachable; |
| ... | ... | @@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5585 | 5638 | //else |
| 5586 | 5639 | // @as(dest, x) ) |
| 5587 | 5640 | const if_node = try transCreateNodeIf(c); |
| 5588 | | const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); |
| 5589 | | try type_info_node.params.push(inner_node); |
| 5641 | const type_info_node = try rp.c.createBuiltinCall("@typeInfo", 1); |
| 5642 | type_info_node.params()[0] = inner_node; |
| 5590 | 5643 | type_info_node.rparen_token = try appendToken(c, .LParen, ")"); |
| 5591 | 5644 | const cmp_node = try c.arena.create(ast.Node.InfixOp); |
| 5592 | 5645 | cmp_node.* = .{ |
| ... | ... | @@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5598 | 5651 | if_node.condition = &cmp_node.base; |
| 5599 | 5652 | _ = try appendToken(c, .RParen, ")"); |
| 5600 | 5653 | |
| 5601 | | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); |
| 5602 | | try int_to_ptr.params.push(inner_node); |
| 5603 | | try int_to_ptr.params.push(node_to_cast); |
| 5654 | const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2); |
| 5655 | int_to_ptr.params()[0] = inner_node; |
| 5656 | int_to_ptr.params()[1] = node_to_cast; |
| 5604 | 5657 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| 5605 | 5658 | if_node.body = &int_to_ptr.base; |
| 5606 | 5659 | |
| 5607 | 5660 | const else_node = try transCreateNodeElse(c); |
| 5608 | 5661 | if_node.@"else" = else_node; |
| 5609 | 5662 | |
| 5610 | | const as_node = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5611 | | try as_node.params.push(inner_node); |
| 5612 | | try as_node.params.push(node_to_cast); |
| 5663 | const as_node = try c.createBuiltinCall("@as", 2); |
| 5664 | as_node.params()[0] = inner_node; |
| 5665 | as_node.params()[1] = node_to_cast; |
| 5613 | 5666 | as_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5614 | 5667 | else_node.body = &as_node.base; |
| 5615 | 5668 | |
| ... | ... | @@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5630 | 5683 | // @as(dest, x) ) |
| 5631 | 5684 | |
| 5632 | 5685 | const if_1 = try transCreateNodeIf(c); |
| 5633 | | const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); |
| 5634 | | const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| 5635 | | try type_info_1.params.push(&type_of_1.base); |
| 5636 | | try type_of_1.params.push(node_to_cast); |
| 5686 | const type_info_1 = try c.createBuiltinCall("@typeInfo", 1); |
| 5687 | const type_of_1 = try c.createBuiltinCall("@TypeOf", 1); |
| 5688 | type_info_1.params()[0] = &type_of_1.base; |
| 5689 | type_of_1.params()[0] = node_to_cast; |
| 5637 | 5690 | type_of_1.rparen_token = try appendToken(c, .RParen, ")"); |
| 5638 | 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 | 5710 | .rhs = child_ident, |
| 5658 | 5711 | }; |
| 5659 | 5712 | |
| 5660 | | const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf"); |
| 5661 | | try align_of.params.push(&inner_node_child.base); |
| 5713 | const align_of = try rp.c.createBuiltinCall("@alignOf", 1); |
| 5714 | align_of.params()[0] = &inner_node_child.base; |
| 5662 | 5715 | align_of.rparen_token = try appendToken(c, .RParen, ")"); |
| 5663 | 5716 | // hack to get zig fmt to render a comma in builtin calls |
| 5664 | 5717 | _ = try appendToken(c, .Comma, ","); |
| 5665 | 5718 | |
| 5666 | | const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast"); |
| 5667 | | try align_cast.params.push(&align_of.base); |
| 5668 | | try align_cast.params.push(node_to_cast); |
| 5719 | const align_cast = try c.createBuiltinCall("@alignCast", 2); |
| 5720 | align_cast.params()[0] = &align_of.base; |
| 5721 | align_cast.params()[1] = node_to_cast; |
| 5669 | 5722 | align_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| 5670 | 5723 | |
| 5671 | | const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast"); |
| 5672 | | try ptr_cast.params.push(inner_node); |
| 5673 | | try ptr_cast.params.push(&align_cast.base); |
| 5724 | const ptr_cast = try c.createBuiltinCall("@ptrCast", 2); |
| 5725 | ptr_cast.params()[0] = inner_node; |
| 5726 | ptr_cast.params()[1] = &align_cast.base; |
| 5674 | 5727 | ptr_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| 5675 | 5728 | if_1.body = &ptr_cast.base; |
| 5676 | 5729 | |
| ... | ... | @@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5678 | 5731 | if_1.@"else" = else_1; |
| 5679 | 5732 | |
| 5680 | 5733 | const if_2 = try transCreateNodeIf(c); |
| 5681 | | const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); |
| 5682 | | const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf"); |
| 5683 | | try type_info_2.params.push(&type_of_2.base); |
| 5684 | | try type_of_2.params.push(node_to_cast); |
| 5734 | const type_info_2 = try c.createBuiltinCall("@typeInfo", 1); |
| 5735 | const type_of_2 = try c.createBuiltinCall("@TypeOf", 1); |
| 5736 | type_info_2.params()[0] = &type_of_2.base; |
| 5737 | type_of_2.params()[0] = node_to_cast; |
| 5685 | 5738 | type_of_2.rparen_token = try appendToken(c, .RParen, ")"); |
| 5686 | 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 | 5753 | .op = .BoolAnd, |
| 5701 | 5754 | .rhs = undefined, |
| 5702 | 5755 | }; |
| 5703 | | const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo"); |
| 5704 | | try type_info_3.params.push(inner_node); |
| 5756 | const type_info_3 = try c.createBuiltinCall("@typeInfo", 1); |
| 5757 | type_info_3.params()[0] = inner_node; |
| 5705 | 5758 | type_info_3.rparen_token = try appendToken(c, .LParen, ")"); |
| 5706 | 5759 | const cmp_3 = try c.arena.create(ast.Node.InfixOp); |
| 5707 | 5760 | cmp_3.* = .{ |
| ... | ... | @@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5715 | 5768 | else_1.body = &if_2.base; |
| 5716 | 5769 | _ = try appendToken(c, .RParen, ")"); |
| 5717 | 5770 | |
| 5718 | | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); |
| 5719 | | try int_to_ptr.params.push(inner_node); |
| 5720 | | try int_to_ptr.params.push(node_to_cast); |
| 5771 | const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2); |
| 5772 | int_to_ptr.params()[0] = inner_node; |
| 5773 | int_to_ptr.params()[1] = node_to_cast; |
| 5721 | 5774 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| 5722 | 5775 | if_2.body = &int_to_ptr.base; |
| 5723 | 5776 | |
| 5724 | 5777 | const else_2 = try transCreateNodeElse(c); |
| 5725 | 5778 | if_2.@"else" = else_2; |
| 5726 | 5779 | |
| 5727 | | const as = try transCreateNodeBuiltinFnCall(c, "@as"); |
| 5728 | | try as.params.push(inner_node); |
| 5729 | | try as.params.push(node_to_cast); |
| 5780 | const as = try c.createBuiltinCall("@as", 2); |
| 5781 | as.params()[0] = inner_node; |
| 5782 | as.params()[1] = node_to_cast; |
| 5730 | 5783 | as.rparen_token = try appendToken(c, .RParen, ")"); |
| 5731 | 5784 | else_2.body = &as.base; |
| 5732 | 5785 | |
| ... | ... | @@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node { |
| 5765 | 5818 | return &group_node.base; |
| 5766 | 5819 | } |
| 5767 | 5820 | |
| 5768 | | const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt"); |
| 5769 | | try builtin_node.params.push(node); |
| 5821 | const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1); |
| 5822 | builtin_node.params()[0] = node; |
| 5770 | 5823 | builtin_node.rparen_token = try appendToken(c, .RParen, ")"); |
| 5771 | 5824 | return &builtin_node.base; |
| 5772 | 5825 | } |
| ... | ... | @@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5944 | 5997 | continue; |
| 5945 | 5998 | }, |
| 5946 | 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 | 6003 | while (true) { |
| 5949 | 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 | 6006 | const next = it.next().?; |
| 5952 | 6007 | if (next.id == .Comma) |
| 5953 | 6008 | _ = try appendToken(c, .Comma, ",") |
| ... | ... | @@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5965 | 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 | 6031 | node = &call_node.base; |
| 5970 | 6032 | continue; |
| 5971 | 6033 | }, |