feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transEnumDecl
fn transEnumDecl(t: *Translator, scope: *Scope, enum_qt: QualType) Error!void
File
Code
fn transEnumDecl(t: *Translator, scope: *Scope, enum_qt: QualType) Error!void {
const base = enum_qt.base(t.comp);
const enum_ty = base.type.@"enum";
if (t.type_decls.get(enum_ty.decl_node)) |_|
return;
const toplevel = scope.id == .root;
const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(t) else undefined;
var bare_name = enum_ty.name.lookup(t.comp);
var is_unnamed = false;
var name = bare_name;
if (t.unnamed_typedefs.get(base.qt)) |typedef_name| {
bare_name = typedef_name;
name = typedef_name;
} else {
if (enum_ty.isAnonymous(t.comp)) {
bare_name = try std.fmt.allocPrint(t.arena, "unnamed_{d}", .{t.getMangle()});
is_unnamed = true;
}
name = try std.fmt.allocPrint(t.arena, "enum_{s}", .{bare_name});
}
if (!toplevel) name = try bs.makeMangledName(name);
try t.type_decls.putNoClobber(t.gpa, enum_ty.decl_node, name);
const enum_type_node = if (!base.qt.hasIncompleteSize(t.comp)) blk: {
const enum_decl = enum_ty.decl_node.get(t.tree).enum_decl;
for (enum_ty.fields, enum_decl.fields) |field, field_node| {
var enum_val_name = field.name.lookup(t.comp);
if (!toplevel) {
enum_val_name = try bs.makeMangledName(enum_val_name);
}
const enum_const_type_node: ?ZigNode = t.transType(scope, field.qt, field.name_tok) catch |err| switch (err) {
error.UnsupportedType => null,
else => |e| return e,
};
const val = t.tree.value_map.get(field_node).?;
const enum_const_def = try ZigTag.enum_constant.create(t.arena, .{
.name = enum_val_name,
.is_public = toplevel,
.type = enum_const_type_node,
.value = try t.createIntNode(val),
});
if (toplevel)
try t.addTopLevelDecl(enum_val_name, enum_const_def)
else {
try scope.appendNode(enum_const_def);
try bs.discardVariable(enum_val_name);
}
}
break :blk t.transType(scope, enum_ty.tag.?, enum_decl.name_or_kind_tok) catch |err| switch (err) {
error.UnsupportedType => {
return t.failDecl(scope, enum_decl.name_or_kind_tok, name, "unable to translate enum integer type", .{});
},
else => |e| return e,
};
} else blk: {
try t.opaque_demotes.put(t.gpa, base.qt, {});
break :blk ZigTag.opaque_literal.init();
};
const is_pub = toplevel and !is_unnamed;
const payload = try t.arena.create(ast.Payload.SimpleVarDecl);
payload.* = .{
.base = .{ .tag = if (is_pub) .pub_var_simple else .var_simple },
.data = .{
.init = enum_type_node,
.name = name,
},
};
const node = ZigNode.initPayload(&payload.base);
if (toplevel) {
try t.addTopLevelDecl(name, node);
if (!is_unnamed)
try t.alias_list.append(t.gpa, .{ .alias = bare_name, .name = name });
} else {
try scope.appendNode(node);
try bs.discardVariable(name);
}
}