| ... | ... | @@ -49,7 +49,9 @@ const Scope = struct { |
| 49 | 49 | Block, |
| 50 | 50 | Root, |
| 51 | 51 | While, |
| 52 | FnDef, |
| 52 | 53 | }; |
| 54 | |
| 53 | 55 | const Switch = struct { |
| 54 | 56 | base: Scope, |
| 55 | 57 | }; |
| ... | ... | @@ -65,21 +67,14 @@ const Scope = struct { |
| 65 | 67 | block_node: *ast.Node.Block, |
| 66 | 68 | |
| 67 | 69 | /// Don't forget to set rbrace token later |
| 68 | | fn create(c: *Context, parent: *Scope, lbrace_tok: ast.TokenIndex) !*Block { |
| 70 | fn init(c: *Context, parent: *Scope, block_node: *ast.Node.Block) !*Block { |
| 69 | 71 | const block = try c.a().create(Block); |
| 70 | | block.* = Block{ |
| 71 | | .base = Scope{ |
| 72 | | .id = Id.Block, |
| 72 | block.* = .{ |
| 73 | .base = .{ |
| 74 | .id = .Block, |
| 73 | 75 | .parent = parent, |
| 74 | 76 | }, |
| 75 | | .block_node = try c.a().create(ast.Node.Block), |
| 76 | | }; |
| 77 | | block.block_node.* = ast.Node.Block{ |
| 78 | | .base = ast.Node{ .id = ast.Node.Id.Block }, |
| 79 | | .label = null, |
| 80 | | .lbrace = lbrace_tok, |
| 81 | | .statements = ast.Node.Block.StatementList.init(c.a()), |
| 82 | | .rbrace = undefined, |
| 77 | .block_node = block_node, |
| 83 | 78 | }; |
| 84 | 79 | return block; |
| 85 | 80 | } |
| ... | ... | @@ -87,11 +82,91 @@ const Scope = struct { |
| 87 | 82 | |
| 88 | 83 | const Root = struct { |
| 89 | 84 | base: Scope, |
| 85 | sym_table: SymbolTable, |
| 86 | macro_table: SymbolTable, |
| 87 | |
| 88 | fn init(c: *Context) Root { |
| 89 | return .{ |
| 90 | .base = .{ |
| 91 | .id = .Root, |
| 92 | .parent = null, |
| 93 | }, |
| 94 | .sym_table = SymbolTable.init(c.a()), |
| 95 | .macro_table = SymbolTable.init(c.a()), |
| 96 | }; |
| 97 | } |
| 98 | |
| 99 | fn contains(scope: *Root, name: []const u8) bool { |
| 100 | return scope.sym_table.contains(name) or scope.macro_table.contains(name); |
| 101 | } |
| 90 | 102 | }; |
| 91 | 103 | |
| 92 | 104 | const While = struct { |
| 93 | 105 | base: Scope, |
| 94 | 106 | }; |
| 107 | |
| 108 | const FnDef = struct { |
| 109 | base: Scope, |
| 110 | params: AliasList, |
| 111 | |
| 112 | fn init(c: *Context) FnDef { |
| 113 | return .{ |
| 114 | .base = .{ |
| 115 | .id = .FnDef, |
| 116 | .parent = &c.global_scope.base, |
| 117 | }, |
| 118 | .params = AliasList.init(c.a()), |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | fn getAlias(scope: *FnDef, name: []const u8) ?[]const u8 { |
| 123 | var it = scope.params.iterator(0); |
| 124 | while (it.next()) |p| { |
| 125 | if (std.mem.eql(u8, p.name, name)) |
| 126 | return p.alias; |
| 127 | } |
| 128 | return scope.base.parent.?.getAlias(name); |
| 129 | } |
| 130 | |
| 131 | fn contains(scope: *FnDef, name: []const u8) bool { |
| 132 | var it = scope.params.iterator(0); |
| 133 | while (it.next()) |p| { |
| 134 | if (std.mem.eql(u8, p.name, name)) |
| 135 | return true; |
| 136 | } |
| 137 | return scope.base.parent.?.contains(name); |
| 138 | } |
| 139 | }; |
| 140 | |
| 141 | fn findBlockScope(inner: *Scope) *Scope.Block { |
| 142 | var scope = inner; |
| 143 | while (true) : (scope = scope.parent orelse unreachable) { |
| 144 | if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | fn createAlias(scope: *Scope, c: *Context, name: []const u8) !?[]const u8 { |
| 149 | if (scope.contains(name)) { |
| 150 | return try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() }); |
| 151 | } |
| 152 | return null; |
| 153 | } |
| 154 | |
| 155 | fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 { |
| 156 | return switch (scope.id) { |
| 157 | .Root => null, |
| 158 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), |
| 159 | else => @panic("TODO Scope.getAlias"), |
| 160 | }; |
| 161 | } |
| 162 | |
| 163 | fn contains(scope: *Scope, name: []const u8) bool { |
| 164 | return switch (scope.id) { |
| 165 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), |
| 166 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), |
| 167 | else => @panic("TODO Scope.contains"), |
| 168 | }; |
| 169 | } |
| 95 | 170 | }; |
| 96 | 171 | |
| 97 | 172 | const TransResult = struct { |
| ... | ... | @@ -107,8 +182,6 @@ const Context = struct { |
| 107 | 182 | source_manager: *ZigClangSourceManager, |
| 108 | 183 | decl_table: DeclTable, |
| 109 | 184 | alias_list: AliasList, |
| 110 | | sym_table: SymbolTable, |
| 111 | | macro_table: SymbolTable, |
| 112 | 185 | global_scope: *Scope.Root, |
| 113 | 186 | ptr_params: std.BufSet, |
| 114 | 187 | clang_context: *ZigClangASTContext, |
| ... | ... | @@ -145,7 +218,7 @@ pub fn translate( |
| 145 | 218 | args_begin: [*]?[*]const u8, |
| 146 | 219 | args_end: [*]?[*]const u8, |
| 147 | 220 | errors: *[]ClangErrMsg, |
| 148 | | resources_path: [*]const u8, |
| 221 | resources_path: [*:0]const u8, |
| 149 | 222 | ) !*ast.Tree { |
| 150 | 223 | const ast_unit = ZigClangLoadFromCommandLine( |
| 151 | 224 | args_begin, |
| ... | ... | @@ -195,18 +268,11 @@ pub fn translate( |
| 195 | 268 | .err = undefined, |
| 196 | 269 | .decl_table = DeclTable.init(arena), |
| 197 | 270 | .alias_list = AliasList.init(arena), |
| 198 | | .sym_table = SymbolTable.init(arena), |
| 199 | | .macro_table = SymbolTable.init(arena), |
| 200 | 271 | .global_scope = try arena.create(Scope.Root), |
| 201 | 272 | .ptr_params = std.BufSet.init(arena), |
| 202 | 273 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, |
| 203 | 274 | }; |
| 204 | | context.global_scope.* = Scope.Root{ |
| 205 | | .base = Scope{ |
| 206 | | .id = Scope.Id.Root, |
| 207 | | .parent = null, |
| 208 | | }, |
| 209 | | }; |
| 275 | context.global_scope.* = Scope.Root.init(&context); |
| 210 | 276 | |
| 211 | 277 | if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorC)) { |
| 212 | 278 | return context.err; |
| ... | ... | @@ -217,7 +283,7 @@ pub fn translate( |
| 217 | 283 | try addMacros(&context); |
| 218 | 284 | var it = context.alias_list.iterator(0); |
| 219 | 285 | while (it.next()) |alias| { |
| 220 | | if (!context.sym_table.contains(alias.alias)) { |
| 286 | if (!context.global_scope.sym_table.contains(alias.alias)) { |
| 221 | 287 | try createAlias(&context, alias); |
| 222 | 288 | } |
| 223 | 289 | } |
| ... | ... | @@ -276,7 +342,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 276 | 342 | const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl); |
| 277 | 343 | const fn_qt = ZigClangFunctionDecl_getType(fn_decl); |
| 278 | 344 | const fn_type = ZigClangQualType_getTypePtr(fn_qt); |
| 279 | | var scope = &c.global_scope.base; |
| 345 | var fndef_scope = Scope.FnDef.init(c); |
| 346 | var scope = &fndef_scope.base; |
| 280 | 347 | const has_body = ZigClangFunctionDecl_hasBody(fn_decl); |
| 281 | 348 | const storage_class = ZigClangFunctionDecl_getStorageClass(fn_decl); |
| 282 | 349 | const decl_ctx = FnDeclContext{ |
| ... | ... | @@ -343,7 +410,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 343 | 410 | else |
| 344 | 411 | try appendToken(c, .Keyword_threadlocal, "threadlocal"); |
| 345 | 412 | |
| 346 | | var scope = &c.global_scope.base; |
| 413 | const scope = &c.global_scope.base; |
| 347 | 414 | const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl))); |
| 348 | 415 | _ = try c.decl_table.put(@ptrToInt(var_decl), var_name); |
| 349 | 416 | const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); |
| ... | ... | @@ -364,7 +431,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| 364 | 431 | else |
| 365 | 432 | try appendToken(c, .Keyword_var, "var"); |
| 366 | 433 | |
| 367 | | const name_tok = try appendIdentifier(c, var_name); |
| 434 | const name_tok = try appendIdentifier(c, var_name, null); |
| 368 | 435 | |
| 369 | 436 | _ = try appendToken(c, .Colon, ":"); |
| 370 | 437 | const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { |
| ... | ... | @@ -425,7 +492,7 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err |
| 425 | 492 | |
| 426 | 493 | const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); |
| 427 | 494 | _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name); |
| 428 | | const name_tok = try appendIdentifier(c, typedef_name); |
| 495 | const name_tok = try appendIdentifier(c, typedef_name, null); |
| 429 | 496 | const eq_tok = try appendToken(c, .Equal, "="); |
| 430 | 497 | |
| 431 | 498 | const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); |
| ... | ... | @@ -478,7 +545,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 478 | 545 | |
| 479 | 546 | const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name }); |
| 480 | 547 | _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name); |
| 481 | | const name_tok = try appendIdentifier(c, name); |
| 548 | const name_tok = try appendIdentifier(c, name, null); |
| 482 | 549 | |
| 483 | 550 | const eq_tok = try appendToken(c, .Equal, "="); |
| 484 | 551 | const init_node = transRecordDecl(c, record_decl) catch |err| switch (err) { |
| ... | ... | @@ -514,10 +581,10 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error! |
| 514 | 581 | fn createAlias(c: *Context, alias: var) !void { |
| 515 | 582 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 516 | 583 | const mut_tok = try appendToken(c, .Keyword_const, "const"); |
| 517 | | const name_tok = try appendIdentifier(c, alias.alias); |
| 584 | const name_tok = try appendIdentifier(c, alias.alias, null); |
| 518 | 585 | |
| 519 | 586 | const eq_tok = try appendToken(c, .Equal, "="); |
| 520 | | const init_node = try transCreateNodeIdentifier(c, alias.name); |
| 587 | const init_node = try transCreateNodeIdentifier(c, alias.name, null); |
| 521 | 588 | |
| 522 | 589 | const node = try c.a().create(ast.Node.VarDecl); |
| 523 | 590 | node.* = ast.Node.VarDecl{ |
| ... | ... | @@ -731,7 +798,7 @@ fn transCompoundStmtInline( |
| 731 | 798 | const end_it = ZigClangCompoundStmt_body_end(stmt); |
| 732 | 799 | var scope = parent_scope; |
| 733 | 800 | while (it != end_it) : (it += 1) { |
| 734 | | const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); |
| 801 | const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value); |
| 735 | 802 | scope = result.child_scope; |
| 736 | 803 | if (result.node != &block_node.base) |
| 737 | 804 | try block_node.statements.push(result.node); |
| ... | ... | @@ -743,13 +810,13 @@ fn transCompoundStmtInline( |
| 743 | 810 | }; |
| 744 | 811 | } |
| 745 | 812 | |
| 746 | | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) !TransResult { |
| 747 | | const lbrace_tok = try appendToken(rp.c, .LBrace, "{"); |
| 748 | | const block_scope = try Scope.Block.create(rp.c, scope, lbrace_tok); |
| 749 | | const inline_result = try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node); |
| 750 | | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 813 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!TransResult { |
| 814 | const block_node = try transCreateNodeBlock(rp.c, null, null); |
| 815 | const block_scope = try Scope.Block.init(rp.c, scope, block_node); |
| 816 | const inline_result = try transCompoundStmtInline(rp, &block_scope.base, stmt, block_node); |
| 817 | block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 751 | 818 | return TransResult{ |
| 752 | | .node = &block_scope.block_node.base, |
| 819 | .node = &block_node.base, |
| 753 | 820 | .node_scope = inline_result.node_scope, |
| 754 | 821 | .child_scope = inline_result.child_scope, |
| 755 | 822 | }; |
| ... | ... | @@ -779,17 +846,17 @@ fn transCStyleCastExprClass( |
| 779 | 846 | return maybeSuppressResult(rp, scope, result_used, cast_res); |
| 780 | 847 | } |
| 781 | 848 | |
| 782 | | fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { |
| 849 | fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!TransResult { |
| 783 | 850 | const c = rp.c; |
| 784 | | const block_scope = findBlockScope(parent_scope); |
| 851 | const block_scope = parent_scope.findBlockScope(); |
| 785 | 852 | var scope = parent_scope; |
| 786 | 853 | |
| 787 | 854 | var it = ZigClangDeclStmt_decl_begin(stmt); |
| 788 | 855 | const end_it = ZigClangDeclStmt_decl_end(stmt); |
| 789 | 856 | while (it != end_it) : (it += 1) { |
| 790 | | switch (ZigClangDecl_getKind(it.*)) { |
| 857 | switch (ZigClangDecl_getKind(it[0])) { |
| 791 | 858 | .Var => { |
| 792 | | const var_decl = @ptrCast(*const ZigClangVarDecl, it.*); |
| 859 | const var_decl = @ptrCast(*const ZigClangVarDecl, it[0]); |
| 793 | 860 | |
| 794 | 861 | const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) |
| 795 | 862 | null |
| ... | ... | @@ -803,7 +870,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe |
| 803 | 870 | const c_name = try c.str(ZigClangDecl_getName_bytes_begin( |
| 804 | 871 | @ptrCast(*const ZigClangDecl, var_decl), |
| 805 | 872 | )); |
| 806 | | const name_token = try appendIdentifier(c, c_name); |
| 873 | const name_token = try appendIdentifier(c, c_name, null); // TODO parent_scope); |
| 807 | 874 | |
| 808 | 875 | const var_scope = try c.a().create(Scope.Var); |
| 809 | 876 | var_scope.* = Scope.Var{ |
| ... | ... | @@ -871,7 +938,7 @@ fn transDeclRefExpr( |
| 871 | 938 | const c_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl))); |
| 872 | 939 | const zig_name = transLookupZigIdentifier(scope, c_name); |
| 873 | 940 | if (lrvalue == .l_value) try rp.c.ptr_params.put(zig_name); |
| 874 | | const node = try transCreateNodeIdentifier(rp.c, zig_name); |
| 941 | const node = try transCreateNodeIdentifier(rp.c, zig_name, null); // TODO scope); |
| 875 | 942 | return TransResult{ |
| 876 | 943 | .node = node, |
| 877 | 944 | .node_scope = scope, |
| ... | ... | @@ -1240,13 +1307,6 @@ fn transImplicitValueInitExpr( |
| 1240 | 1307 | }; |
| 1241 | 1308 | } |
| 1242 | 1309 | |
| 1243 | | fn findBlockScope(inner: *Scope) *Scope.Block { |
| 1244 | | var scope = inner; |
| 1245 | | while (true) : (scope = scope.parent orelse unreachable) { |
| 1246 | | if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope); |
| 1247 | | } |
| 1248 | | } |
| 1249 | | |
| 1250 | 1310 | fn transLookupZigIdentifier(inner: *Scope, c_name: []const u8) []const u8 { |
| 1251 | 1311 | var scope = inner; |
| 1252 | 1312 | while (true) : (scope = scope.parent orelse return c_name) { |
| ... | ... | @@ -1303,7 +1363,7 @@ fn maybeSuppressResult( |
| 1303 | 1363 | if (used == .used) return result; |
| 1304 | 1364 | // NOTE: This is backwards, but the semicolon must immediately follow the node. |
| 1305 | 1365 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1306 | | const lhs = try transCreateNodeIdentifier(rp.c, "_"); |
| 1366 | const lhs = try transCreateNodeIdentifier(rp.c, "_", null); |
| 1307 | 1367 | const op_token = try appendToken(rp.c, .Equal, "="); |
| 1308 | 1368 | const op_node = try rp.c.a().create(ast.Node.InfixOp); |
| 1309 | 1369 | op_node.* = ast.Node.InfixOp{ |
| ... | ... | @@ -1321,7 +1381,7 @@ fn maybeSuppressResult( |
| 1321 | 1381 | |
| 1322 | 1382 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { |
| 1323 | 1383 | try c.tree.root_node.decls.push(decl_node); |
| 1324 | | _ = try c.sym_table.put(name, decl_node); |
| 1384 | _ = try c.global_scope.sym_table.put(name, decl_node); |
| 1325 | 1385 | } |
| 1326 | 1386 | |
| 1327 | 1387 | fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TypeError!*ast.Node { |
| ... | ... | @@ -1383,7 +1443,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro |
| 1383 | 1443 | return node; |
| 1384 | 1444 | } |
| 1385 | 1445 | |
| 1386 | | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)))); |
| 1446 | const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))), null); |
| 1387 | 1447 | _ = try appendToken(c, .Colon, ":"); |
| 1388 | 1448 | const field_type = try transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc); |
| 1389 | 1449 | |
| ... | ... | @@ -1407,7 +1467,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro |
| 1407 | 1467 | |
| 1408 | 1468 | fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.Node { |
| 1409 | 1469 | if (c.decl_table.get(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)))) |name| |
| 1410 | | return try transCreateNodeIdentifier(c, name.value); // Avoid processing this decl twice |
| 1470 | return try transCreateNodeIdentifier(c, name.value, null); // Avoid processing this decl twice |
| 1411 | 1471 | const rp = makeRestorePoint(c); |
| 1412 | 1472 | const enum_loc = ZigClangEnumDecl_getLocation(enum_decl); |
| 1413 | 1473 | |
| ... | ... | @@ -1423,7 +1483,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1423 | 1483 | |
| 1424 | 1484 | const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name}); |
| 1425 | 1485 | _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name); |
| 1426 | | const name_tok = try appendIdentifier(c, name); |
| 1486 | const name_tok = try appendIdentifier(c, name, null); |
| 1427 | 1487 | const eq_tok = try appendToken(c, .Equal, "="); |
| 1428 | 1488 | |
| 1429 | 1489 | const init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: { |
| ... | ... | @@ -1490,7 +1550,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1490 | 1550 | else |
| 1491 | 1551 | enum_val_name; |
| 1492 | 1552 | |
| 1493 | | const field_name_tok = try appendIdentifier(c, field_name); |
| 1553 | const field_name_tok = try appendIdentifier(c, field_name, null); |
| 1494 | 1554 | |
| 1495 | 1555 | const int_node = if (!pure_enum) blk: { |
| 1496 | 1556 | _ = try appendToken(c, .Colon, "="); |
| ... | ... | @@ -1543,18 +1603,18 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1543 | 1603 | try addTopLevelDecl(c, name, &node.base); |
| 1544 | 1604 | if (!is_unnamed) |
| 1545 | 1605 | try c.alias_list.push(.{ .alias = bare_name, .name = name }); |
| 1546 | | return transCreateNodeIdentifier(c, name); |
| 1606 | return transCreateNodeIdentifier(c, name, null); |
| 1547 | 1607 | } |
| 1548 | 1608 | |
| 1549 | 1609 | fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void { |
| 1550 | 1610 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 1551 | 1611 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 1552 | | const name_tok = try appendIdentifier(c, enum_val_name); |
| 1612 | const name_tok = try appendIdentifier(c, enum_val_name, null); |
| 1553 | 1613 | const eq_tok = try appendToken(c, .Equal, "="); |
| 1554 | 1614 | |
| 1555 | | const enum_ident = try transCreateNodeIdentifier(c, enum_name); |
| 1615 | const enum_ident = try transCreateNodeIdentifier(c, enum_name, null); |
| 1556 | 1616 | const period_tok = try appendToken(c, .Period, "."); |
| 1557 | | const field_ident = try transCreateNodeIdentifier(c, field_name); |
| 1617 | const field_ident = try transCreateNodeIdentifier(c, field_name, null); |
| 1558 | 1618 | |
| 1559 | 1619 | const field_access_node = try c.a().create(ast.Node.InfixOp); |
| 1560 | 1620 | field_access_node.* = .{ |
| ... | ... | @@ -1836,7 +1896,7 @@ fn transCreateNodePtrType( |
| 1836 | 1896 | .Identifier => blk: { |
| 1837 | 1897 | const lbracket = try appendToken(c, .LBracket, "["); // Rendering checks if this token + 2 == .Identifier, so needs to return this token |
| 1838 | 1898 | _ = try appendToken(c, .Asterisk, "*"); |
| 1839 | | _ = try appendIdentifier(c, "c"); |
| 1899 | _ = try appendIdentifier(c, "c", null); // not really an identifier |
| 1840 | 1900 | _ = try appendToken(c, .RBracket, "]"); |
| 1841 | 1901 | break :blk lbracket; |
| 1842 | 1902 | }, |
| ... | ... | @@ -1954,10 +2014,12 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { |
| 1954 | 2014 | } |
| 1955 | 2015 | |
| 1956 | 2016 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias_node: *ast.Node) !*ast.Node { |
| 2017 | const scope = &c.global_scope.base; |
| 2018 | |
| 1957 | 2019 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 1958 | 2020 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| 1959 | 2021 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| 1960 | | const name_tok = try appendIdentifier(c, name); |
| 2022 | const name_tok = try appendIdentifier(c, name, null); |
| 1961 | 2023 | _ = try appendToken(c, .LParen, "("); |
| 1962 | 2024 | |
| 1963 | 2025 | const proto_alias = proto_alias_node.cast(ast.Node.FnProto).?; |
| ... | ... | @@ -2006,13 +2068,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 2006 | 2068 | .section_expr = null, |
| 2007 | 2069 | }; |
| 2008 | 2070 | |
| 2009 | | const block = try c.a().create(ast.Node.Block); |
| 2010 | | block.* = .{ |
| 2011 | | .label = null, |
| 2012 | | .lbrace = try appendToken(c, .LBrace, "{"), |
| 2013 | | .statements = ast.Node.Block.StatementList.init(c.a()), |
| 2014 | | .rbrace = undefined, |
| 2015 | | }; |
| 2071 | const block = try transCreateNodeBlock(c, null, null); |
| 2016 | 2072 | |
| 2017 | 2073 | const return_expr = try transCreateNodeReturnExpr(c); |
| 2018 | 2074 | const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?); |
| ... | ... | @@ -2023,7 +2079,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 2023 | 2079 | _ = try appendToken(c, .Comma, ","); |
| 2024 | 2080 | } |
| 2025 | 2081 | const param = pn.*.cast(ast.Node.ParamDecl).?; |
| 2026 | | try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?))); |
| 2082 | try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?), null)); |
| 2027 | 2083 | } |
| 2028 | 2084 | call_expr.rtoken = try appendToken(c, .RParen, ")"); |
| 2029 | 2085 | return_expr.rhs = &call_expr.base; |
| ... | ... | @@ -2051,7 +2107,7 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node { |
| 2051 | 2107 | const node = try c.a().create(ast.Node.EnumLiteral); |
| 2052 | 2108 | node.* = .{ |
| 2053 | 2109 | .dot = try appendToken(c, .Period, "."), |
| 2054 | | .name = try appendIdentifier(c, name), |
| 2110 | .name = try appendIdentifier(c, name, null), // scoped to an enum |
| 2055 | 2111 | }; |
| 2056 | 2112 | return &node.base; |
| 2057 | 2113 | } |
| ... | ... | @@ -2080,6 +2136,22 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { |
| 2080 | 2136 | return node; |
| 2081 | 2137 | } |
| 2082 | 2138 | |
| 2139 | fn transCreateNodeBlock(c: *Context, label: ?[]const u8, scope: ?*Scope) !*ast.Node.Block { |
| 2140 | const label_node = if (label) |l| blk: { |
| 2141 | const ll = try appendIdentifier(c, l, scope); |
| 2142 | _ = try appendToken(c, .Colon, ":"); |
| 2143 | break :blk ll; |
| 2144 | } else null; |
| 2145 | const block_node = try c.a().create(ast.Node.Block); |
| 2146 | block_node.* = .{ |
| 2147 | .label = label_node, |
| 2148 | .lbrace = try appendToken(c, .LBrace, "{"), |
| 2149 | .statements = ast.Node.Block.StatementList.init(c.a()), |
| 2150 | .rbrace = undefined, |
| 2151 | }; |
| 2152 | return block_node; |
| 2153 | } |
| 2154 | |
| 2083 | 2155 | const RestorePoint = struct { |
| 2084 | 2156 | c: *Context, |
| 2085 | 2157 | token_index: ast.TokenIndex, |
| ... | ... | @@ -2124,7 +2196,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 2124 | 2196 | .Float16 => "f16", |
| 2125 | 2197 | .LongDouble => "c_longdouble", |
| 2126 | 2198 | else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 2127 | | }); |
| 2199 | }, null); |
| 2128 | 2200 | }, |
| 2129 | 2201 | .FunctionProto => { |
| 2130 | 2202 | const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); |
| ... | ... | @@ -2202,14 +2274,21 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 2202 | 2274 | |
| 2203 | 2275 | const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); |
| 2204 | 2276 | const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl))); |
| 2205 | | return transCreateNodeIdentifier(rp.c, typedef_name); |
| 2277 | return transCreateNodeIdentifier(rp.c, typedef_name, null); |
| 2206 | 2278 | }, |
| 2207 | 2279 | .Record => { |
| 2208 | 2280 | const record_ty = @ptrCast(*const ZigClangRecordType, ty); |
| 2209 | 2281 | |
| 2282 | // TODO this sould get the name from decl_table |
| 2283 | // struct Foo { |
| 2284 | // struct Bar{ |
| 2285 | // int b; |
| 2286 | // }; |
| 2287 | // struct Bar c; |
| 2288 | // }; |
| 2210 | 2289 | const record_decl = ZigClangRecordType_getDecl(record_ty); |
| 2211 | 2290 | if (try getContainerName(rp, record_decl)) |name| |
| 2212 | | return transCreateNodeIdentifier(rp.c, name) |
| 2291 | return transCreateNodeIdentifier(rp.c, name, null) |
| 2213 | 2292 | else |
| 2214 | 2293 | return transRecordDecl(rp.c, record_decl); |
| 2215 | 2294 | }, |
| ... | ... | @@ -2334,6 +2413,9 @@ fn finishTransFnProto( |
| 2334 | 2413 | // TODO check for always_inline attribute |
| 2335 | 2414 | // TODO check for align attribute |
| 2336 | 2415 | |
| 2416 | var fndef_scope = Scope.FnDef.init(rp.c); |
| 2417 | const scope = &fndef_scope.base; |
| 2418 | |
| 2337 | 2419 | // pub extern fn name(...) T |
| 2338 | 2420 | const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null; |
| 2339 | 2421 | const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; |
| ... | ... | @@ -2344,7 +2426,7 @@ fn finishTransFnProto( |
| 2344 | 2426 | else |
| 2345 | 2427 | null; |
| 2346 | 2428 | const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn"); |
| 2347 | | const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name) else null; |
| 2429 | const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name, null) else null; |
| 2348 | 2430 | const lparen_tok = try appendToken(rp.c, .LParen, "("); |
| 2349 | 2431 | |
| 2350 | 2432 | var fn_params = ast.Node.FnProto.ParamList.init(rp.c.a()); |
| ... | ... | @@ -2359,13 +2441,17 @@ fn finishTransFnProto( |
| 2359 | 2441 | const param_name_tok: ?ast.TokenIndex = blk: { |
| 2360 | 2442 | if (fn_decl != null) { |
| 2361 | 2443 | const param = ZigClangFunctionDecl_getParamDecl(fn_decl.?, @intCast(c_uint, i)); |
| 2362 | | const param_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param))); |
| 2363 | | if (param_name.len > 0) { |
| 2364 | | // TODO: If len == 0, auto-generate arg1, arg2, etc? Or leave the name blank? |
| 2365 | | const result = try appendIdentifier(rp.c, param_name); |
| 2366 | | _ = try appendToken(rp.c, .Colon, ":"); |
| 2367 | | break :blk result; |
| 2368 | | } |
| 2444 | var param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param))); |
| 2445 | if (param_name.len < 1) |
| 2446 | param_name = "arg"[0..]; |
| 2447 | const checked_param_name = if (try scope.createAlias(rp.c, param_name)) |a| blk: { |
| 2448 | try fndef_scope.params.push(.{ .name = param_name, .alias = a }); |
| 2449 | break :blk a; |
| 2450 | } else param_name; |
| 2451 | |
| 2452 | const result = try appendIdentifier(rp.c, checked_param_name, null); |
| 2453 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2454 | break :blk result; |
| 2369 | 2455 | } |
| 2370 | 2456 | break :blk null; |
| 2371 | 2457 | }; |
| ... | ... | @@ -2411,12 +2497,12 @@ fn finishTransFnProto( |
| 2411 | 2497 | |
| 2412 | 2498 | const return_type_node = blk: { |
| 2413 | 2499 | if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) { |
| 2414 | | break :blk try transCreateNodeIdentifier(rp.c, "noreturn"); |
| 2500 | break :blk try transCreateNodeIdentifier(rp.c, "noreturn", null); |
| 2415 | 2501 | } else { |
| 2416 | 2502 | const return_qt = ZigClangFunctionType_getReturnType(fn_ty); |
| 2417 | 2503 | if (isCVoid(return_qt)) { |
| 2418 | 2504 | // convert primitive c_void to actual void (only for return type) |
| 2419 | | break :blk try transCreateNodeIdentifier(rp.c, "void"); |
| 2505 | break :blk try transCreateNodeIdentifier(rp.c, "void", null); |
| 2420 | 2506 | } else { |
| 2421 | 2507 | break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) { |
| 2422 | 2508 | error.UnsupportedType => { |
| ... | ... | @@ -2469,7 +2555,7 @@ fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []cons |
| 2469 | 2555 | fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: var) !void { |
| 2470 | 2556 | // const name = @compileError(msg); |
| 2471 | 2557 | const const_tok = try appendToken(c, .Keyword_const, "const"); |
| 2472 | | const name_tok = try appendIdentifier(c, name); |
| 2558 | const name_tok = try appendIdentifier(c, name, null); |
| 2473 | 2559 | const eq_tok = try appendToken(c, .Equal, "="); |
| 2474 | 2560 | const builtin_tok = try appendToken(c, .Builtin, "@compileError"); |
| 2475 | 2561 | const lparen_tok = try appendToken(c, .LParen, "("); |
| ... | ... | @@ -2554,7 +2640,11 @@ fn isValidZigIdentifier(name: []const u8) bool { |
| 2554 | 2640 | return true; |
| 2555 | 2641 | } |
| 2556 | 2642 | |
| 2557 | | fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex { |
| 2643 | fn appendIdentifier(c: *Context, name: []const u8, scope: ?*Scope) !ast.TokenIndex { |
| 2644 | if (scope) |s| |
| 2645 | if (s.getAlias(name)) |alias| { |
| 2646 | return appendTokenFmt(c, .Identifier, "{}", .{alias}); |
| 2647 | }; |
| 2558 | 2648 | if (!isValidZigIdentifier(name) or std.zig.Token.getKeyword(name) != null) { |
| 2559 | 2649 | return appendTokenFmt(c, .Identifier, "@\"{}\"", .{name}); |
| 2560 | 2650 | } else { |
| ... | ... | @@ -2562,8 +2652,8 @@ fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex { |
| 2562 | 2652 | } |
| 2563 | 2653 | } |
| 2564 | 2654 | |
| 2565 | | fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node { |
| 2566 | | const token_index = try appendIdentifier(c, name); |
| 2655 | fn transCreateNodeIdentifier(c: *Context, name: []const u8, scope: ?*Scope) !*ast.Node { |
| 2656 | const token_index = try appendIdentifier(c, name, scope); |
| 2567 | 2657 | const identifier = try c.a().create(ast.Node.Identifier); |
| 2568 | 2658 | identifier.* = ast.Node.Identifier{ |
| 2569 | 2659 | .base = ast.Node{ .id = ast.Node.Id.Identifier }, |
| ... | ... | @@ -2581,6 +2671,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 2581 | 2671 | var it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit); |
| 2582 | 2672 | const it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit); |
| 2583 | 2673 | var tok_list = ctok.TokenList.init(c.a()); |
| 2674 | const scope = &c.global_scope.base; |
| 2584 | 2675 | |
| 2585 | 2676 | while (it.I != it_end.I) : (it.I += 1) { |
| 2586 | 2677 | const entity = ZigClangPreprocessingRecord_iterator_deref(it); |
| ... | ... | @@ -2592,9 +2683,9 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 2592 | 2683 | const begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro); |
| 2593 | 2684 | |
| 2594 | 2685 | const name = try c.str(raw_name); |
| 2595 | | // if (name_exists_global(c, name)) { // TODO |
| 2596 | | // continue; |
| 2597 | | // } |
| 2686 | if (scope.contains(name)) { |
| 2687 | continue; |
| 2688 | } |
| 2598 | 2689 | const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); |
| 2599 | 2690 | ctok.tokenizeCMacro(&tok_list, begin_c) catch |err| switch (err) { |
| 2600 | 2691 | error.OutOfMemory => |e| return e, |
| ... | ... | @@ -2645,14 +2736,14 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 2645 | 2736 | |
| 2646 | 2737 | fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 2647 | 2738 | const rp = makeRestorePoint(c); |
| 2739 | const scope = &c.global_scope.base; |
| 2648 | 2740 | |
| 2649 | 2741 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 2650 | 2742 | const mut_tok = try appendToken(c, .Keyword_const, "const"); |
| 2651 | | const name_tok = try appendIdentifier(c, name); |
| 2652 | | |
| 2743 | const name_tok = try appendIdentifier(c, name, null); |
| 2653 | 2744 | const eq_tok = try appendToken(c, .Equal, "="); |
| 2654 | 2745 | |
| 2655 | | const init_node = try parseCExpr(rp, it, source_loc); |
| 2746 | const init_node = try parseCExpr(rp, it, source_loc, scope); |
| 2656 | 2747 | |
| 2657 | 2748 | const node = try c.a().create(ast.Node.VarDecl); |
| 2658 | 2749 | node.* = ast.Node.VarDecl{ |
| ... | ... | @@ -2671,15 +2762,18 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, |
| 2671 | 2762 | .init_node = init_node, |
| 2672 | 2763 | .semicolon_token = try appendToken(c, .Semicolon, ";"), |
| 2673 | 2764 | }; |
| 2674 | | _ = try c.macro_table.put(name, &node.base); |
| 2765 | _ = try c.global_scope.macro_table.put(name, &node.base); |
| 2675 | 2766 | } |
| 2676 | 2767 | |
| 2677 | 2768 | fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 2678 | 2769 | const rp = makeRestorePoint(c); |
| 2770 | var fndef_scope = Scope.FnDef.init(c); |
| 2771 | const scope = &fndef_scope.base; |
| 2772 | |
| 2679 | 2773 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 2680 | 2774 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| 2681 | 2775 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| 2682 | | const name_tok = try appendIdentifier(c, name); |
| 2776 | const name_tok = try appendIdentifier(c, name, null); |
| 2683 | 2777 | _ = try appendToken(c, .LParen, "("); |
| 2684 | 2778 | |
| 2685 | 2779 | if (it.next().?.id != .LParen) { |
| ... | ... | @@ -2691,8 +2785,12 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2691 | 2785 | if (param_tok.id != .Identifier) |
| 2692 | 2786 | return error.ParseError; |
| 2693 | 2787 | |
| 2694 | | // TODO avoid name collisions |
| 2695 | | const param_name_tok = try appendIdentifier(c, param_tok.bytes); |
| 2788 | const checked_name = if (try scope.createAlias(c, param_tok.bytes)) |alias| blk: { |
| 2789 | try fndef_scope.params.push(.{ .name = param_tok.bytes, .alias = alias }); |
| 2790 | break :blk alias; |
| 2791 | } else param_tok.bytes; |
| 2792 | |
| 2793 | const param_name_tok = try appendIdentifier(c, checked_name, null); |
| 2696 | 2794 | _ = try appendToken(c, .Colon, ":"); |
| 2697 | 2795 | |
| 2698 | 2796 | const token_index = try appendToken(c, .Keyword_var, "var"); |
| ... | ... | @@ -2745,16 +2843,10 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2745 | 2843 | .section_expr = null, |
| 2746 | 2844 | }; |
| 2747 | 2845 | |
| 2748 | | const block = try c.a().create(ast.Node.Block); |
| 2749 | | block.* = .{ |
| 2750 | | .label = null, |
| 2751 | | .lbrace = try appendToken(c, .LBrace, "{"), |
| 2752 | | .statements = ast.Node.Block.StatementList.init(c.a()), |
| 2753 | | .rbrace = undefined, |
| 2754 | | }; |
| 2846 | const block = try transCreateNodeBlock(c, null, null); |
| 2755 | 2847 | |
| 2756 | 2848 | const return_expr = try transCreateNodeReturnExpr(c); |
| 2757 | | const expr = try parseCExpr(rp, it, source_loc); |
| 2849 | const expr = try parseCExpr(rp, it, source_loc, scope); |
| 2758 | 2850 | _ = try appendToken(c, .Semicolon, ";"); |
| 2759 | 2851 | try type_of.params.push(expr); |
| 2760 | 2852 | return_expr.rhs = expr; |
| ... | ... | @@ -2762,7 +2854,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 2762 | 2854 | block.rbrace = try appendToken(c, .RBrace, "}"); |
| 2763 | 2855 | try block.statements.push(&return_expr.base); |
| 2764 | 2856 | fn_proto.body_node = &block.base; |
| 2765 | | _ = try c.macro_table.put(name, &fn_proto.base); |
| 2857 | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); |
| 2766 | 2858 | } |
| 2767 | 2859 | |
| 2768 | 2860 | const ParseError = Error || error{ |
| ... | ... | @@ -2770,8 +2862,8 @@ const ParseError = Error || error{ |
| 2770 | 2862 | UnsupportedTranslation, |
| 2771 | 2863 | }; |
| 2772 | 2864 | |
| 2773 | | fn parseCExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 2774 | | return parseCPrefixOpExpr(rp, it, source_loc); |
| 2865 | fn parseCExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 2866 | return parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 2775 | 2867 | } |
| 2776 | 2868 | |
| 2777 | 2869 | fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| ... | ... | @@ -2796,7 +2888,7 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 2796 | 2888 | .LL => "c_longlong", |
| 2797 | 2889 | .LLU => "c_ulonglong", |
| 2798 | 2890 | else => unreachable, |
| 2799 | | })); |
| 2891 | }, null)); |
| 2800 | 2892 | _ = try appendToken(rp.c, .Comma, ","); |
| 2801 | 2893 | try cast_node.params.push(try transCreateNodeInt(rp.c, tok.bytes)); |
| 2802 | 2894 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -2810,7 +2902,7 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 2810 | 2902 | .F => "f32", |
| 2811 | 2903 | .L => "f64", |
| 2812 | 2904 | else => unreachable, |
| 2813 | | })); |
| 2905 | }, null)); |
| 2814 | 2906 | _ = try appendToken(rp.c, .Comma, ","); |
| 2815 | 2907 | try cast_node.params.push(try transCreateNodeFloat(rp.c, tok.bytes)); |
| 2816 | 2908 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -2825,7 +2917,7 @@ fn parseCNumLit(rp: RestorePoint, tok: *CToken, source_loc: ZigClangSourceLocati |
| 2825 | 2917 | ); |
| 2826 | 2918 | } |
| 2827 | 2919 | |
| 2828 | | fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 2920 | fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 2829 | 2921 | const tok = it.next().?; |
| 2830 | 2922 | switch (tok.id) { |
| 2831 | 2923 | .CharLit => { |
| ... | ... | @@ -2847,9 +2939,9 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 2847 | 2939 | .NumLitInt, .NumLitFloat => { |
| 2848 | 2940 | return parseCNumLit(rp, tok, source_loc); |
| 2849 | 2941 | }, |
| 2850 | | .Identifier => return transCreateNodeIdentifier(rp.c, tok.bytes), |
| 2942 | .Identifier => return transCreateNodeIdentifier(rp.c, tok.bytes, scope), |
| 2851 | 2943 | .LParen => { |
| 2852 | | const inner_node = try parseCExpr(rp, it, source_loc); |
| 2944 | const inner_node = try parseCExpr(rp, it, source_loc, scope); |
| 2853 | 2945 | |
| 2854 | 2946 | if (it.peek().?.id == .RParen) { |
| 2855 | 2947 | _ = it.next(); |
| ... | ... | @@ -2859,7 +2951,7 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 2859 | 2951 | // hack to get zig fmt to render a comma in builtin calls |
| 2860 | 2952 | _ = try appendToken(rp.c, .Comma, ","); |
| 2861 | 2953 | |
| 2862 | | const node_to_cast = try parseCExpr(rp, it, source_loc); |
| 2954 | const node_to_cast = try parseCExpr(rp, it, source_loc, scope); |
| 2863 | 2955 | |
| 2864 | 2956 | if (it.next().?.id != .RParen) { |
| 2865 | 2957 | return revertAndWarn( |
| ... | ... | @@ -2951,8 +3043,8 @@ fn parseCPrimaryExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: |
| 2951 | 3043 | } |
| 2952 | 3044 | } |
| 2953 | 3045 | |
| 2954 | | fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 2955 | | var node = try parseCPrimaryExpr(rp, it, source_loc); |
| 3046 | fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 3047 | var node = try parseCPrimaryExpr(rp, it, source_loc, scope); |
| 2956 | 3048 | while (true) { |
| 2957 | 3049 | const tok = it.next().?; |
| 2958 | 3050 | switch (tok.id) { |
| ... | ... | @@ -2968,7 +3060,7 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 2968 | 3060 | ); |
| 2969 | 3061 | |
| 2970 | 3062 | const op_token = try appendToken(rp.c, .Period, "."); |
| 2971 | | const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes); |
| 3063 | const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes, null); // TODO scope); |
| 2972 | 3064 | const access_node = try rp.c.a().create(ast.Node.InfixOp); |
| 2973 | 3065 | access_node.* = .{ |
| 2974 | 3066 | .op_token = op_token, |
| ... | ... | @@ -2991,7 +3083,7 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 2991 | 3083 | } else { |
| 2992 | 3084 | // expr * expr |
| 2993 | 3085 | const op_token = try appendToken(rp.c, .Asterisk, "*"); |
| 2994 | | const rhs = try parseCPrimaryExpr(rp, it, source_loc); |
| 3086 | const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope); |
| 2995 | 3087 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); |
| 2996 | 3088 | bitshift_node.* = .{ |
| 2997 | 3089 | .op_token = op_token, |
| ... | ... | @@ -3004,7 +3096,7 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3004 | 3096 | }, |
| 3005 | 3097 | .Shl => { |
| 3006 | 3098 | const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<"); |
| 3007 | | const rhs = try parseCPrimaryExpr(rp, it, source_loc); |
| 3099 | const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope); |
| 3008 | 3100 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); |
| 3009 | 3101 | bitshift_node.* = .{ |
| 3010 | 3102 | .op_token = op_token, |
| ... | ... | @@ -3022,27 +3114,27 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3022 | 3114 | } |
| 3023 | 3115 | } |
| 3024 | 3116 | |
| 3025 | | fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 3117 | fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 3026 | 3118 | const op_tok = it.next().?; |
| 3027 | 3119 | |
| 3028 | 3120 | switch (op_tok.id) { |
| 3029 | 3121 | .Bang => { |
| 3030 | 3122 | const node = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); |
| 3031 | | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| 3123 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 3032 | 3124 | return &node.base; |
| 3033 | 3125 | }, |
| 3034 | 3126 | .Minus => { |
| 3035 | 3127 | const node = try transCreateNodePrefixOp(rp.c, .Negation, .Minus, "-"); |
| 3036 | | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| 3128 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 3037 | 3129 | return &node.base; |
| 3038 | 3130 | }, |
| 3039 | 3131 | .Tilde => { |
| 3040 | 3132 | const node = try transCreateNodePrefixOp(rp.c, .BitNot, .Tilde, "~"); |
| 3041 | | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc); |
| 3133 | node.rhs = try parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 3042 | 3134 | return &node.base; |
| 3043 | 3135 | }, |
| 3044 | 3136 | .Asterisk => { |
| 3045 | | const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc); |
| 3137 | const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 3046 | 3138 | const node = try rp.c.a().create(ast.Node.SuffixOp); |
| 3047 | 3139 | node.* = .{ |
| 3048 | 3140 | .lhs = .{ .node = prefix_op_expr }, |
| ... | ... | @@ -3053,7 +3145,7 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3053 | 3145 | }, |
| 3054 | 3146 | else => { |
| 3055 | 3147 | _ = it.prev(); |
| 3056 | | return try parseCSuffixOpExpr(rp, it, source_loc); |
| 3148 | return try parseCSuffixOpExpr(rp, it, source_loc, scope); |
| 3057 | 3149 | }, |
| 3058 | 3150 | } |
| 3059 | 3151 | } |
| ... | ... | @@ -3070,7 +3162,7 @@ fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node { |
| 3070 | 3162 | else |
| 3071 | 3163 | return null; |
| 3072 | 3164 | // TODO a.b.c |
| 3073 | | if (c.sym_table.get(name)) |kv| { |
| 3165 | if (c.global_scope.sym_table.get(name)) |kv| { |
| 3074 | 3166 | if (kv.value.cast(ast.Node.VarDecl)) |val| { |
| 3075 | 3167 | if (val.type_node) |type_node| { |
| 3076 | 3168 | if (type_node.cast(ast.Node.PrefixOp)) |casted| { |
| ... | ... | @@ -3085,7 +3177,7 @@ fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node { |
| 3085 | 3177 | } |
| 3086 | 3178 | |
| 3087 | 3179 | fn addMacros(c: *Context) !void { |
| 3088 | | var macro_it = c.macro_table.iterator(); |
| 3180 | var macro_it = c.global_scope.macro_table.iterator(); |
| 3089 | 3181 | while (macro_it.next()) |kv| { |
| 3090 | 3182 | if (getFnDecl(c, kv.value)) |proto_node| { |
| 3091 | 3183 | // If a macro aliases a global variable which is a function pointer, we conclude that |