feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transType
fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex) TypeError!ZigNode
File
Code
fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex) TypeError!ZigNode {
loop: switch (qt.type(t.comp)) {
.atomic => {
const type_name = try t.getTypeStr(qt);
return t.fail(error.UnsupportedType, source_loc, "TODO support atomic type: '{s}'", .{type_name});
},
.void => return ZigTag.type.create(t.arena, "anyopaque"),
.bool => return ZigTag.type.create(t.arena, "bool"),
.int => |int_ty| switch (int_ty) {
.char => return ZigTag.type.create(t.arena, "u8"),
.schar => return ZigTag.type.create(t.arena, "i8"),
.uchar => return ZigTag.type.create(t.arena, "u8"),
.short => return ZigTag.type.create(t.arena, "c_short"),
.ushort => return ZigTag.type.create(t.arena, "c_ushort"),
.int => return ZigTag.type.create(t.arena, "c_int"),
.uint => return ZigTag.type.create(t.arena, "c_uint"),
.long => return ZigTag.type.create(t.arena, "c_long"),
.ulong => return ZigTag.type.create(t.arena, "c_ulong"),
.long_long => return ZigTag.type.create(t.arena, "c_longlong"),
.ulong_long => return ZigTag.type.create(t.arena, "c_ulonglong"),
.int128 => return ZigTag.type.create(t.arena, "i128"),
.uint128 => return ZigTag.type.create(t.arena, "u128"),
},
.float => |float_ty| switch (float_ty) {
.fp16, .float16 => return ZigTag.type.create(t.arena, "f16"),
.float, .float32 => return ZigTag.type.create(t.arena, "f32"),
.double, .float64, .float32x => return ZigTag.type.create(t.arena, "f64"),
.long_double, .float64x => return ZigTag.type.create(t.arena, "c_longdouble"),
.float128 => return ZigTag.type.create(t.arena, "f128"),
.bf16 => return t.fail(error.UnsupportedType, source_loc, "TODO support bfloat16", .{}),
.dfloat32,
.dfloat64,
.dfloat128,
.dfloat64x,
=> return t.fail(error.UnsupportedType, source_loc, "TODO support decimal float type: '{s}'", .{try t.getTypeStr(qt)}),
.float128x => unreachable,
},
.pointer => |pointer_ty| {
const child_qt = pointer_ty.child;
const is_fn_proto = child_qt.is(t.comp, .func);
const is_const = is_fn_proto or child_qt.@"const";
const is_volatile = child_qt.@"volatile";
const elem_type = try t.transType(scope, child_qt, source_loc);
const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{
.is_const = is_const,
.is_volatile = is_volatile,
.elem_type = elem_type,
.is_allowzero = false,
};
if (is_fn_proto or
t.typeIsOpaque(child_qt) or
t.typeWasDemotedToOpaque(child_qt))
{
const ptr = try ZigTag.single_pointer.create(t.arena, ptr_info);
return ZigTag.optional_type.create(t.arena, ptr);
}
return ZigTag.c_pointer.create(t.arena, ptr_info);
},
.array => |array_ty| {
const elem_qt = array_ty.elem;
switch (array_ty.len) {
.incomplete, .unspecified_variable => {
const elem_type = try t.transType(scope, elem_qt, source_loc);
return ZigTag.c_pointer.create(t.arena, .{
.is_const = elem_qt.@"const",
.is_volatile = elem_qt.@"volatile",
.is_allowzero = false,
.elem_type = elem_type,
});
},
.fixed, .static => |len| {
const elem_type = try t.transType(scope, elem_qt, source_loc);
return ZigTag.array_type.create(t.arena, .{ .len = len, .elem_type = elem_type });
},
.variable => return t.fail(error.UnsupportedType, source_loc, "VLA unsupported '{s}'", .{try t.getTypeStr(qt)}),
}
},
.func => |func_ty| return t.transFnType(scope, qt, func_ty, source_loc, .{}),
.@"struct", .@"union" => |record_ty| {
var trans_scope = scope;
if (!record_ty.isAnonymous(t.comp)) {
if (t.weak_global_names.contains(record_ty.name.lookup(t.comp))) trans_scope = &t.global_scope.base;
}
try t.transRecordDecl(trans_scope, qt);
const name = t.type_decls.get(record_ty.decl_node).?;
return ZigTag.identifier.create(t.arena, name);
},
.@"enum" => |enum_ty| {
var trans_scope = scope;
const is_anonymous = enum_ty.isAnonymous(t.comp);
if (!is_anonymous) {
if (t.weak_global_names.contains(enum_ty.name.lookup(t.comp))) trans_scope = &t.global_scope.base;
}
try t.transEnumDecl(trans_scope, qt);
const name = t.type_decls.get(enum_ty.decl_node).?;
return ZigTag.identifier.create(t.arena, name);
},
.typedef => |typedef_ty| {
var trans_scope = scope;
const typedef_name = typedef_ty.name.lookup(t.comp);
if (builtin_typedef_map.get(typedef_name)) |builtin| return ZigTag.type.create(t.arena, builtin);
if (t.global_names.contains(typedef_name)) trans_scope = &t.global_scope.base;
try t.transTypeDef(trans_scope, typedef_ty.decl_node);
const name = t.type_decls.get(typedef_ty.decl_node).?;
return ZigTag.identifier.create(t.arena, name);
},
.attributed => |attributed_ty| continue :loop attributed_ty.base.type(t.comp),
.typeof => |typeof_ty| {
if (typeof_ty.expr) |expr| {
if (t.transExpr(scope, expr, .used)) |node| {
return ZigTag.typeof.create(t.arena, node);
} else |err| switch (err) {
error.SelfReferential => {},
error.UnsupportedTranslation => {},
error.UnsupportedType => {},
error.OutOfMemory => |e| return e,
}
}
continue :loop typeof_ty.base.type(t.comp);
},
.vector => |vector_ty| {
const len = try t.createNumberNode(vector_ty.len);
const elem_type = try t.transType(scope, vector_ty.elem, source_loc);
return ZigTag.vector.create(t.arena, .{ .lhs = len, .rhs = elem_type });
},
else => return t.fail(error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{try t.getTypeStr(qt)}),
}
}