authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2024-07-30 13:37:37-07:00
committergravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2024-07-31 09:35:07-07:00
log5cc9e18277e1b166be0898255448f3c642759bbc
treeb92eaa5319df576e8cc6cb44e61db7596577ddcd
parent2f2f35105ec76b3543b3198071fef35f4cbf71e2
signaturebadge-check Signed by SSH key SHA256:cf2/TFgSxv2uRX26INvFSw25Prr1Dy9H8MiRXgLpok4

aro_translate_c: Translate enum types


1 files changed, 24 insertions(+), 14 deletions(-)

lib/compiler/aro_translate_c.zig+24-14
...@@ -243,6 +243,7 @@ fn transTopLevelDecls(c: *Context) !void {...@@ -243,6 +243,7 @@ fn transTopLevelDecls(c: *Context) !void {
243fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {243fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {
244 const node_tags = c.tree.nodes.items(.tag);244 const node_tags = c.tree.nodes.items(.tag);
245 const node_data = c.tree.nodes.items(.data);245 const node_data = c.tree.nodes.items(.data);
246 const node_ty = c.tree.nodes.items(.ty);
246 const data = node_data[@intFromEnum(decl)];247 const data = node_data[@intFromEnum(decl)];
247 switch (node_tags[@intFromEnum(decl)]) {248 switch (node_tags[@intFromEnum(decl)]) {
248 .typedef => {249 .typedef => {
...@@ -270,11 +271,13 @@ fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {...@@ -270,11 +271,13 @@ fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {
270 var field_count: u8 = 0;271 var field_count: u8 = 0;
271 if (fields[0] != .none) field_count += 1;272 if (fields[0] != .none) field_count += 1;
272 if (fields[1] != .none) field_count += 1;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 .enum_decl => {277 .enum_decl => {
276 const fields = c.tree.data[data.range.start..data.range.end];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 },
279282
280 .enum_field_decl,283 .enum_field_decl,
...@@ -572,18 +575,16 @@ fn transVarDecl(c: *Context, node: NodeIndex) Error!void {...@@ -572,18 +575,16 @@ fn transVarDecl(c: *Context, node: NodeIndex) Error!void {
572 return failDecl(c, data.decl.name, name, "unable to translate variable declaration", .{});575 return failDecl(c, data.decl.name, name, "unable to translate variable declaration", .{});
573}576}
574577
575fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: []const NodeIndex) Error!void {578fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const Type.Enum, field_nodes: []const NodeIndex) Error!void {
576 const node_types = c.tree.nodes.items(.ty);579 if (c.decl_table.get(@intFromPtr(enum_decl))) |_|
577 const ty = node_types[@intFromEnum(enum_decl)];
578 if (c.decl_table.get(@intFromPtr(ty.data.@"enum"))) |_|
579 return; // Avoid processing this decl twice580 return; // Avoid processing this decl twice
580 const toplevel = scope.id == .root;581 const toplevel = scope.id == .root;
581 const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;582 const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
582583
583 var is_unnamed = false;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 var name = bare_name;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 bare_name = typedef_name;588 bare_name = typedef_name;
588 name = typedef_name;589 name = typedef_name;
589 } else {590 } else {
...@@ -594,10 +595,10 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:...@@ -594,10 +595,10 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:
594 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});595 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});
595 }596 }
596 if (!toplevel) name = try bs.makeMangledName(c, name);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);
598599
599 const enum_type_node = if (!ty.data.@"enum".isIncomplete()) blk: {600 const enum_type_node = if (!enum_decl.isIncomplete()) blk: {
600 for (ty.data.@"enum".fields, field_nodes) |field, field_node| {601 for (enum_decl.fields, field_nodes) |field, field_node| {
601 var enum_val_name: []const u8 = c.mapper.lookup(field.name);602 var enum_val_name: []const u8 = c.mapper.lookup(field.name);
602 if (!toplevel) {603 if (!toplevel) {
603 enum_val_name = try bs.makeMangledName(c, enum_val_name);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,14 +624,14 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:
623 }624 }
624 }625 }
625626
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 error.UnsupportedType => {628 error.UnsupportedType => {
628 return failDecl(c, 0, name, "unable to translate enum integer type", .{});629 return failDecl(c, 0, name, "unable to translate enum integer type", .{});
629 },630 },
630 else => |e| return e,631 else => |e| return e,
631 };632 };
632 } else blk: {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 break :blk ZigTag.opaque_literal.init();635 break :blk ZigTag.opaque_literal.init();
635 };636 };
636637
...@@ -680,7 +681,16 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH...@@ -680,7 +681,16 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH
680 .long_double => return ZigTag.type.create(c.arena, "c_longdouble"),681 .long_double => return ZigTag.type.create(c.arena, "c_longdouble"),
681 .float80 => return ZigTag.type.create(c.arena, "f80"),682 .float80 => return ZigTag.type.create(c.arena, "f80"),
682 .float128 => return ZigTag.type.create(c.arena, "f128"),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 .pointer => {694 .pointer => {
685 const child_type = ty.elemType();695 const child_type = ty.elemType();
686696