aboutsummaryrefslogtreecommitdiff
path: root/src/AstGen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-21 22:33:00 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-09-21 23:21:07 -0700
commitaecebf38acc8835db21eeea7b53e4ee26ec739a8 (patch)
tree132a3982487ae7bb1a0210a4ff2b7cd7a2934855 /src/AstGen.zig
parent0e2b9ac7770df07212d4d1cbfb15c3aaed0bef18 (diff)
downloadzig-aecebf38acc8835db21eeea7b53e4ee26ec739a8.tar.gz
zig-aecebf38acc8835db21eeea7b53e4ee26ec739a8.zip
stage2: progress towards ability to compile compiler-rt
* prepare compiler-rt to support being compiled by stage2 - put in a few minor workarounds that will be removed later, such as using `builtin.stage2_arch` rather than `builtin.cpu.arch`. - only try to export a few symbols for now - we'll move more symbols over to the "working in stage2" section as they become functional and gain test coverage. - use `inline fn` at function declarations rather than `@call` with an always_inline modifier at the callsites, to avoid depending on the anonymous array literal syntax language feature (for now). * AIR: replace floatcast instruction with fptrunc and fpext for shortening and widening floating point values, respectively. * Introduce a new ZIR instruction, `export_value`, which implements `@export` for the case when the thing to be exported is a local comptime value that points to a function. - AstGen: fix `@export` not properly reporting ambiguous decl references. * Sema: handle ExportOptions linkage. The value is now available to all backends. - Implement setting global linkage as appropriate in the LLVM backend. I did not yet inspect the LLVM IR, so this still needs to be audited. There is already a pending task to make sure the alias stuff is working as intended, and this is related. - Sema almost handles section, just a tiny bit more code is needed in `resolveExportOptions`. * Sema: implement float widening and shortening for both `@floatCast` and float coercion. - Implement the LLVM backend code for this as well.
Diffstat (limited to 'src/AstGen.zig')
-rw-r--r--src/AstGen.zig74
1 files changed, 49 insertions, 25 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 176203d37f..6a533dff11 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -2166,6 +2166,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.ensure_result_used,
.ensure_result_non_error,
.@"export",
+ .export_value,
.set_eval_branch_quota,
.ensure_err_payload_void,
.atomic_store,
@@ -7095,32 +7096,55 @@ fn builtinCall(
.identifier => {
const ident_token = main_tokens[params[0]];
decl_name = try astgen.identAsString(ident_token);
- {
- var s = scope;
- while (true) switch (s.tag) {
- .local_val => {
- const local_val = s.cast(Scope.LocalVal).?;
- if (local_val.name == decl_name) {
- local_val.used = true;
- break;
- }
- s = local_val.parent;
- },
- .local_ptr => {
- const local_ptr = s.cast(Scope.LocalPtr).?;
- if (local_ptr.name == decl_name) {
- if (!local_ptr.maybe_comptime)
- return astgen.failNode(params[0], "unable to export runtime-known value", .{});
- local_ptr.used = true;
- break;
+
+ var s = scope;
+ var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already
+ while (true) switch (s.tag) {
+ .local_val => {
+ const local_val = s.cast(Scope.LocalVal).?;
+ if (local_val.name == decl_name) {
+ local_val.used = true;
+ _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
+ .operand = local_val.inst,
+ .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]),
+ });
+ return rvalue(gz, rl, .void_value, node);
+ }
+ s = local_val.parent;
+ },
+ .local_ptr => {
+ const local_ptr = s.cast(Scope.LocalPtr).?;
+ if (local_ptr.name == decl_name) {
+ if (!local_ptr.maybe_comptime)
+ return astgen.failNode(params[0], "unable to export runtime-known value", .{});
+ local_ptr.used = true;
+ const loaded = try gz.addUnNode(.load, local_ptr.ptr, node);
+ _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{
+ .operand = loaded,
+ .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]),
+ });
+ return rvalue(gz, rl, .void_value, node);
+ }
+ s = local_ptr.parent;
+ },
+ .gen_zir => s = s.cast(GenZir).?.parent,
+ .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
+ .namespace => {
+ const ns = s.cast(Scope.Namespace).?;
+ if (ns.decls.get(decl_name)) |i| {
+ if (found_already) |f| {
+ return astgen.failNodeNotes(node, "ambiguous reference", .{}, &.{
+ try astgen.errNoteNode(f, "declared here", .{}),
+ try astgen.errNoteNode(i, "also declared here", .{}),
+ });
}
- s = local_ptr.parent;
- },
- .gen_zir => s = s.cast(GenZir).?.parent,
- .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
- .namespace, .top => break,
- };
- }
+ // We found a match but must continue looking for ambiguous references to decls.
+ found_already = i;
+ }
+ s = ns.parent;
+ },
+ .top => break,
+ };
},
.field_access => {
const namespace_node = node_datas[params[0]].lhs;