aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-05-06 22:30:44 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-05-06 22:30:44 -0700
commita7221ef4e902e63e72524559a067afcf6c1dfd17 (patch)
treee3cbbbd7bd87409c8da573ecefa7174939ed8020 /src
parent3acd98fa3423d67cdce7118bc6abe736309e71df (diff)
downloadzig-a7221ef4e902e63e72524559a067afcf6c1dfd17.tar.gz
zig-a7221ef4e902e63e72524559a067afcf6c1dfd17.zip
Sema: implement `@typeInfo` for functions
The goal is to get start code to be able to inspect the calling convention of `main` in order to determine whether to export a main for libc to call, or to allow the root source file to do it.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig39
-rw-r--r--src/type.zig2
-rw-r--r--src/value.zig20
3 files changed, 59 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 5b2dc339f6..eb9400e7b1 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -4708,7 +4708,44 @@ fn zirBuiltinSrc(
fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
- return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirTypeInfo", .{});
+ const ty = try sema.resolveType(block, src, inst_data.operand);
+ const type_info_ty = try sema.getBuiltinType(block, src, "TypeInfo");
+ const target = sema.mod.getTarget();
+
+ switch (ty.zigTypeTag()) {
+ .Fn => {
+ const field_values = try sema.arena.alloc(Value, 6);
+ // calling_convention: CallingConvention,
+ field_values[0] = try Value.Tag.enum_field_index.create(
+ sema.arena,
+ @enumToInt(ty.fnCallingConvention()),
+ );
+ // alignment: comptime_int,
+ field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.ptrAlignment(target));
+ // is_generic: bool,
+ field_values[2] = Value.initTag(.bool_false); // TODO
+ // is_var_args: bool,
+ field_values[3] = Value.initTag(.bool_false); // TODO
+ // return_type: ?type,
+ field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
+ // args: []const FnArg,
+ field_values[5] = Value.initTag(.null_value); // TODO
+
+ return sema.mod.constInst(sema.arena, src, .{
+ .ty = type_info_ty,
+ .val = try Value.Tag.@"union".create(sema.arena, .{
+ .tag = try Value.Tag.enum_field_index.create(
+ sema.arena,
+ @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn),
+ ),
+ .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr),
+ }),
+ });
+ },
+ else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{
+ @tagName(t),
+ }),
+ }
}
fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
diff --git a/src/type.zig b/src/type.zig
index bf4b3f7b64..f492eeb3ec 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -1214,7 +1214,7 @@ pub const Type = extern union {
if (ptr_info.@"align" != 0) {
return ptr_info.@"align";
} else {
- return ptr_info.pointee_type.abiAlignment();
+ return ptr_info.pointee_type.abiAlignment(target);
}
},
diff --git a/src/value.zig b/src/value.zig
index e6ce65a9f4..2c7002402b 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -120,6 +120,8 @@ pub const Value = extern union {
error_union,
/// An instance of a struct.
@"struct",
+ /// An instance of a union.
+ @"union",
/// This is a special value that tracks a set of types that have been stored
/// to an inferred allocation. It does not support any of the normal value queries.
inferred_alloc,
@@ -228,6 +230,7 @@ pub const Value = extern union {
.@"error" => Payload.Error,
.inferred_alloc => Payload.InferredAlloc,
.@"struct" => Payload.Struct,
+ .@"union" => Payload.Union,
};
}
@@ -446,6 +449,7 @@ pub const Value = extern union {
return Value{ .ptr_otherwise = &new_payload.base };
},
.@"struct" => @panic("TODO can't copy struct value without knowing the type"),
+ .@"union" => @panic("TODO can't copy union value without knowing the type"),
.inferred_alloc => unreachable,
}
@@ -528,6 +532,9 @@ pub const Value = extern union {
.@"struct" => {
return out_stream.writeAll("(struct value)");
},
+ .@"union" => {
+ return out_stream.writeAll("(union value)");
+ },
.null_value => return out_stream.writeAll("null"),
.undef => return out_stream.writeAll("undefined"),
.zero => return out_stream.writeAll("0"),
@@ -709,6 +716,7 @@ pub const Value = extern union {
.error_union,
.empty_struct_value,
.@"struct",
+ .@"union",
.inferred_alloc,
.abi_align_default,
=> unreachable,
@@ -1225,6 +1233,7 @@ pub const Value = extern union {
.export_options_type,
.extern_options_type,
.@"struct",
+ .@"union",
=> @panic("TODO this hash function looks pretty broken. audit it"),
}
return hasher.final();
@@ -1413,6 +1422,7 @@ pub const Value = extern union {
.error_union,
.empty_struct_value,
.@"struct",
+ .@"union",
.null_value,
.abi_align_default,
=> false,
@@ -1564,6 +1574,16 @@ pub const Value = extern union {
/// Field values. The number and type are according to the struct type.
data: [*]Value,
};
+
+ pub const Union = struct {
+ pub const base_tag = Tag.@"union";
+
+ base: Payload = .{ .tag = base_tag },
+ data: struct {
+ tag: Value,
+ val: Value,
+ },
+ };
};
/// Big enough to fit any non-BigInt value