| ... | @@ -229,8 +229,7 @@ pub const Context = struct { | ... | @@ -229,8 +229,7 @@ pub const Context = struct { |
| 229 | global_scope: *Scope.Root, | 229 | global_scope: *Scope.Root, |
| 230 | clang_context: *ZigClangASTContext, | 230 | clang_context: *ZigClangASTContext, |
| 231 | mangle_count: u32 = 0, | 231 | mangle_count: u32 = 0, |
| 232 | root_node: *ast.Node.Root, | 232 | root_decls: std.ArrayListUnmanaged(*ast.Node), |
| 233 | root_decls_it: *?*std.SinglyLinkedList(*ast.Node).Node, | | |
| 234 | | 233 | |
| 235 | /// This one is different than the root scope's name table. This contains | 234 | /// This one is different than the root scope's name table. This contains |
| 236 | /// a list of names that we found by visiting all the top level decls without | 235 | /// a list of names that we found by visiting all the top level decls without |
| ... | @@ -318,13 +317,6 @@ pub fn translate( | ... | @@ -318,13 +317,6 @@ pub fn translate( |
| 318 | var arena = std.heap.ArenaAllocator.init(gpa); | 317 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 319 | errdefer arena.deinit(); | 318 | errdefer arena.deinit(); |
| 320 | | 319 | |
| 321 | const root_node = try arena.allocator.create(ast.Node.Root); | | |
| 322 | root_node.* = .{ | | |
| 323 | .decls = ast.Node.Root.DeclList{}, | | |
| 324 | // initialized with the eof token at the end | | |
| 325 | .eof_token = undefined, | | |
| 326 | }; | | |
| 327 | | | |
| 328 | var context = Context{ | 320 | var context = Context{ |
| 329 | .gpa = gpa, | 321 | .gpa = gpa, |
| 330 | .arena = &arena.allocator, | 322 | .arena = &arena.allocator, |
| ... | @@ -338,8 +330,7 @@ pub fn translate( | ... | @@ -338,8 +330,7 @@ pub fn translate( |
| 338 | .global_names = std.StringHashMap(void).init(gpa), | 330 | .global_names = std.StringHashMap(void).init(gpa), |
| 339 | .tokens = .{}, | 331 | .tokens = .{}, |
| 340 | .errors = .{}, | 332 | .errors = .{}, |
| 341 | .root_node = root_node, | 333 | .root_decls = .{}, |
| 342 | .root_decls_it = &root_node.decls.first, | | |
| 343 | }; | 334 | }; |
| 344 | context.global_scope.* = Scope.Root.init(&context); | 335 | context.global_scope.* = Scope.Root.init(&context); |
| 345 | defer context.decl_table.deinit(); | 336 | defer context.decl_table.deinit(); |
| ... | @@ -347,6 +338,7 @@ pub fn translate( | ... | @@ -347,6 +338,7 @@ pub fn translate( |
| 347 | defer context.tokens.deinit(gpa); | 338 | defer context.tokens.deinit(gpa); |
| 348 | defer context.errors.deinit(gpa); | 339 | defer context.errors.deinit(gpa); |
| 349 | defer context.global_names.deinit(); | 340 | defer context.global_names.deinit(); |
| | 341 | defer context.root_decls.deinit(gpa); |
| 350 | | 342 | |
| 351 | try prepopulateGlobalNameTable(ast_unit, &context); | 343 | try prepopulateGlobalNameTable(ast_unit, &context); |
| 352 | | 344 | |
| ... | @@ -363,7 +355,10 @@ pub fn translate( | ... | @@ -363,7 +355,10 @@ pub fn translate( |
| 363 | } | 355 | } |
| 364 | } | 356 | } |
| 365 | | 357 | |
| 366 | root_node.eof_token = try appendToken(&context, .Eof, ""); | 358 | const eof_token = try appendToken(&context, .Eof, ""); |
| | 359 | const root_node = try ast.Node.Root.create(&arena.allocator, context.root_decls.items.len, eof_token); |
| | 360 | mem.copy(*ast.Node, root_node.decls(), context.root_decls.items); |
| | 361 | |
| 367 | if (false) { | 362 | if (false) { |
| 368 | std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", .{source_buffer.items}); | 363 | std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", .{source_buffer.items}); |
| 369 | for (context.tokens.items) |token| { | 364 | for (context.tokens.items) |token| { |
| ... | @@ -831,16 +826,8 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -831,16 +826,8 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 831 | const container_tok = try appendToken(c, container_kind, container_kind_name); | 826 | const container_tok = try appendToken(c, container_kind, container_kind_name); |
| 832 | const lbrace_token = try appendToken(c, .LBrace, "{"); | 827 | const lbrace_token = try appendToken(c, .LBrace, "{"); |
| 833 | | 828 | |
| 834 | const container_node = try c.arena.create(ast.Node.ContainerDecl); | 829 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); |
| 835 | container_node.* = .{ | 830 | defer fields_and_decls.deinit(); |
| 836 | .layout_token = layout_tok, | | |
| 837 | .kind_token = container_tok, | | |
| 838 | .init_arg_expr = .None, | | |
| 839 | .fields_and_decls = ast.Node.ContainerDecl.DeclList{}, | | |
| 840 | .lbrace_token = lbrace_token, | | |
| 841 | .rbrace_token = undefined, | | |
| 842 | }; | | |
| 843 | var container_fields_and_decls = c.llpusher(&container_node.fields_and_decls); | | |
| 844 | | 831 | |
| 845 | var unnamed_field_count: u32 = 0; | 832 | var unnamed_field_count: u32 = 0; |
| 846 | var it = ZigClangRecordDecl_field_begin(record_def); | 833 | var it = ZigClangRecordDecl_field_begin(record_def); |
| ... | @@ -915,10 +902,19 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* | ... | @@ -915,10 +902,19 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 915 | ); | 902 | ); |
| 916 | } | 903 | } |
| 917 | | 904 | |
| 918 | try container_fields_and_decls.push(&field_node.base); | 905 | try fields_and_decls.append(&field_node.base); |
| 919 | _ = try appendToken(c, .Comma, ","); | 906 | _ = try appendToken(c, .Comma, ","); |
| 920 | } | 907 | } |
| 921 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); | 908 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, fields_and_decls.items.len); |
| | 909 | container_node.* = .{ |
| | 910 | .layout_token = layout_tok, |
| | 911 | .kind_token = container_tok, |
| | 912 | .init_arg_expr = .None, |
| | 913 | .fields_and_decls_len = fields_and_decls.items.len, |
| | 914 | .lbrace_token = lbrace_token, |
| | 915 | .rbrace_token = try appendToken(c, .RBrace, "}"), |
| | 916 | }; |
| | 917 | mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items); |
| 922 | semicolon = try appendToken(c, .Semicolon, ";"); | 918 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 923 | break :blk &container_node.base; | 919 | break :blk &container_node.base; |
| 924 | }; | 920 | }; |
| ... | @@ -963,16 +959,8 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -963,16 +959,8 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 963 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); | 959 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); |
| 964 | const container_tok = try appendToken(c, .Keyword_enum, "enum"); | 960 | const container_tok = try appendToken(c, .Keyword_enum, "enum"); |
| 965 | | 961 | |
| 966 | const container_node = try c.arena.create(ast.Node.ContainerDecl); | 962 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); |
| 967 | container_node.* = .{ | 963 | defer fields_and_decls.deinit(); |
| 968 | .layout_token = extern_tok, | | |
| 969 | .kind_token = container_tok, | | |
| 970 | .init_arg_expr = .None, | | |
| 971 | .fields_and_decls = ast.Node.ContainerDecl.DeclList{}, | | |
| 972 | .lbrace_token = undefined, | | |
| 973 | .rbrace_token = undefined, | | |
| 974 | }; | | |
| 975 | var container_node_fields_and_decls = c.llpusher(&container_node.fields_and_decls); | | |
| 976 | | 964 | |
| 977 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); | 965 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); |
| 978 | // The underlying type may be null in case of forward-declared enum | 966 | // The underlying type may be null in case of forward-declared enum |
| ... | @@ -981,7 +969,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -981,7 +969,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 981 | | 969 | |
| 982 | // default to c_int since msvc and gcc default to different types | 970 | // default to c_int since msvc and gcc default to different types |
| 983 | _ = try appendToken(c, .LParen, "("); | 971 | _ = try appendToken(c, .LParen, "("); |
| 984 | container_node.init_arg_expr = .{ | 972 | const init_arg_expr = ast.Node.ContainerDecl.InitArg{ |
| 985 | .Type = if (int_type.ptr != null and | 973 | .Type = if (int_type.ptr != null and |
| 986 | !isCBuiltinType(int_type, .UInt) and | 974 | !isCBuiltinType(int_type, .UInt) and |
| 987 | !isCBuiltinType(int_type, .Int)) | 975 | !isCBuiltinType(int_type, .Int)) |
| ... | @@ -997,7 +985,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -997,7 +985,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 997 | }; | 985 | }; |
| 998 | _ = try appendToken(c, .RParen, ")"); | 986 | _ = try appendToken(c, .RParen, ")"); |
| 999 | | 987 | |
| 1000 | container_node.lbrace_token = try appendToken(c, .LBrace, "{"); | 988 | const lbrace_token = try appendToken(c, .LBrace, "{"); |
| 1001 | | 989 | |
| 1002 | it = ZigClangEnumDecl_enumerator_begin(enum_def); | 990 | it = ZigClangEnumDecl_enumerator_begin(enum_def); |
| 1003 | end_it = ZigClangEnumDecl_enumerator_end(enum_def); | 991 | end_it = ZigClangEnumDecl_enumerator_end(enum_def); |
| ... | @@ -1029,7 +1017,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -1029,7 +1017,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1029 | .align_expr = null, | 1017 | .align_expr = null, |
| 1030 | }; | 1018 | }; |
| 1031 | | 1019 | |
| 1032 | try container_node_fields_and_decls.push(&field_node.base); | 1020 | try fields_and_decls.append(&field_node.base); |
| 1033 | _ = try appendToken(c, .Comma, ","); | 1021 | _ = try appendToken(c, .Comma, ","); |
| 1034 | | 1022 | |
| 1035 | // In C each enum value is in the global namespace. So we put them there too. | 1023 | // In C each enum value is in the global namespace. So we put them there too. |
| ... | @@ -1064,10 +1052,18 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -1064,10 +1052,18 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1064 | .align_expr = null, | 1052 | .align_expr = null, |
| 1065 | }; | 1053 | }; |
| 1066 | | 1054 | |
| 1067 | try container_node_fields_and_decls.push(&field_node.base); | 1055 | try fields_and_decls.append(&field_node.base); |
| 1068 | _ = try appendToken(c, .Comma, ","); | 1056 | _ = try appendToken(c, .Comma, ","); |
| 1069 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); | 1057 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, fields_and_decls.items.len); |
| 1070 | | 1058 | container_node.* = .{ |
| | 1059 | .layout_token = extern_tok, |
| | 1060 | .kind_token = container_tok, |
| | 1061 | .init_arg_expr = init_arg_expr, |
| | 1062 | .fields_and_decls_len = fields_and_decls.items.len, |
| | 1063 | .lbrace_token = lbrace_token, |
| | 1064 | .rbrace_token = try appendToken(c, .RBrace, "}"), |
| | 1065 | }; |
| | 1066 | mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items); |
| 1071 | break :blk &container_node.base; | 1067 | break :blk &container_node.base; |
| 1072 | } else | 1068 | } else |
| 1073 | try transCreateNodeOpaqueType(c); | 1069 | try transCreateNodeOpaqueType(c); |
| ... | @@ -3474,7 +3470,7 @@ fn maybeSuppressResult( | ... | @@ -3474,7 +3470,7 @@ fn maybeSuppressResult( |
| 3474 | } | 3470 | } |
| 3475 | | 3471 | |
| 3476 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { | 3472 | fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { |
| 3477 | c.root_decls_it = try c.llpush(*ast.Node, c.root_decls_it, decl_node); | 3473 | try c.root_decls.append(c.gpa, decl_node); |
| 3478 | _ = try c.global_scope.sym_table.put(name, decl_node); | 3474 | _ = try c.global_scope.sym_table.put(name, decl_node); |
| 3479 | } | 3475 | } |
| 3480 | | 3476 | |
| ... | @@ -6119,9 +6115,7 @@ fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node { | ... | @@ -6119,9 +6115,7 @@ fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node { |
| 6119 | return null; | 6115 | return null; |
| 6120 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { | 6116 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { |
| 6121 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { | 6117 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { |
| 6122 | var it = container.fields_and_decls.first; | 6118 | for (container.fieldsAndDecls()) |field_ref| { |
| 6123 | while (it) |field_ref_node| : (it = field_ref_node.next) { | | |
| 6124 | const field_ref = field_ref_node.data; | | |
| 6125 | const field = field_ref.cast(ast.Node.ContainerField).?; | 6119 | const field = field_ref.cast(ast.Node.ContainerField).?; |
| 6126 | const ident = infix.rhs.cast(ast.Node.Identifier).?; | 6120 | const ident = infix.rhs.cast(ast.Node.Identifier).?; |
| 6127 | if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) { | 6121 | if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) { |
| ... | @@ -6147,9 +6141,7 @@ fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node { | ... | @@ -6147,9 +6141,7 @@ fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node { |
| 6147 | return null; | 6141 | return null; |
| 6148 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { | 6142 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { |
| 6149 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { | 6143 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { |
| 6150 | var it = container.fields_and_decls.first; | 6144 | for (container.fieldsAndDecls()) |field_ref| { |
| 6151 | while (it) |field_ref_node| : (it = field_ref_node.next) { | | |
| 6152 | const field_ref = field_ref_node.data; | | |
| 6153 | const field = field_ref.cast(ast.Node.ContainerField).?; | 6145 | const field = field_ref.cast(ast.Node.ContainerField).?; |
| 6154 | const ident = infix.rhs.cast(ast.Node.Identifier).?; | 6146 | const ident = infix.rhs.cast(ast.Node.Identifier).?; |
| 6155 | if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) { | 6147 | if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) { |