| ... | ... | @@ -229,8 +229,7 @@ pub const Context = struct { |
| 229 | 229 | global_scope: *Scope.Root, |
| 230 | 230 | clang_context: *ZigClangASTContext, |
| 231 | 231 | mangle_count: u32 = 0, |
| 232 | | root_node: *ast.Node.Root, |
| 233 | | root_decls_it: *?*std.SinglyLinkedList(*ast.Node).Node, |
| 232 | root_decls: std.ArrayListUnmanaged(*ast.Node), |
| 234 | 233 | |
| 235 | 234 | /// This one is different than the root scope's name table. This contains |
| 236 | 235 | /// a list of names that we found by visiting all the top level decls without |
| ... | ... | @@ -318,13 +317,6 @@ pub fn translate( |
| 318 | 317 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 319 | 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 | 320 | var context = Context{ |
| 329 | 321 | .gpa = gpa, |
| 330 | 322 | .arena = &arena.allocator, |
| ... | ... | @@ -338,8 +330,7 @@ pub fn translate( |
| 338 | 330 | .global_names = std.StringHashMap(void).init(gpa), |
| 339 | 331 | .tokens = .{}, |
| 340 | 332 | .errors = .{}, |
| 341 | | .root_node = root_node, |
| 342 | | .root_decls_it = &root_node.decls.first, |
| 333 | .root_decls = .{}, |
| 343 | 334 | }; |
| 344 | 335 | context.global_scope.* = Scope.Root.init(&context); |
| 345 | 336 | defer context.decl_table.deinit(); |
| ... | ... | @@ -347,6 +338,7 @@ pub fn translate( |
| 347 | 338 | defer context.tokens.deinit(gpa); |
| 348 | 339 | defer context.errors.deinit(gpa); |
| 349 | 340 | defer context.global_names.deinit(); |
| 341 | defer context.root_decls.deinit(gpa); |
| 350 | 342 | |
| 351 | 343 | try prepopulateGlobalNameTable(ast_unit, &context); |
| 352 | 344 | |
| ... | ... | @@ -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 | 362 | if (false) { |
| 368 | 363 | std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", .{source_buffer.items}); |
| 369 | 364 | for (context.tokens.items) |token| { |
| ... | ... | @@ -831,16 +826,8 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 831 | 826 | const container_tok = try appendToken(c, container_kind, container_kind_name); |
| 832 | 827 | const lbrace_token = try appendToken(c, .LBrace, "{"); |
| 833 | 828 | |
| 834 | | const container_node = try c.arena.create(ast.Node.ContainerDecl); |
| 835 | | container_node.* = .{ |
| 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); |
| 829 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); |
| 830 | defer fields_and_decls.deinit(); |
| 844 | 831 | |
| 845 | 832 | var unnamed_field_count: u32 = 0; |
| 846 | 833 | var it = ZigClangRecordDecl_field_begin(record_def); |
| ... | ... | @@ -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 | 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 | 918 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 923 | 919 | break :blk &container_node.base; |
| 924 | 920 | }; |
| ... | ... | @@ -963,16 +959,8 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 963 | 959 | const extern_tok = try appendToken(c, .Keyword_extern, "extern"); |
| 964 | 960 | const container_tok = try appendToken(c, .Keyword_enum, "enum"); |
| 965 | 961 | |
| 966 | | const container_node = try c.arena.create(ast.Node.ContainerDecl); |
| 967 | | container_node.* = .{ |
| 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); |
| 962 | var fields_and_decls = std.ArrayList(*ast.Node).init(c.gpa); |
| 963 | defer fields_and_decls.deinit(); |
| 976 | 964 | |
| 977 | 965 | const int_type = ZigClangEnumDecl_getIntegerType(enum_decl); |
| 978 | 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 | 969 | |
| 982 | 970 | // default to c_int since msvc and gcc default to different types |
| 983 | 971 | _ = try appendToken(c, .LParen, "("); |
| 984 | | container_node.init_arg_expr = .{ |
| 972 | const init_arg_expr = ast.Node.ContainerDecl.InitArg{ |
| 985 | 973 | .Type = if (int_type.ptr != null and |
| 986 | 974 | !isCBuiltinType(int_type, .UInt) and |
| 987 | 975 | !isCBuiltinType(int_type, .Int)) |
| ... | ... | @@ -997,7 +985,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 997 | 985 | }; |
| 998 | 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 | 990 | it = ZigClangEnumDecl_enumerator_begin(enum_def); |
| 1003 | 991 | end_it = ZigClangEnumDecl_enumerator_end(enum_def); |
| ... | ... | @@ -1029,7 +1017,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 1029 | 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 | 1021 | _ = try appendToken(c, .Comma, ","); |
| 1034 | 1022 | |
| 1035 | 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 | 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 | 1056 | _ = try appendToken(c, .Comma, ","); |
| 1069 | | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); |
| 1070 | | |
| 1057 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, fields_and_decls.items.len); |
| 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 | 1067 | break :blk &container_node.base; |
| 1072 | 1068 | } else |
| 1073 | 1069 | try transCreateNodeOpaqueType(c); |
| ... | ... | @@ -3474,7 +3470,7 @@ fn maybeSuppressResult( |
| 3474 | 3470 | } |
| 3475 | 3471 | |
| 3476 | 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 | 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 | 6115 | return null; |
| 6120 | 6116 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { |
| 6121 | 6117 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { |
| 6122 | | var it = container.fields_and_decls.first; |
| 6123 | | while (it) |field_ref_node| : (it = field_ref_node.next) { |
| 6124 | | const field_ref = field_ref_node.data; |
| 6118 | for (container.fieldsAndDecls()) |field_ref| { |
| 6125 | 6119 | const field = field_ref.cast(ast.Node.ContainerField).?; |
| 6126 | 6120 | const ident = infix.rhs.cast(ast.Node.Identifier).?; |
| 6127 | 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 | 6141 | return null; |
| 6148 | 6142 | if (getContainerTypeOf(c, infix.lhs)) |ty_node| { |
| 6149 | 6143 | if (ty_node.cast(ast.Node.ContainerDecl)) |container| { |
| 6150 | | var it = container.fields_and_decls.first; |
| 6151 | | while (it) |field_ref_node| : (it = field_ref_node.next) { |
| 6152 | | const field_ref = field_ref_node.data; |
| 6144 | for (container.fieldsAndDecls()) |field_ref| { |
| 6153 | 6145 | const field = field_ref.cast(ast.Node.ContainerField).?; |
| 6154 | 6146 | const ident = infix.rhs.cast(ast.Node.Identifier).?; |
| 6155 | 6147 | if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) { |