| ... | ... | @@ -243,6 +243,7 @@ fn transTopLevelDecls(c: *Context) !void { |
| 243 | 243 | fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void { |
| 244 | 244 | const node_tags = c.tree.nodes.items(.tag); |
| 245 | 245 | const node_data = c.tree.nodes.items(.data); |
| 246 | const node_ty = c.tree.nodes.items(.ty); |
| 246 | 247 | const data = node_data[@intFromEnum(decl)]; |
| 247 | 248 | switch (node_tags[@intFromEnum(decl)]) { |
| 248 | 249 | .typedef => { |
| ... | ... | @@ -270,11 +271,13 @@ fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void { |
| 270 | 271 | var field_count: u8 = 0; |
| 271 | 272 | if (fields[0] != .none) field_count += 1; |
| 272 | 273 | if (fields[1] != .none) field_count += 1; |
| 273 | | try transEnumDecl(c, scope, decl, fields[0..field_count]); |
| 274 | const enum_decl = node_ty[@intFromEnum(decl)].canonicalize(.standard).data.@"enum"; |
| 275 | try transEnumDecl(c, scope, enum_decl, fields[0..field_count]); |
| 274 | 276 | }, |
| 275 | 277 | .enum_decl => { |
| 276 | 278 | const fields = c.tree.data[data.range.start..data.range.end]; |
| 277 | | try transEnumDecl(c, scope, decl, fields); |
| 279 | const enum_decl = node_ty[@intFromEnum(decl)].canonicalize(.standard).data.@"enum"; |
| 280 | try transEnumDecl(c, scope, enum_decl, fields); |
| 278 | 281 | }, |
| 279 | 282 | |
| 280 | 283 | .enum_field_decl, |
| ... | ... | @@ -572,18 +575,16 @@ fn transVarDecl(c: *Context, node: NodeIndex) Error!void { |
| 572 | 575 | return failDecl(c, data.decl.name, name, "unable to translate variable declaration", .{}); |
| 573 | 576 | } |
| 574 | 577 | |
| 575 | | fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: []const NodeIndex) Error!void { |
| 576 | | const node_types = c.tree.nodes.items(.ty); |
| 577 | | const ty = node_types[@intFromEnum(enum_decl)]; |
| 578 | | if (c.decl_table.get(@intFromPtr(ty.data.@"enum"))) |_| |
| 578 | fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const Type.Enum, field_nodes: []const NodeIndex) Error!void { |
| 579 | if (c.decl_table.get(@intFromPtr(enum_decl))) |_| |
| 579 | 580 | return; // Avoid processing this decl twice |
| 580 | 581 | const toplevel = scope.id == .root; |
| 581 | 582 | const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined; |
| 582 | 583 | |
| 583 | 584 | var is_unnamed = false; |
| 584 | | var bare_name: []const u8 = c.mapper.lookup(ty.data.@"enum".name); |
| 585 | var bare_name: []const u8 = c.mapper.lookup(enum_decl.name); |
| 585 | 586 | var name = bare_name; |
| 586 | | if (c.unnamed_typedefs.get(@intFromPtr(ty.data.@"enum"))) |typedef_name| { |
| 587 | if (c.unnamed_typedefs.get(@intFromPtr(enum_decl))) |typedef_name| { |
| 587 | 588 | bare_name = typedef_name; |
| 588 | 589 | name = typedef_name; |
| 589 | 590 | } else { |
| ... | ... | @@ -594,10 +595,10 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: |
| 594 | 595 | name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name}); |
| 595 | 596 | } |
| 596 | 597 | if (!toplevel) name = try bs.makeMangledName(c, name); |
| 597 | | try c.decl_table.putNoClobber(c.gpa, @intFromPtr(ty.data.@"enum"), name); |
| 598 | try c.decl_table.putNoClobber(c.gpa, @intFromPtr(enum_decl), name); |
| 598 | 599 | |
| 599 | | const enum_type_node = if (!ty.data.@"enum".isIncomplete()) blk: { |
| 600 | | for (ty.data.@"enum".fields, field_nodes) |field, field_node| { |
| 600 | const enum_type_node = if (!enum_decl.isIncomplete()) blk: { |
| 601 | for (enum_decl.fields, field_nodes) |field, field_node| { |
| 601 | 602 | var enum_val_name: []const u8 = c.mapper.lookup(field.name); |
| 602 | 603 | if (!toplevel) { |
| 603 | 604 | enum_val_name = try bs.makeMangledName(c, enum_val_name); |
| ... | ... | @@ -623,14 +624,14 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: |
| 623 | 624 | } |
| 624 | 625 | } |
| 625 | 626 | |
| 626 | | break :blk transType(c, scope, ty.data.@"enum".tag_ty, .standard, 0) catch |err| switch (err) { |
| 627 | break :blk transType(c, scope, enum_decl.tag_ty, .standard, 0) catch |err| switch (err) { |
| 627 | 628 | error.UnsupportedType => { |
| 628 | 629 | return failDecl(c, 0, name, "unable to translate enum integer type", .{}); |
| 629 | 630 | }, |
| 630 | 631 | else => |e| return e, |
| 631 | 632 | }; |
| 632 | 633 | } else blk: { |
| 633 | | try c.opaque_demotes.put(c.gpa, @intFromPtr(ty.data.@"enum"), {}); |
| 634 | try c.opaque_demotes.put(c.gpa, @intFromPtr(enum_decl), {}); |
| 634 | 635 | break :blk ZigTag.opaque_literal.init(); |
| 635 | 636 | }; |
| 636 | 637 | |
| ... | ... | @@ -680,7 +681,16 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH |
| 680 | 681 | .long_double => return ZigTag.type.create(c.arena, "c_longdouble"), |
| 681 | 682 | .float80 => return ZigTag.type.create(c.arena, "f80"), |
| 682 | 683 | .float128 => return ZigTag.type.create(c.arena, "f128"), |
| 683 | | .@"enum" => @panic("TODO"), |
| 684 | .@"enum" => { |
| 685 | const enum_decl = ty.data.@"enum"; |
| 686 | var trans_scope = scope; |
| 687 | if (enum_decl.name != .empty) { |
| 688 | const decl_name = c.mapper.lookup(enum_decl.name); |
| 689 | if (c.weak_global_names.contains(decl_name)) trans_scope = &c.global_scope.base; |
| 690 | } |
| 691 | try transEnumDecl(c, trans_scope, enum_decl, &.{}); |
| 692 | return ZigTag.identifier.create(c.arena, c.decl_table.get(@intFromPtr(enum_decl)).?); |
| 693 | }, |
| 684 | 694 | .pointer => { |
| 685 | 695 | const child_type = ty.elemType(); |
| 686 | 696 | |